manager.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package router
  2. import (
  3. "bp.jydev.jianyu360.cn/BaseService/gateway/common/db"
  4. . "bp.jydev.jianyu360.cn/BaseService/gateway/common/gatecode"
  5. "fmt"
  6. "github.com/gogf/gf/v2/net/ghttp"
  7. "github.com/gogf/gf/v2/util/gconv"
  8. "log"
  9. "regexp"
  10. )
  11. type Manager struct {
  12. eqRouters map[string]*Router
  13. regexRouter map[*regexp.Regexp]*Router
  14. }
  15. // InitRouterManager 初始化系统代理路由
  16. // 支持完全匹配和正则匹配
  17. func InitRouterManager() (*Manager, error) {
  18. res := db.GateWatMySql.Query("SELECT status,middleground_code,url,function_code,check_sess,check_power,check_auth,check_status,check_blacklist,timeout,remark,appid,deduct_source FROM front_proxy")
  19. if res == nil || len(*res) == 0 {
  20. return nil, fmt.Errorf("未发现可用路由")
  21. }
  22. // 初始化 routerManager
  23. routerManager := &Manager{
  24. eqRouters: make(map[string]*Router),
  25. regexRouter: make(map[*regexp.Regexp]*Router),
  26. }
  27. for _, row := range *res {
  28. // 获取路由信息
  29. router := gconv.String(row["url"])
  30. routerRule := &Router{
  31. Status: gconv.Int(row["status"]),
  32. SessCheck: gconv.Int(row["check_sess"]),
  33. PowerCheck: gconv.Int(row["check_power"]),
  34. AccountCheck: gconv.Int(row["check_status"]),
  35. AuthCheck: gconv.Int(row["check_auth"]),
  36. BlackCheck: gconv.Int(row["check_blacklist"]) == 1,
  37. Deduct: gconv.Int(row["deduct_source"]),
  38. FuncCode: gconv.String(row["function_code"]),
  39. MiddleCode: gconv.String(row["middleground_code"]),
  40. AppId: gconv.String(row["appid"]),
  41. ReqUrl: router,
  42. TimeOut: gconv.Int64(row["timeout"]),
  43. Remark: gconv.String(row["remark"]),
  44. }
  45. // 判断路由匹配方式是完全匹配还是正则匹配 (此处逻辑参考x-web框架)
  46. if regexp.QuoteMeta(router) == router {
  47. routerManager.eqRouters[router] = routerRule
  48. } else {
  49. reg, err := regexp.Compile(router)
  50. if err != nil {
  51. log.Printf("路由%s装载异常 %v\n", router, err)
  52. }
  53. routerManager.regexRouter[reg] = routerRule
  54. }
  55. }
  56. return routerManager, nil
  57. }
  58. // GetRouterRule 获取路由规则
  59. // 根据用户请求地址匹配路由规则,优先绝对匹配后用正则匹配。
  60. func (m *Manager) GetRouterRule(url string) (*Router, error) {
  61. routerRule, exists := m.eqRouters[url]
  62. if !exists {
  63. for reg, thisRouterRule := range m.regexRouter {
  64. if reg.MatchString(url) {
  65. routerRule = thisRouterRule
  66. }
  67. }
  68. }
  69. if routerRule == nil {
  70. return nil, NewErrorWithCode(GATEWAY_ROUTER_NOTFIND, fmt.Sprintf("未找到请求地址%s,请检查是否注册到数据库\n", url))
  71. }
  72. // 路由状态判断
  73. if routerRule.Status != 1 {
  74. return nil, NewErrorWithCode(GATEWAY_ROUTER_UPHOLD, fmt.Sprintf("接口状态:%d\n", routerRule.Status))
  75. }
  76. return routerRule, nil
  77. }
  78. // InfusionContext 注入通用结构体gContext
  79. func (m *Manager) InfusionContext(r *ghttp.Request) (err error) {
  80. var router *Router
  81. var GCtx = &GContext{
  82. Sess: &JySession{},
  83. RouterRule: &Router{},
  84. }
  85. router, err = m.GetRouterRule(r.RequestURI)
  86. if err != nil {
  87. r.SetCtxVar(GContextKey, GCtx)
  88. return
  89. }
  90. GCtx.RouterRule = router
  91. //获取session
  92. jySess, _ := InitJySessionContext(r)
  93. GCtx.Sess = jySess
  94. r.SetCtxVar(GContextKey, GCtx)
  95. return
  96. }