Go 实现 /api/v1/analysis 契约、Demo/Live Worker、DeerFlow SSE;含设计文档与冒烟脚本。 Co-authored-by: Cursor <cursoragent@cursor.com>
145 lines
3.8 KiB
Go
145 lines
3.8 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Config 运行配置(环境变量优先,与 Java EBA_* / analysis.* 对齐)。
|
|
type Config struct {
|
|
Port int
|
|
|
|
// MySQL:优先 EBA_DB_DSN;否则用 HOST/PORT/NAME/USER/PASSWORD 拼,或解析 JDBC URL。
|
|
DBDSN string
|
|
|
|
AnalysisMode string // live | demo
|
|
AuthEnabled bool
|
|
DemoEnabled bool
|
|
LivePollMS int
|
|
DemoTickMS int
|
|
|
|
DeerFlowBaseURL string
|
|
DeerFlowUser string
|
|
DeerFlowPassword string
|
|
DeerFlowCoordinator string
|
|
DeerFlowStreamIdleTimeout int // 毫秒
|
|
}
|
|
|
|
// Load 从环境变量加载;缺省贴近本机联调。
|
|
func Load() Config {
|
|
c := Config{
|
|
Port: envInt("SERVER_PORT", 18097),
|
|
AnalysisMode: env("ANALYSIS_MODE", "live"),
|
|
AuthEnabled: envBool("ANALYSIS_AUTH_ENABLED", false),
|
|
DemoEnabled: envBool("EBA_WORKER_DEMO_ENABLED", false),
|
|
LivePollMS: envInt("EBA_WORKER_LIVE_POLL_MS", 1000),
|
|
DemoTickMS: envInt("EBA_WORKER_TICK_MS", 400),
|
|
DeerFlowBaseURL: strings.TrimRight(env("EBA_DF_BASE_URL", "http://127.0.0.1:8001"), "/"),
|
|
DeerFlowUser: env("EBA_DF_USER", "admin"),
|
|
DeerFlowPassword: env("EBA_DF_PASSWORD", "123ewq"),
|
|
DeerFlowCoordinator: env("EBA_DF_COORDINATOR", "roundtable-coordinator"),
|
|
DeerFlowStreamIdleTimeout: envInt("EBA_DF_STREAM_IDLE_TIMEOUT_MS", 180000),
|
|
}
|
|
c.DBDSN = resolveDSN()
|
|
// live 默认关掉 demo;显式 ANALYSIS_MODE=demo 时打开假进度
|
|
if c.AnalysisMode == "demo" {
|
|
c.DemoEnabled = true
|
|
}
|
|
if c.AnalysisMode == "live" && !envExplicit("EBA_WORKER_DEMO_ENABLED") {
|
|
c.DemoEnabled = false
|
|
}
|
|
return c
|
|
}
|
|
|
|
func resolveDSN() string {
|
|
if d := strings.TrimSpace(os.Getenv("EBA_DB_DSN")); d != "" {
|
|
return ensureMultiStatements(d)
|
|
}
|
|
user := env("EBA_DB_USER", "eba")
|
|
pass := env("EBA_DB_PASSWORD", "eba_local_dev")
|
|
jdbc := strings.TrimSpace(os.Getenv("EBA_DB_URL"))
|
|
if jdbc != "" {
|
|
if dsn, ok := jdbcToDSN(jdbc, user, pass); ok {
|
|
return dsn
|
|
}
|
|
}
|
|
host := env("EBA_DB_HOST", "127.0.0.1")
|
|
port := env("EBA_DB_PORT", "3306")
|
|
name := env("EBA_DB_NAME", "eightbf_analysis")
|
|
return user + ":" + pass + "@tcp(" + host + ":" + port + ")/" + name +
|
|
"?parseTime=true&loc=Asia%2FShanghai&charset=utf8mb4&multiStatements=true"
|
|
}
|
|
|
|
// jdbcToDSN 把 Java 的 jdbc:mysql://host:port/db?... 转成 Go driver DSN。
|
|
func jdbcToDSN(jdbc, user, pass string) (string, bool) {
|
|
s := strings.TrimPrefix(jdbc, "jdbc:mysql://")
|
|
if s == jdbc {
|
|
return "", false
|
|
}
|
|
hostPath := s
|
|
query := ""
|
|
if i := strings.Index(s, "?"); i >= 0 {
|
|
hostPath = s[:i]
|
|
query = s[i+1:]
|
|
}
|
|
host := hostPath
|
|
db := "eightbf_analysis"
|
|
if i := strings.Index(hostPath, "/"); i >= 0 {
|
|
host = hostPath[:i]
|
|
db = hostPath[i+1:]
|
|
}
|
|
params := "parseTime=true&loc=Asia%2FShanghai&charset=utf8mb4&multiStatements=true"
|
|
_ = query // Java JDBC 专用参数不照搬
|
|
return user + ":" + pass + "@tcp(" + host + ")/" + db + "?" + params, true
|
|
}
|
|
|
|
func ensureMultiStatements(dsn string) string {
|
|
if strings.Contains(dsn, "multiStatements=") {
|
|
return dsn
|
|
}
|
|
if strings.Contains(dsn, "?") {
|
|
return dsn + "&multiStatements=true"
|
|
}
|
|
return dsn + "?multiStatements=true"
|
|
}
|
|
|
|
func env(k, def string) string {
|
|
if v := strings.TrimSpace(os.Getenv(k)); v != "" {
|
|
return v
|
|
}
|
|
return def
|
|
}
|
|
|
|
func envExplicit(k string) bool {
|
|
_, ok := os.LookupEnv(k)
|
|
return ok
|
|
}
|
|
|
|
func envBool(k string, def bool) bool {
|
|
v := strings.TrimSpace(os.Getenv(k))
|
|
if v == "" {
|
|
return def
|
|
}
|
|
switch strings.ToLower(v) {
|
|
case "1", "true", "yes", "on":
|
|
return true
|
|
case "0", "false", "no", "off":
|
|
return false
|
|
default:
|
|
return def
|
|
}
|
|
}
|
|
|
|
func envInt(k string, def int) int {
|
|
v := strings.TrimSpace(os.Getenv(k))
|
|
if v == "" {
|
|
return def
|
|
}
|
|
n, err := strconv.Atoi(v)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
return n
|
|
}
|