Add monitoring metrics, numeric sorting, report-time display, vehicle number labels, and map layout fixes. Include accumulated mileage, hydrogen, OneOS authentication, open platform, ingestion, deployment, and UI updates. Exclude temporary files, generated reports, and credentials. Validate frontend 632 tests and production build, API packages, vehicle-map tests, and release installer tests. Gateway suite has one pre-existing date-sensitive identity throttling test failure reproduced on the parent commit.
243 lines
10 KiB
Go
243 lines
10 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Config struct {
|
|
DailyGeographyEnabled bool
|
|
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
|
|
OneOSProfileEnabled bool
|
|
OneOSAuthEnabled bool
|
|
OneOSProfileBaseURL string
|
|
OneOSProfileServiceToken string
|
|
OneOSProfileIssuer string
|
|
OneOSProfileAllowedTenant string
|
|
OneOSProfileTimeout time.Duration
|
|
OneOSPublicOrigin string
|
|
OneOSPasswordEnabled bool
|
|
OneOSPasswordClientID string
|
|
OneOSPasswordRSAPublicKey string
|
|
OneOSLoginTicketExchangePath string
|
|
OneOSLoginTicketServiceToken string
|
|
OneOSDevIntegration bool
|
|
OneOSLocalBackend bool
|
|
OneOSVehicleQueryScope bool
|
|
OneOSDevDataProxyURL string
|
|
OneOSDevDataProxyToken string
|
|
OneOSLocalOnly bool
|
|
OneOSVehicleScopePath string
|
|
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,
|
|
OneOSProfileEnabled: envBool("ONEOS_PROFILE_ENABLED", false),
|
|
OneOSAuthEnabled: envBool("ONEOS_AUTH_ENABLED", false),
|
|
OneOSProfileBaseURL: os.Getenv("ONEOS_PROFILE_BASE_URL"),
|
|
OneOSProfileServiceToken: os.Getenv("ONEOS_PROFILE_SERVICE_TOKEN"),
|
|
OneOSProfileIssuer: os.Getenv("ONEOS_PROFILE_ISSUER"),
|
|
OneOSProfileAllowedTenant: os.Getenv("ONEOS_PROFILE_ALLOWED_TENANT"),
|
|
OneOSProfileTimeout: time.Duration(envInt("ONEOS_PROFILE_TIMEOUT_MS", 3500)) * time.Millisecond,
|
|
OneOSPublicOrigin: os.Getenv("ONEOS_PUBLIC_ORIGIN"),
|
|
OneOSPasswordEnabled: envBool("ONEOS_PASSWORD_ENABLED", false),
|
|
OneOSPasswordClientID: os.Getenv("ONEOS_PASSWORD_CLIENT_ID"),
|
|
OneOSPasswordRSAPublicKey: os.Getenv("ONEOS_PASSWORD_RSA_PUBLIC_KEY"),
|
|
OneOSLoginTicketExchangePath: os.Getenv("ONEOS_LOGIN_TICKET_EXCHANGE_PATH"),
|
|
OneOSLoginTicketServiceToken: os.Getenv("ONEOS_LOGIN_TICKET_SERVICE_TOKEN"),
|
|
OneOSDevIntegration: envBool("ONEOS_DEV_INTEGRATION", false),
|
|
OneOSLocalBackend: envBool("ONEOS_LOCAL_BACKEND", false),
|
|
OneOSVehicleQueryScope: envBool("ONEOS_VEHICLE_QUERY_SCOPE", false),
|
|
OneOSDevDataProxyURL: os.Getenv("ONEOS_DEV_DATA_PROXY_URL"),
|
|
OneOSDevDataProxyToken: os.Getenv("ONEOS_DEV_DATA_PROXY_TOKEN"),
|
|
OneOSLocalOnly: envBool("ONEOS_LOCAL_ONLY", false),
|
|
OneOSVehicleScopePath: os.Getenv("ONEOS_VEHICLE_SCOPE_PATH"),
|
|
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"),
|
|
DailyGeographyEnabled: envBool("DAILY_GEOGRAPHY_ENABLED", false),
|
|
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
|
|
}
|
|
}
|