package config import ( "encoding/json" "fmt" "os" "time" ) type Config struct { Server ServerConfig `json:"server"` Gateway GatewayConfig `json:"gateway"` Auth AuthConfig `json:"auth"` } type ServerConfig struct { HTTPListen string `json:"httpListen"` ReadTimeoutSeconds int `json:"readTimeoutSeconds"` WriteTimeoutSeconds int `json:"writeTimeoutSeconds"` IdleTimeoutSeconds int `json:"idleTimeoutSeconds"` ShutdownTimeoutSeconds int `json:"shutdownTimeoutSeconds"` } type GatewayConfig struct { MaxPayloadBytes int `json:"maxPayloadBytes"` WriteWaitSeconds int `json:"writeWaitSeconds"` PongWaitSeconds int `json:"pongWaitSeconds"` PingIntervalSeconds int `json:"pingIntervalSeconds"` MaxLatestStateEntries int `json:"maxLatestStateEntries"` } type AuthConfig struct { ProducerTokens []string `json:"producerTokens"` ConsumerTokens []string `json:"consumerTokens"` ControllerTokens []string `json:"controllerTokens"` AllowAnonymousConsumers bool `json:"allowAnonymousConsumers"` } func Load(path string) (Config, error) { data, err := os.ReadFile(path) if err != nil { return Config{}, fmt.Errorf("read config: %w", err) } var cfg Config if err := json.Unmarshal(data, &cfg); err != nil { return Config{}, fmt.Errorf("parse config: %w", err) } cfg.applyDefaults() if err := cfg.validate(); err != nil { return Config{}, err } return cfg, nil } func (c *Config) applyDefaults() { if c.Server.HTTPListen == "" { c.Server.HTTPListen = ":8080" } if c.Server.ReadTimeoutSeconds <= 0 { c.Server.ReadTimeoutSeconds = 15 } if c.Server.WriteTimeoutSeconds <= 0 { c.Server.WriteTimeoutSeconds = 15 } if c.Server.IdleTimeoutSeconds <= 0 { c.Server.IdleTimeoutSeconds = 60 } if c.Server.ShutdownTimeoutSeconds <= 0 { c.Server.ShutdownTimeoutSeconds = 10 } if c.Gateway.MaxPayloadBytes <= 0 { c.Gateway.MaxPayloadBytes = 64 * 1024 } if c.Gateway.WriteWaitSeconds <= 0 { c.Gateway.WriteWaitSeconds = 10 } if c.Gateway.PongWaitSeconds <= 0 { c.Gateway.PongWaitSeconds = 60 } if c.Gateway.PingIntervalSeconds <= 0 { c.Gateway.PingIntervalSeconds = 25 } if c.Gateway.MaxLatestStateEntries <= 0 { c.Gateway.MaxLatestStateEntries = 10000 } } func (c Config) validate() error { if c.Gateway.PingInterval() >= c.Gateway.PongWait() { return fmt.Errorf("gateway.pingIntervalSeconds must be smaller than gateway.pongWaitSeconds") } return nil } func (c ServerConfig) ReadTimeout() time.Duration { return time.Duration(c.ReadTimeoutSeconds) * time.Second } func (c ServerConfig) WriteTimeout() time.Duration { return time.Duration(c.WriteTimeoutSeconds) * time.Second } func (c ServerConfig) IdleTimeout() time.Duration { return time.Duration(c.IdleTimeoutSeconds) * time.Second } func (c ServerConfig) ShutdownTimeout() time.Duration { return time.Duration(c.ShutdownTimeoutSeconds) * time.Second } func (c GatewayConfig) WriteWait() time.Duration { return time.Duration(c.WriteWaitSeconds) * time.Second } func (c GatewayConfig) PongWait() time.Duration { return time.Duration(c.PongWaitSeconds) * time.Second } func (c GatewayConfig) PingInterval() time.Duration { return time.Duration(c.PingIntervalSeconds) * time.Second }