refactor: Replace switch statement with map-based config parsing
This commit is contained in:
146
config/config.go
146
config/config.go
@@ -8,83 +8,105 @@ import (
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// Environment variable names
|
||||
const (
|
||||
EnvLogLevel = "LOG_LEVEL"
|
||||
EnvRootPath = "ROOT_PATH"
|
||||
EnvNumWorkers = "NUM_OF_WORKERS"
|
||||
EnvWorkerBatchSize = "WORKER_BATCH_SIZE"
|
||||
EnvMaxResponseSize = "MAX_RESPONSE_SIZE"
|
||||
EnvResponseTimeout = "RESPONSE_TIMEOUT"
|
||||
)
|
||||
|
||||
// Config holds the application configuration loaded from environment variables
|
||||
type Config struct {
|
||||
LogLevel zerolog.Level
|
||||
rootPath string
|
||||
MaxResponseSize int
|
||||
NumOfWorkers int
|
||||
ResponseTimeout int
|
||||
WorkerBatchSize int
|
||||
LogLevel zerolog.Level // Logging level (debug, info, warn, error)
|
||||
RootPath string // Root path for the application
|
||||
MaxResponseSize int // Maximum size of response in bytes
|
||||
NumOfWorkers int // Number of concurrent workers
|
||||
ResponseTimeout int // Timeout for responses in seconds
|
||||
WorkerBatchSize int // Batch size for worker processing
|
||||
}
|
||||
|
||||
var CONFIG Config
|
||||
|
||||
func GetConfig() *Config {
|
||||
var config Config
|
||||
for _, envVar := range []string{
|
||||
"LOG_LEVEL",
|
||||
"ROOT_PATH",
|
||||
"NUM_OF_WORKERS",
|
||||
"WORKER_BATCH_SIZE",
|
||||
"MAX_RESPONSE_SIZE",
|
||||
"RESPONSE_TIMEOUT",
|
||||
} {
|
||||
if env, ok := os.LookupEnv(envVar); !ok {
|
||||
fmt.Fprintf(os.Stderr, "Missing env var %s\n", envVar)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
switch envVar {
|
||||
case "LOG_LEVEL":
|
||||
{
|
||||
logLevel, err := zerolog.ParseLevel(env)
|
||||
// parsePositiveInt parses and validates positive integer values
|
||||
func parsePositiveInt(value string) (int, error) {
|
||||
val, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Invalid LOG_LEVEL value\n")
|
||||
os.Exit(1)
|
||||
return 0, err
|
||||
}
|
||||
config.LogLevel = logLevel
|
||||
if val <= 0 {
|
||||
return 0, fmt.Errorf("value must be positive")
|
||||
}
|
||||
case "ROOT_PATH":
|
||||
{
|
||||
config.rootPath = env
|
||||
return val, nil
|
||||
}
|
||||
case "NUM_OF_WORKERS":
|
||||
{
|
||||
if numOfWorkers, err := strconv.Atoi(env); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Invalid NUM_OF_WORKERS value\n")
|
||||
os.Exit(1)
|
||||
} else {
|
||||
config.NumOfWorkers = numOfWorkers
|
||||
|
||||
// GetConfig loads and validates configuration from environment variables
|
||||
func GetConfig() *Config {
|
||||
config := &Config{}
|
||||
|
||||
// Map of environment variables to their parsing functions
|
||||
parsers := map[string]func(string) error{
|
||||
EnvLogLevel: func(v string) error {
|
||||
level, err := zerolog.ParseLevel(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid log level: %w", err)
|
||||
}
|
||||
config.LogLevel = level
|
||||
return nil
|
||||
},
|
||||
EnvRootPath: func(v string) error {
|
||||
config.RootPath = v
|
||||
return nil
|
||||
},
|
||||
EnvNumWorkers: func(v string) error {
|
||||
val, err := parsePositiveInt(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid number of workers: %w", err)
|
||||
}
|
||||
case "WORKER_BATCH_SIZE":
|
||||
{
|
||||
if workerBatchSize, err := strconv.Atoi(env); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Invalid WORKER_BATCH_SIZE value\n")
|
||||
os.Exit(1)
|
||||
} else {
|
||||
config.WorkerBatchSize = workerBatchSize
|
||||
config.NumOfWorkers = val
|
||||
return nil
|
||||
},
|
||||
EnvWorkerBatchSize: func(v string) error {
|
||||
val, err := parsePositiveInt(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid worker batch size: %w", err)
|
||||
}
|
||||
config.WorkerBatchSize = val
|
||||
return nil
|
||||
},
|
||||
EnvMaxResponseSize: func(v string) error {
|
||||
val, err := parsePositiveInt(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid max response size: %w", err)
|
||||
}
|
||||
case "MAX_RESPONSE_SIZE":
|
||||
{
|
||||
if maxResponseSize, err := strconv.Atoi(env); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Invalid MAX_RESPONSE_SIZE value\n")
|
||||
os.Exit(1)
|
||||
} else {
|
||||
config.MaxResponseSize = maxResponseSize
|
||||
config.MaxResponseSize = val
|
||||
return nil
|
||||
},
|
||||
EnvResponseTimeout: func(v string) error {
|
||||
val, err := parsePositiveInt(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid response timeout: %w", err)
|
||||
}
|
||||
}
|
||||
case "RESPONSE_TIMEOUT":
|
||||
{
|
||||
if val, err := strconv.Atoi(env); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Invalid RESPONSE_TIMEOUT value\n")
|
||||
os.Exit(1)
|
||||
} else {
|
||||
config.ResponseTimeout = val
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
// Process each environment variable
|
||||
for envVar, parser := range parsers {
|
||||
value, ok := os.LookupEnv(envVar)
|
||||
if !ok {
|
||||
fmt.Fprintf(os.Stderr, "Missing required environment variable: %s\n", envVar)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err := parser(value); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Configuration error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return &config
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user