manager.go 3.9 KB

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