暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "git.x2erp.com/qdy/go-svc-mcp/internal/handler"
  7. "git.x2erp.com/qdy/go-svc-mcp/internal/mcp"
  8. _ "git.x2erp.com/qdy/go-svc-mcp/internal/tools/commons" // 触发工具自动注册
  9. _ "git.x2erp.com/qdy/go-svc-mcp/internal/tools/dbs" // 触发工具自动注册
  10. "git.x2erp.com/qdy/go-base/authbase"
  11. "git.x2erp.com/qdy/go-base/config"
  12. "git.x2erp.com/qdy/go-base/config/core"
  13. "git.x2erp.com/qdy/go-base/config/subconfigs"
  14. "git.x2erp.com/qdy/go-base/container"
  15. "git.x2erp.com/qdy/go-base/graceful"
  16. "git.x2erp.com/qdy/go-base/logger"
  17. "git.x2erp.com/qdy/go-base/webx"
  18. "git.x2erp.com/qdy/go-base/webx/router"
  19. "git.x2erp.com/qdy/go-db/factory/database"
  20. "git.x2erp.com/qdy/go-db/sqldef"
  21. mcpsdk "github.com/modelcontextprotocol/go-sdk/mcp"
  22. _ "git.x2erp.com/qdy/go-svc-mcp/internal/tables" // 导入表定义包,触发 init() 函数
  23. )
  24. // 数据库配置键名常量(yaml配置键名)
  25. const (
  26. // BusinessDBKey 业务数据库键名
  27. BusinessDBKey = "business"
  28. // WarehouseDBKey 仓库数据库键名
  29. WarehouseDBKey = "warehouse"
  30. )
  31. var (
  32. appName = "svc-mcp"
  33. appVersion = "1"
  34. )
  35. func validateDbsConfigKeys() error {
  36. // 获取 dbs 配置
  37. dbsConfig := core.GetRegisteredConfig("dbs")
  38. if dbsConfig == nil {
  39. log.Println("多数据库配置为空,数据库相关工具无法使用")
  40. log.Println("配置要求说明:")
  41. log.Println("1. 在配置文件中添加 dbs 配置节")
  42. log.Println("2. 必须同时配置 'business' 和 'warehouse' 两个数据库")
  43. log.Println("3. 示例配置:")
  44. log.Println(" databases:")
  45. log.Println(" business:")
  46. log.Println(" host: \"localhost\"")
  47. log.Println(" port: 3306")
  48. log.Println(" warehouse:")
  49. log.Println(" host: \"localhost\"")
  50. log.Println(" port: 3307")
  51. return nil // 空配置允许继续执行
  52. }
  53. dbs, ok := dbsConfig.(*subconfigs.DbsConfig)
  54. if !ok {
  55. return fmt.Errorf("dbs配置类型错误")
  56. }
  57. if len(dbs.Databases) == 0 {
  58. log.Println("多数据库配置为空,数据库相关工具无法使用")
  59. log.Println("配置要求说明:")
  60. log.Println("1. 在配置文件中添加 dbs 配置节")
  61. log.Println("2. 必须同时配置 'business' 和 'warehouse' 两个数据库")
  62. log.Println("3. 示例配置:")
  63. log.Println(" databases:")
  64. log.Println(" business:")
  65. log.Println(" host: \"localhost\"")
  66. log.Println(" port: 3306")
  67. log.Println(" warehouse:")
  68. log.Println(" host: \"localhost\"")
  69. log.Println(" port: 3307")
  70. return nil // 空配置允许继续执行
  71. }
  72. // 检查配置的键名必须是 business 和 warehouse
  73. hasBusiness := false
  74. hasWarehouse := false
  75. for key := range dbs.Databases {
  76. switch key {
  77. case BusinessDBKey:
  78. hasBusiness = true
  79. case WarehouseDBKey:
  80. hasWarehouse = true
  81. default:
  82. return fmt.Errorf("数据库配置键名 '%s' 错误,只允许配置 '%s' 和 '%s'", key, BusinessDBKey, WarehouseDBKey)
  83. }
  84. }
  85. // 检查是否同时包含 business 和 warehouse
  86. if !hasBusiness || !hasWarehouse {
  87. return fmt.Errorf("数据库配置必须同时包含 '%s' 和 '%s' 两个数据库", BusinessDBKey, WarehouseDBKey)
  88. }
  89. // 检查是否有额外的数据库配置
  90. if len(dbs.Databases) > 2 {
  91. return fmt.Errorf("数据库配置只能包含 '%s' 和 '%s' 两个数据库,不能有其他数据库配置", BusinessDBKey, WarehouseDBKey)
  92. }
  93. log.Printf("多数据库配置键名验证通过,包含 %s 和 %s 数据库", BusinessDBKey, WarehouseDBKey)
  94. return nil
  95. }
  96. func main() {
  97. // 0. 初始化日志
  98. logBootFactory := logger.InitBootLog()
  99. // 1. 获取配置文件
  100. cfg := config.GetConfig()
  101. cfg.SetAppName(appName)
  102. cfg.SetAppVersion(appVersion)
  103. // 验证多数据库配置键名
  104. if err := validateDbsConfigKeys(); err != nil {
  105. log.Fatalf("多数据库配置验证失败: %v", err)
  106. }
  107. // 2. 创建关闭容器
  108. ctr := container.NewContainer(cfg)
  109. // 注册日志,实现自动关闭
  110. container.Reg(ctr, logBootFactory)
  111. // 3. 创建数据库工厂
  112. dbFactory := container.Create(ctr, database.CreateDBFactory)
  113. dbFactory.TestConnection()
  114. //建立多数据库
  115. dbs := container.Create(ctr, database.CreateDBSFactory)
  116. // 创建表
  117. creteTabel(dbFactory)
  118. // 创建mongodb
  119. //mongoDBFactory := container.Create(ctr, mongodb.CreateFactory)
  120. //mongoDBFactory.TestConnection()
  121. // 创建mcpservice
  122. mcpServer := createMcpService(cfg, dbFactory, dbs)
  123. //启用运行日志
  124. container.Create(ctr, logger.InitRuntimeLogger)
  125. //建立httpservice
  126. webxService := createMHttpService(cfg, dbFactory)
  127. //等待关闭
  128. graceful.WaitForShutdown(cfg.GetServiceConfig().ServiceName, ctr, mcpServer.GetHTTPServer(), webxService.GetServer())
  129. }
  130. // 创建httpService
  131. func createMHttpService(cfg config.IConfig, dbFactory *database.DBFactory) *webx.WebService {
  132. //得到webservice服务工厂
  133. webxFactory := webx.GetWebServiceFactory()
  134. //建立hhtpService服务
  135. webServcie, _ := webxFactory.CreateService(cfg.GetServiceConfig())
  136. //建立路由-api
  137. routerService := router.NewWebService(webServcie.GetRouter())
  138. //注册路由--api
  139. handler.RegisterRouter(routerService, dbFactory)
  140. //启动服务
  141. webServcie.Run()
  142. return webServcie
  143. }
  144. // createMcpService 创建mcpService
  145. func createMcpService(cfg config.IConfig, dbFactory *database.DBFactory, dbs *database.DBSFactory) *mcp.Server {
  146. // 4. 创建基础请求上下文(可从配置或认证中提取)
  147. //baseCtx := &ctx.RequestContext{
  148. // TenantID: "default-tenant", // 实际应从认证中间件获取
  149. //}
  150. // 5. 创建 MCP 服务器
  151. mcpServer, err := mcp.NewServer(mcp.Config{
  152. Name: appName,
  153. Version: appVersion,
  154. Description: "MCP 工具服务,提供自动注册发现和依赖注入",
  155. DBFactory: dbFactory,
  156. DBSFactory: dbs,
  157. Port: cfg.GetMcpServiceConfig().Port,
  158. ServiceName: cfg.GetMcpServiceConfig().ServiceName,
  159. })
  160. if err != nil {
  161. log.Fatalf("Failed to create MCP server: %v", err)
  162. }
  163. log.Printf("MCP server created with tools registered")
  164. // 6. 获取 SDK 服务器实例
  165. sdkServer := mcpServer.GetSDKServer()
  166. mcpHandler := mcpsdk.NewStreamableHTTPHandler(func(req *http.Request) *mcpsdk.Server {
  167. return sdkServer
  168. }, nil)
  169. // 包装验证中间件
  170. //handler := auth.AuthMiddlewareMcp(mcpHandler, dbFactory)
  171. handler := authbase.TokenAuth(mcpHandler)
  172. sdkServer.AddReceivingMiddleware()
  173. mcpServer.Run(handler)
  174. return mcpServer
  175. }
  176. func creteTabel(factory *database.DBFactory) {
  177. // 获取数据库连接和类型
  178. db := factory.GetDB()
  179. dbType := factory.GetDBType()
  180. // 创建表同步器
  181. syncer, err := sqldef.NewTableSyncer(db, dbType)
  182. if err != nil {
  183. log.Printf("创建 - 建立器失败: %v", err)
  184. return
  185. }
  186. // 创建表
  187. if err := syncer.CreateTables(); err != nil {
  188. log.Printf("建表失败: %v", err)
  189. return
  190. }
  191. log.Println("数据库表建立完成!")
  192. }