Nessuna descrizione
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.go 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. package main
  2. import (
  3. "encoding/json"
  4. "log"
  5. "net/http"
  6. "strings"
  7. "time"
  8. "git.x2erp.com/qdy/go-base/config"
  9. "git.x2erp.com/qdy/go-base/myservice"
  10. "git.x2erp.com/qdy/go-base/types"
  11. "git.x2erp.com/qdy/go-db/factory/database"
  12. "git.x2erp.com/qdy/go-svc-worker/service"
  13. "go-micro.dev/v4/metadata"
  14. )
  15. // 定义业务服务
  16. type DBFactory struct {
  17. dbFactory *database.DBFactory
  18. }
  19. // 配置
  20. var (
  21. cfg config.IConfig
  22. serviceName string
  23. serviceVersion string
  24. )
  25. func main() {
  26. // 1. 获取配置
  27. cfg = config.GetConfig()
  28. serviceConfig := cfg.GetService()
  29. microConfig := cfg.GetMicro()
  30. serviceName = serviceConfig.ServiceName
  31. serviceVersion = serviceConfig.ServiceVersion
  32. log.Printf("serviceName: %s", serviceName)
  33. log.Printf("Port: %d", serviceConfig.Port)
  34. log.Printf("Consul: %s", microConfig.RegistryAddress)
  35. // 2. 初始化数据库
  36. dbFactory, err := database.GetDBFactory()
  37. if err != nil {
  38. log.Fatal("数据库连接失败:", err)
  39. }
  40. defer func() {
  41. if err := dbFactory.Close(); err != nil {
  42. log.Printf("数据库关闭错误: %v", err)
  43. }
  44. }()
  45. // 3. 创建服务实例
  46. dbfactory := &DBFactory{dbFactory: dbFactory}
  47. // 4. 使用 micro.Start 启动服务
  48. webService := myservice.Start(cfg)
  49. // 7. 注册HTTP路由
  50. webService.Handle("/", http.HandlerFunc(rootHandler))
  51. webService.Handle("/health", http.HandlerFunc(dbfactory.healthHandler))
  52. webService.Handle("/info", http.HandlerFunc(infoHandler))
  53. webService.Handle("/api/data/agent/to/doris", authMiddleware(http.HandlerFunc(dbfactory.agentToDorisHandler)))
  54. if err := webService.Run(); err != nil {
  55. log.Fatal("服务运行失败:", err)
  56. }
  57. }
  58. // 根处理器
  59. func rootHandler(w http.ResponseWriter, r *http.Request) {
  60. if r.URL.Path != "/" {
  61. http.NotFound(w, r)
  62. return
  63. }
  64. respondJSON(w, http.StatusOK, map[string]string{
  65. "service": serviceName,
  66. "status": "running",
  67. "mode": "http-microservice",
  68. })
  69. }
  70. // 健康检查处理器
  71. func (s *DBFactory) healthHandler(w http.ResponseWriter, r *http.Request) {
  72. if err := s.dbFactory.TestConnection(s.dbFactory.GetDBType()); err != nil {
  73. respondJSON(w, http.StatusServiceUnavailable, map[string]string{
  74. "status": "down",
  75. "error": err.Error(),
  76. })
  77. return
  78. }
  79. respondJSON(w, http.StatusOK, map[string]string{
  80. "status": "up",
  81. "time": time.Now().Format(time.RFC3339),
  82. })
  83. }
  84. // 信息处理器
  85. func infoHandler(w http.ResponseWriter, r *http.Request) {
  86. respondJSON(w, http.StatusOK, map[string]interface{}{
  87. "service": serviceName,
  88. "version": serviceVersion,
  89. "api": map[string]string{
  90. "POST /api/data/agent/to/doris": "同步数据到Doris",
  91. "GET /health": "健康检查",
  92. "GET /info": "服务信息",
  93. "GET /": "根路径",
  94. },
  95. "features": []string{
  96. "服务发现(Consul)",
  97. "负载均衡",
  98. "健康检查",
  99. "HTTP API网关",
  100. },
  101. })
  102. }
  103. // AgentToDoris处理器
  104. func (s *DBFactory) agentToDorisHandler(w http.ResponseWriter, r *http.Request) {
  105. if r.Method != "POST" {
  106. respondJSON(w, http.StatusMethodNotAllowed, types.QueryResult{
  107. Error: "只支持POST请求",
  108. Success: false,
  109. })
  110. return
  111. }
  112. // 解析请求
  113. var requestData types.QueryRequest
  114. if err := json.NewDecoder(r.Body).Decode(&requestData); err != nil {
  115. respondJSON(w, http.StatusBadRequest, map[string]string{
  116. "error": "无效的JSON数据",
  117. })
  118. return
  119. }
  120. // 处理业务逻辑
  121. result := service.ServiceAgentToDoris(s.dbFactory, requestData)
  122. respondJSON(w, http.StatusOK, result)
  123. }
  124. // 认证中间件
  125. func authMiddleware(next http.Handler) http.Handler {
  126. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  127. // JWT令牌认证
  128. token := r.Header.Get("Authorization")
  129. if token != "" && strings.HasPrefix(token, "Bearer ") {
  130. token = token[7:]
  131. }
  132. // 双重认证:API密钥或JWT
  133. if token == "" {
  134. respondJSON(w, http.StatusUnauthorized, map[string]string{
  135. "error": "需要API密钥或Bearer令牌",
  136. })
  137. return
  138. }
  139. // 验证JWT令牌
  140. if token != "" && !isValidJWT(token) {
  141. respondJSON(w, http.StatusUnauthorized, map[string]string{
  142. "error": "无效的访问令牌",
  143. })
  144. return
  145. }
  146. // 将认证信息添加到上下文
  147. ctx := r.Context()
  148. if token != "" {
  149. ctx = metadata.Set(ctx, "Authorization", "Bearer "+token)
  150. }
  151. next.ServeHTTP(w, r.WithContext(ctx))
  152. })
  153. }
  154. // JWT验证
  155. func isValidJWT(token string) bool {
  156. // TODO: 实现JWT验证逻辑
  157. // 可以使用 github.com/golang-jwt/jwt/v5
  158. // 临时实现:检查token是否有效格式
  159. //if len(token) < 10 {
  160. // return false
  161. // }
  162. return true // 临时返回true,实际需要验证签名和过期时间
  163. }
  164. // JSON响应辅助函数
  165. func respondJSON(w http.ResponseWriter, status int, data interface{}) {
  166. w.Header().Set("Content-Type", "application/json")
  167. w.Header().Set("X-Service-Name", serviceName)
  168. w.Header().Set("X-Service-Version", serviceVersion)
  169. w.WriteHeader(status)
  170. if err := json.NewEncoder(w).Encode(data); err != nil {
  171. log.Printf("JSON编码错误: %v", err)
  172. }
  173. }