jointdispatcher.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package dispatcher
  15. import (
  16. "context"
  17. "fmt"
  18. "net/http"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/log"
  21. "yunion.io/x/pkg/appctx"
  22. "yunion.io/x/pkg/util/printutils"
  23. "yunion.io/x/onecloud/pkg/appsrv"
  24. "yunion.io/x/onecloud/pkg/httperrors"
  25. "yunion.io/x/onecloud/pkg/mcclient/modulebase"
  26. )
  27. func AddJointModelDispatcher(prefix string, app *appsrv.Application, manager IJointModelDispatchHandler, isSlave bool) {
  28. metadata := map[string]interface{}{"manager": manager}
  29. tags := map[string]string{"resource": manager.KeywordPlural()}
  30. // list
  31. app.AddHandler2("GET",
  32. fmt.Sprintf("%s/%s", prefix, manager.KeywordPlural()),
  33. manager.Filter(jointListHandler),
  34. metadata, "list_joint", tags)
  35. // joint list descendent
  36. app.AddHandler2("GET",
  37. fmt.Sprintf("%s/%s/<master_id>/%s", prefix,
  38. manager.MasterKeywordPlural(),
  39. manager.SlaveKeywordPlural()),
  40. manager.Filter(jointListDescendentHandler),
  41. metadata, "list_descendent", tags)
  42. // joint list descendent
  43. app.AddHandler2("GET",
  44. fmt.Sprintf("%s/%s/<slave_id>/%s", prefix,
  45. manager.SlaveKeywordPlural(),
  46. manager.MasterKeywordPlural()),
  47. manager.Filter(jointListDescendentHandler),
  48. metadata, "list_descendent", tags)
  49. // joint Get
  50. app.AddHandler2("GET",
  51. fmt.Sprintf("%s/%s/<master_id>/%s/<slave_id>", prefix,
  52. manager.MasterKeywordPlural(),
  53. manager.SlaveKeywordPlural()),
  54. manager.Filter(jointGetHandler),
  55. metadata, "get_joint", tags)
  56. app.AddHandler2("GET",
  57. fmt.Sprintf("%s/%s/<slave_id>/%s/<master_id>", prefix,
  58. manager.SlaveKeywordPlural(),
  59. manager.MasterKeywordPlural()),
  60. manager.Filter(jointGetHandler),
  61. metadata, "get_joint", tags)
  62. if isSlave {
  63. // slave node only support get and head
  64. return
  65. }
  66. // joint attach
  67. app.AddHandler2("POST",
  68. fmt.Sprintf("%s/%s/<master_id>/%s/<slave_id>", prefix,
  69. manager.MasterKeywordPlural(),
  70. manager.SlaveKeywordPlural()),
  71. manager.Filter(attachHandler),
  72. metadata, "attach", tags)
  73. app.AddHandler2("POST",
  74. fmt.Sprintf("%s/%s/<slave_id>/%s/<master_id>", prefix,
  75. manager.SlaveKeywordPlural(),
  76. manager.MasterKeywordPlural()),
  77. manager.Filter(attachHandler),
  78. metadata, "attach", tags)
  79. // joint update
  80. app.AddHandler2("PUT",
  81. fmt.Sprintf("%s/%s/<master_id>/%s/<slave_id>", prefix,
  82. manager.MasterKeywordPlural(),
  83. manager.SlaveKeywordPlural()),
  84. manager.Filter(updateJointHandler),
  85. metadata, "update_joint", tags)
  86. app.AddHandler2("PUT",
  87. fmt.Sprintf("%s/%s/<slave_id>/%s/<master_id>", prefix,
  88. manager.SlaveKeywordPlural(),
  89. manager.MasterKeywordPlural()),
  90. manager.Filter(updateJointHandler),
  91. metadata, "update_joint", tags)
  92. // detach joint
  93. app.AddHandler2("DELETE",
  94. fmt.Sprintf("%s/%s/<master_id>/%s/<slave_id>", prefix,
  95. manager.MasterKeywordPlural(),
  96. manager.SlaveKeywordPlural()),
  97. manager.Filter(detachHandler),
  98. metadata, "detach", tags)
  99. app.AddHandler2("DELETE",
  100. fmt.Sprintf("%s/%s/<slave_id>/%s/<master_id>", prefix,
  101. manager.SlaveKeywordPlural(),
  102. manager.MasterKeywordPlural()),
  103. manager.Filter(detachHandler),
  104. metadata, "detach", tags)
  105. }
  106. func fetchJointEnv(ctx context.Context, w http.ResponseWriter, r *http.Request) (IJointModelDispatchHandler, map[string]string, jsonutils.JSONObject, jsonutils.JSONObject) {
  107. params, query, body := appsrv.FetchEnv(ctx, w, r)
  108. metadata := appctx.AppContextMetadata(ctx)
  109. manager, ok := metadata["manager"].(IJointModelDispatchHandler)
  110. if !ok {
  111. log.Errorf("No manager found for URL: %s", r.URL)
  112. }
  113. return manager, params, query, body
  114. }
  115. func jointListHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  116. manager, params, query, _ := fetchJointEnv(ctx, w, r)
  117. listResult, err := manager.List(ctx, mergeQueryParams(params, query), nil)
  118. if err != nil {
  119. httperrors.GeneralServerError(ctx, w, err)
  120. return
  121. }
  122. appsrv.SendJSON(w, modulebase.ListResult2JSONWithKey(listResult, manager.KeywordPlural()))
  123. }
  124. func jointListDescendentHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  125. manager, params, query, _ := fetchJointEnv(ctx, w, r)
  126. var listResult *printutils.ListResult
  127. var err error
  128. if _, ok := params["<master_id>"]; ok {
  129. listResult, err = manager.ListMasterDescendent(ctx, params["<master_id>"], mergeQueryParams(params, query, "<master_id>"))
  130. } else if _, ok := params["<slave_id>"]; ok {
  131. listResult, err = manager.ListSlaveDescendent(ctx, params["<slave_id>"], mergeQueryParams(params, query, "<slave_id>"))
  132. }
  133. if err != nil {
  134. httperrors.GeneralServerError(ctx, w, err)
  135. return
  136. }
  137. appsrv.SendJSON(w, modulebase.ListResult2JSONWithKey(listResult, manager.KeywordPlural()))
  138. }
  139. func jointGetHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  140. manager, params, query, _ := fetchJointEnv(ctx, w, r)
  141. result, err := manager.Get(ctx, params["<master_id>"], params["<slave_id>"], mergeQueryParams(params, query, "<master_id>", "<slave_id>"))
  142. if err != nil {
  143. httperrors.GeneralServerError(ctx, w, err)
  144. return
  145. }
  146. appsrv.SendJSON(w, wrapBody(result, manager.Keyword()))
  147. }
  148. func attachHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  149. manager, params, query, body := fetchJointEnv(ctx, w, r)
  150. log.Debugf("body: %s", body)
  151. var data jsonutils.JSONObject
  152. if body != nil {
  153. data, _ = body.Get(manager.Keyword())
  154. }
  155. if data == nil {
  156. data = jsonutils.NewDict()
  157. }
  158. result, err := manager.Attach(ctx, params["<master_id>"], params["<slave_id>"], mergeQueryParams(params, query, "<master_id>", "<slave_id>"), data)
  159. if err != nil {
  160. httperrors.GeneralServerError(ctx, w, err)
  161. return
  162. }
  163. appsrv.SendJSON(w, wrapBody(result, manager.Keyword()))
  164. }
  165. func updateJointHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  166. manager, params, query, body := fetchJointEnv(ctx, w, r)
  167. data, err := body.Get(manager.Keyword())
  168. if err != nil {
  169. httperrors.GeneralServerError(ctx, w, err)
  170. return
  171. }
  172. result, err := manager.Update(ctx, params["<master_id>"], params["<slave_id>"], mergeQueryParams(params, query, "<master_id>", "<slave_id>"), data)
  173. if err != nil {
  174. httperrors.GeneralServerError(ctx, w, err)
  175. return
  176. }
  177. appsrv.SendJSON(w, wrapBody(result, manager.Keyword()))
  178. }
  179. func detachHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  180. manager, params, query, body := fetchJointEnv(ctx, w, r)
  181. var data jsonutils.JSONObject
  182. if body != nil {
  183. data, _ = body.Get(manager.Keyword())
  184. }
  185. result, err := manager.Detach(ctx, params["<master_id>"], params["<slave_id>"], mergeQueryParams(params, query, "<master_id>", "<slave_id>"), data)
  186. if err != nil {
  187. httperrors.GeneralServerError(ctx, w, err)
  188. return
  189. }
  190. appsrv.SendJSON(w, wrapBody(result, manager.Keyword()))
  191. }