kbus_http.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // package kbus_http -- шина сообщений поверх HTTP.
  2. package kbus_http
  3. import (
  4. "fmt"
  5. "net/http"
  6. "sync"
  7. "github.com/gofiber/fiber/v3"
  8. mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/comp_spec"
  10. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/safe_bool"
  11. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kctx"
  12. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kserv_http"
  13. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/lti/bus_ent"
  14. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/lti/bus_mock/mock_hand_sub_http"
  15. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/lti/bus_spec"
  16. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/lti/dot"
  17. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/lti/kbus_base"
  18. )
  19. // kBusHttp -- шина данных поверх HTTP.
  20. type kBusHttp struct {
  21. *kbus_base.KBusBase
  22. log comp_spec.ILogBuf
  23. }
  24. var (
  25. Bus_ *kBusHttp
  26. block sync.Mutex
  27. )
  28. // GetKernelBusHttp -- возвращает шину HTTP.
  29. func GetKernelBusHttp() bus_spec.IKernelBus {
  30. block.Lock()
  31. defer block.Unlock()
  32. if Bus_ != nil {
  33. return Bus_
  34. }
  35. paramLogBuf := &mL1.LogBufParam{
  36. IsTerm_: safe_bool.NewSafeBool(true),
  37. Prefix_: "kBusHttp",
  38. }
  39. log := mL1.NewLogBuf(paramLogBuf)
  40. log.Debug("GetKernelBusHttp(): new")
  41. kCtx := kctx.GetKernelCtx()
  42. kBus := kbus_base.GetKernelBusBase()
  43. sf := &kBusHttp{
  44. KBusBase: kBus,
  45. log: log,
  46. }
  47. kServHttp := kserv_http.GetKernelServHttp()
  48. fibApp := kServHttp.Fiber()
  49. fibApp.Post("/bus/sub", sf.postSub) // Топик подписки, IN
  50. fibApp.Post("/bus/unsub", sf.postUnsub) // Топик отписки, IN
  51. fibApp.Post("/bus/request", sf.postSendRequest) // Топик входящих запросов, IN
  52. fibApp.Post("/bus/pub", sf.postPublish) // Топик публикаций подписки, IN
  53. kCtx.Set("kernBus", sf, "GetKernelBusHttp(): http data bus")
  54. Bus_ = sf
  55. return Bus_
  56. }
  57. // Входящий запрос HTTP на подписку.
  58. func (sf *kBusHttp) postSub(ctx fiber.Ctx) error {
  59. sf.log.Debug("postSub()")
  60. ctx.Set("Content-type", "text/html; charset=utf8")
  61. ctx.Set("Content-type", "text/json")
  62. ctx.Set("Cache-Control", "no-cache")
  63. sf.log.Debug("postSub()")
  64. req := &dot.SubscribeReq{}
  65. err := ctx.Bind().Body(req)
  66. if err != nil {
  67. resp := &dot.SubscribeResp{
  68. Status_: fmt.Sprintf("kernelBusHttp.postSub(): in parse request, err=\n\t%v\n", err),
  69. Uuid_: req.Uuid_,
  70. }
  71. resp.SelfCheck()
  72. ctx.Response().SetStatusCode(http.StatusBadRequest)
  73. sf.log.Err("postSub(): in body parser, status=%q", resp.Status_)
  74. return ctx.JSON(resp)
  75. }
  76. resp := sf.processSubscribe(req)
  77. resp.SelfCheck()
  78. return ctx.JSON(resp)
  79. }
  80. // Процесс подписки веб-хука.
  81. func (sf *kBusHttp) processSubscribe(req *dot.SubscribeReq) *dot.SubscribeResp {
  82. req.SelfCheck()
  83. topic := bus_ent.NewTopicFix(req.Topic_)
  84. handler := mock_hand_sub_http.NewMockHandSubHttp(topic, req.WebHook_)
  85. resp := &dot.SubscribeResp{
  86. Status_: "ok",
  87. Uuid_: req.Uuid_,
  88. Name_: handler.Name().Get(),
  89. }
  90. res := sf.Subscribe(handler)
  91. if res.IsErr() {
  92. resp.Status_ = fmt.Sprintf("kernelBusHttp.processSubscribe(): err=\n\t%v", res.Err())
  93. return resp
  94. }
  95. return resp
  96. }
  97. // Входящая публикация.
  98. func (sf *kBusHttp) postPublish(ctx fiber.Ctx) error {
  99. sf.log.Debug("postPublish()")
  100. ctx.Set("Content-type", "text/html; charset=utf8")
  101. ctx.Set("Content-type", "text/json")
  102. ctx.Set("Cache-Control", "no-cache")
  103. req := &dot.PublishReq{}
  104. err := ctx.Bind().Body(req)
  105. if err != nil {
  106. resp := &dot.PublishResp{
  107. Status_: fmt.Sprintf("kernelBusHttp.postPublish(): in parse request, err=\n\t%v\n", err),
  108. Uuid_: req.Uuid_,
  109. }
  110. resp.SelfCheck()
  111. ctx.Response().SetStatusCode(http.StatusBadRequest)
  112. sf.log.Err("postPublish(): in body parser, status=%v", resp.Status_)
  113. return ctx.JSON(resp)
  114. }
  115. resp := sf.processPublish(req)
  116. resp.SelfCheck()
  117. return ctx.JSON(resp)
  118. }
  119. // Выполняет процесс публикации.
  120. func (sf *kBusHttp) processPublish(req *dot.PublishReq) *dot.PublishResp {
  121. req.SelfCheck()
  122. topic := bus_ent.NewTopicFix(req.Topic_)
  123. res := sf.Publish(topic, req.BinMsg_)
  124. resp := &dot.PublishResp{
  125. Status_: "ok",
  126. Uuid_: req.Uuid_,
  127. }
  128. if res.IsErr() {
  129. resp.Status_ = fmt.Sprintf("kernelBusHttp.processPublish(): err=\n\t%v", res.Err())
  130. return resp
  131. }
  132. return resp
  133. }
  134. // Входящий запрос.
  135. func (sf *kBusHttp) postSendRequest(ctx fiber.Ctx) error {
  136. sf.log.Debug("postSendRequest()")
  137. ctx.Set("Content-type", "text/html; charset=utf8")
  138. ctx.Set("Content-type", "text/json")
  139. ctx.Set("Cache-Control", "no-cache")
  140. req := &dot.ServeReq{}
  141. err := ctx.Bind().Body(req)
  142. if err != nil {
  143. resp := &dot.ServeResp{
  144. Status_: fmt.Sprintf("kernelBusHttp.postSendRequest(): err=\n\t%v", err),
  145. Uuid_: req.Uuid_,
  146. }
  147. resp.SelfCheck()
  148. ctx.Response().SetStatusCode(http.StatusBadRequest)
  149. sf.log.Err("postSendRequest(): in body parser, status=%v", resp.Status_)
  150. return ctx.JSON(resp)
  151. }
  152. resp := sf.processSendRequest(req)
  153. resp.SelfCheck()
  154. return ctx.JSON(resp)
  155. }
  156. // Обрабатывает входящий запрос.
  157. func (sf *kBusHttp) processSendRequest(req *dot.ServeReq) *dot.ServeResp {
  158. req.SelfCheck()
  159. topic := bus_ent.NewTopicFix(req.Topic_)
  160. res := sf.SendRequest(topic, req.BinReq_)
  161. resp := &dot.ServeResp{
  162. Status_: "ok",
  163. Uuid_: req.Uuid_,
  164. }
  165. if res.IsErr() {
  166. resp.Status_ = fmt.Sprintf("kernelBusHttp.processSendRequest(): err=\n\t%v", res.Err())
  167. return resp
  168. }
  169. resp.BinResp_ = res.Ok()
  170. return resp
  171. }
  172. // Входящая отписка от топика по HTTP.
  173. func (sf *kBusHttp) postUnsub(ctx fiber.Ctx) error {
  174. sf.log.Debug("postUnsub()")
  175. ctx.Set("Content-type", "text/html; charset=utf8")
  176. ctx.Set("Content-type", "text/json")
  177. ctx.Set("Cache-Control", "no-cache")
  178. req := &dot.UnsubReq{}
  179. err := ctx.Bind().Body(req)
  180. if err != nil {
  181. resp := &dot.ServeResp{
  182. Status_: fmt.Sprintf("kernelBusHttp.postSendRequest(): err=\n\t%v", err),
  183. Uuid_: req.Uuid_,
  184. }
  185. resp.SelfCheck()
  186. ctx.Response().SetStatusCode(http.StatusBadRequest)
  187. sf.log.Err("postUnsub(): in body_parser, status=%q", resp.Status_)
  188. return ctx.JSON(resp)
  189. }
  190. resp := sf.processUnsubRequest(req)
  191. resp.SelfCheck()
  192. return ctx.JSON(resp)
  193. }
  194. // Процесс отписки от топика.
  195. func (sf *kBusHttp) processUnsubRequest(req *dot.UnsubReq) *dot.UnsubResp {
  196. req.SelfCheck()
  197. resp := &dot.UnsubResp{
  198. Status_: "ok",
  199. Uuid_: req.Uuid_,
  200. }
  201. optHandler := sf.KCtx_.Get(string(req.HandlerName_))
  202. if optHandler.IsNone() {
  203. resp.Status_ = fmt.Sprintf("kernelBusHttp.processUnsubRequest(): not get handler(%v) from kernel ctx",
  204. req.HandlerName_)
  205. return resp
  206. }
  207. if optHandler == nil {
  208. resp.Status_ = fmt.Sprintf("kernelBusHttp.processUnsubRequest(): handler(%v) not exists", req.HandlerName_)
  209. return resp
  210. }
  211. hand := optHandler.Some().Val().(bus_spec.IBusHandlerSubscribe)
  212. sf.Unsubscribe(hand)
  213. return resp
  214. }