Files
lingniu-vehicle-ingest/vehicle-data-platform/apps/api/internal/config/config.go
2026-07-27 16:46:15 +08:00

201 lines
7.9 KiB
Go

package config
import (
"os"
"strconv"
"strings"
"time"
)
type Config struct {
HTTPAddr string
StaticDir string
MySQLDSN string
RedisAddr string
RedisUsername string
RedisPassword string
RedisDB int
TDengineDriver string
TDengineDSN string
TDengineDatabase string
CapacityCheckBin string
AuthToken string
AuthMode string
AuthTokensJSON string
BootstrapAdminUsername string
BootstrapAdminPassword string
SessionTTL time.Duration
OneOSSSOEnabled bool
OneOSIntrospectionURL string
OneOSServiceToken string
OneOSSigningSecret string
OneOSAudience string
OneOSDefaultMenus []string
OneOSRequestTimeout time.Duration
OneOSSessionTTL time.Duration
DataMode string
ExportDir string
RequestTimeout time.Duration
AMapWebJSKey string
AMapAPIKey string
AMapSecurityCode string
AMapServiceHost string
PlatformRelease string
AlertEvaluationInterval time.Duration
AlertStreamMode string
AlertStreamKafkaBrokers []string
AlertStreamKafkaTopics []string
AlertStreamKafkaGroup string
AlertStreamBatchSize int
AlertStreamBatchWait time.Duration
AlertStreamLateness time.Duration
AlertNotificationTargetsJSON string
AlertNotificationSMSURL string
AlertNotificationSMSSecret string
AlertNotificationEmailURL string
AlertNotificationEmailSecret string
AlertNotificationWeComURL string
AlertNotificationWeComSecret string
AlertNotificationBatchSize int
AlertNotificationPollInterval time.Duration
AlertNotificationLease time.Duration
AlertNotificationTimeout time.Duration
HistoryCleanupAutomation bool
HistoryCleanupPollInterval time.Duration
HistoryCleanupLease time.Duration
}
func Load() Config {
return Config{
HTTPAddr: env("HTTP_ADDR", ":20300"),
StaticDir: env("STATIC_DIR", ""),
MySQLDSN: os.Getenv("MYSQL_DSN"),
RedisAddr: os.Getenv("REDIS_ADDR"),
RedisUsername: os.Getenv("REDIS_USERNAME"),
RedisPassword: os.Getenv("REDIS_PASSWORD"),
RedisDB: envInt("REDIS_DB", 50),
TDengineDriver: env("TDENGINE_DRIVER", "taosWS"),
TDengineDSN: os.Getenv("TDENGINE_DSN"),
TDengineDatabase: env("TDENGINE_DATABASE", "lingniu_vehicle_ts"),
CapacityCheckBin: os.Getenv("CAPACITY_CHECK_BIN"),
AuthToken: os.Getenv("AUTH_TOKEN"),
AuthMode: authMode(),
AuthTokensJSON: os.Getenv("AUTH_TOKENS_JSON"),
BootstrapAdminUsername: os.Getenv("BOOTSTRAP_ADMIN_USERNAME"),
BootstrapAdminPassword: os.Getenv("BOOTSTRAP_ADMIN_PASSWORD"),
SessionTTL: time.Duration(envInt("AUTH_SESSION_TTL_HOURS", 12)) * time.Hour,
OneOSSSOEnabled: envBool("ONEOS_SSO_ENABLED", false),
OneOSIntrospectionURL: os.Getenv("ONEOS_SSO_INTROSPECTION_URL"),
OneOSServiceToken: os.Getenv("ONEOS_SSO_SERVICE_TOKEN"),
OneOSSigningSecret: os.Getenv("ONEOS_SSO_SIGNING_SECRET"),
OneOSAudience: env("ONEOS_SSO_AUDIENCE", "vehicle-platform"),
OneOSDefaultMenus: splitCSV(env("ONEOS_SSO_DEFAULT_MENUS", "vehicles")),
OneOSRequestTimeout: time.Duration(envInt("ONEOS_SSO_REQUEST_TIMEOUT_MS", 3000)) * time.Millisecond,
OneOSSessionTTL: time.Duration(envInt("ONEOS_SSO_SESSION_TTL_MINUTES", 30)) * time.Minute,
DataMode: dataMode(),
ExportDir: os.Getenv("EXPORT_DIR"),
RequestTimeout: time.Duration(envInt("REQUEST_TIMEOUT_MS", 5000)) * time.Millisecond,
AMapWebJSKey: os.Getenv("AMAP_WEB_JS_KEY"),
AMapAPIKey: os.Getenv("AMAP_API_KEY"),
AMapSecurityCode: os.Getenv("AMAP_SECURITY_JS_CODE"),
AMapServiceHost: os.Getenv("AMAP_SECURITY_SERVICE_HOST"),
PlatformRelease: os.Getenv("PLATFORM_RELEASE"),
AlertEvaluationInterval: time.Duration(envInt("ALERT_EVALUATION_INTERVAL_SEC", 10)) * time.Second,
AlertStreamMode: strings.ToLower(env("ALERT_STREAM_MODE", "disabled")),
AlertStreamKafkaBrokers: splitCSV(firstEnv("ALERT_STREAM_KAFKA_BROKERS", "KAFKA_BROKERS")),
AlertStreamKafkaTopics: splitCSV(env("ALERT_STREAM_KAFKA_TOPICS", "vehicle.fields.go.gb32960.v1,vehicle.fields.go.jt808.v1,vehicle.fields.go.yutong-mqtt.v1")),
AlertStreamKafkaGroup: env("ALERT_STREAM_KAFKA_GROUP", "vehicle-alert-stream-v1"),
AlertStreamBatchSize: envInt("ALERT_STREAM_BATCH_SIZE", 200),
AlertStreamBatchWait: time.Duration(envInt("ALERT_STREAM_BATCH_WAIT_MS", 100)) * time.Millisecond,
AlertStreamLateness: time.Duration(envInt("ALERT_STREAM_LATENESS_SEC", 120)) * time.Second,
AlertNotificationTargetsJSON: os.Getenv("ALERT_NOTIFICATION_TARGETS_JSON"),
AlertNotificationSMSURL: os.Getenv("ALERT_NOTIFICATION_SMS_URL"),
AlertNotificationSMSSecret: os.Getenv("ALERT_NOTIFICATION_SMS_SECRET"),
AlertNotificationEmailURL: os.Getenv("ALERT_NOTIFICATION_EMAIL_URL"),
AlertNotificationEmailSecret: os.Getenv("ALERT_NOTIFICATION_EMAIL_SECRET"),
AlertNotificationWeComURL: os.Getenv("ALERT_NOTIFICATION_WECOM_URL"),
AlertNotificationWeComSecret: os.Getenv("ALERT_NOTIFICATION_WECOM_SECRET"),
AlertNotificationBatchSize: envInt("ALERT_NOTIFICATION_BATCH_SIZE", 20),
AlertNotificationPollInterval: time.Duration(envInt("ALERT_NOTIFICATION_POLL_INTERVAL_MS", 1000)) * time.Millisecond,
AlertNotificationLease: time.Duration(envInt("ALERT_NOTIFICATION_LEASE_SEC", 30)) * time.Second,
AlertNotificationTimeout: time.Duration(envInt("ALERT_NOTIFICATION_TIMEOUT_MS", 5000)) * time.Millisecond,
HistoryCleanupAutomation: envBool("HISTORY_EXPORT_CLEANUP_AUTOMATION_ENABLED", false),
HistoryCleanupPollInterval: time.Duration(envInt("HISTORY_EXPORT_CLEANUP_POLL_SEC", 60)) * time.Second,
HistoryCleanupLease: time.Duration(envInt("HISTORY_EXPORT_CLEANUP_LEASE_SEC", 300)) * time.Second,
}
}
func firstEnv(keys ...string) string {
for _, key := range keys {
if value := os.Getenv(key); value != "" {
return value
}
}
return ""
}
func splitCSV(raw string) []string {
parts := strings.Split(raw, ",")
values := make([]string, 0, len(parts))
seen := map[string]bool{}
for _, part := range parts {
part = strings.TrimSpace(part)
if part != "" && !seen[part] {
seen[part] = true
values = append(values, part)
}
}
return values
}
func dataMode() string {
if value := os.Getenv("DATA_MODE"); value != "" {
return value
}
if os.Getenv("MYSQL_DSN") != "" {
return "production"
}
return "mock"
}
func authMode() string {
if value := os.Getenv("AUTH_MODE"); value != "" {
return value
}
if os.Getenv("AUTH_TOKEN") != "" || os.Getenv("AUTH_TOKENS_JSON") != "" {
return "enforce"
}
return "disabled"
}
func env(key, fallback string) string {
if value := os.Getenv(key); value != "" {
return value
}
return fallback
}
func envInt(key string, fallback int) int {
raw := os.Getenv(key)
if raw == "" {
return fallback
}
value, err := strconv.Atoi(raw)
if err != nil {
return fallback
}
return value
}
func envBool(key string, fallback bool) bool {
raw := strings.ToLower(strings.TrimSpace(os.Getenv(key)))
switch raw {
case "1", "true", "yes", "on":
return true
case "0", "false", "no", "off":
return false
default:
return fallback
}
}