// catalog-svc 目录库独立微服务。 // // 方案定位:目录库负责存储 MA、Hash、片库文件 ID、省内内容编码等映射关系, // 为标识查询接口提供统一入口。本服务可独立部署,也可嵌入 api-svc 使用。 // // 部署模式: // - 嵌入模式:通过 api.NewCatalogHandler 挂载到 api-svc 路由组 // - 独立模式:运行 catalog-svc,监听独立端口(默认 :8083) // // 环境变量: // - TCS_CATALOG_ADDR:监听地址(默认 :8083) // - TCS_CHAIN_BACKEND:链后端(memory/pg/chainmaker) // - TCS_POSTGRES_DSN:PostgreSQL 连接串 package main import ( "database/sql" "log" _ "github.com/lib/pq" "github.com/gin-gonic/gin" "github.com/tcs-iptv/tcs/internal/api" "github.com/tcs-iptv/tcs/internal/catalog" "github.com/tcs-iptv/tcs/internal/chain" "github.com/tcs-iptv/tcs/internal/config" "github.com/tcs-iptv/tcs/internal/httpx" "github.com/tcs-iptv/tcs/internal/monitor" ) // openDB 尝试连接 PostgreSQL。 func openDB(dsn string) *sql.DB { db, err := sql.Open("postgres", dsn) if err != nil { return nil } if err := db.Ping(); err != nil { return nil } return db } // newChain 按配置选择链后端(与 api-svc 相同逻辑)。 func newChain(backend, sdkConf string, db *sql.DB) chain.Client { switch backend { case "chainmaker": cm, err := chain.NewChainMakerClient(sdkConf, db) if err == nil { return cm } log.Printf("catalog-svc: ChainMaker 后端不可用(%v),降级", err) fallthrough case "pg": if db != nil { if pc, err := chain.NewPersistentChain(db); err == nil { return pc } } fallthrough default: log.Printf("catalog-svc: 使用内存链(仅开发用)") return chain.NewMemoryChain() } } func main() { cfg := config.Load() catalogAddr := cfg.CatalogAddr // 装配链后端 db := openDB(cfg.PostgresDSN) ch := newChain(cfg.ChainBackend, cfg.ChainMakerSDKConf, db) // 创建目录库服务 cat := catalog.New(ch) // 鉴权密钥库(与 api-svc 共享配置) keys := httpx.NewMemoryKeyStore() keys.Add("ak-regulator", "sk-regulator", string(chain.RoleRegulator)) keys.Add("ak-reviewer", "sk-reviewer", string(chain.RoleReviewer)) keys.Add("ak-cp", "sk-cp", string(chain.RoleCP)) keys.Add("ak-operator", "sk-operator", string(chain.RoleOperator)) r := gin.Default() httpx.Health(r, "catalog-svc") // 运行监控 r.Use(monitor.Middleware()) r.GET("/metrics", monitor.Handler()) // 目录库查询路由(受鉴权保护) v1 := r.Group("/api/v1", httpx.AuthMiddleware(keys)) catH := api.NewCatalogHandler(cat) catH.Register(v1) log.Printf("catalog-svc listening on %s", catalogAddr) if err := r.Run(catalogAddr); err != nil { log.Fatalf("catalog-svc failed: %v", err) } }