183 lines
5.6 KiB
Go
183 lines
5.6 KiB
Go
package config
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/tech/sendico/pkg/db"
|
|
"github.com/tech/sendico/pkg/messaging"
|
|
)
|
|
|
|
const (
|
|
defaultShutdownTimeoutSeconds = 15
|
|
defaultMetricsAddress = ":9420"
|
|
defaultIngestStream = "CALLBACKS"
|
|
defaultIngestSubject = "callbacks.events"
|
|
defaultIngestDurable = "callbacks-ingest"
|
|
defaultIngestBatchSize = 32
|
|
defaultIngestFetchTimeoutMS = 2000
|
|
defaultIngestIdleSleepMS = 500
|
|
defaultTaskCollection = "callback_tasks"
|
|
defaultInboxCollection = "callback_inbox"
|
|
defaultEndpointsCollection = "webhook_endpoints"
|
|
defaultWorkerConcurrency = 8
|
|
defaultWorkerPollIntervalMS = 200
|
|
defaultLockTTLSeconds = 30
|
|
defaultRequestTimeoutMS = 10000
|
|
defaultMaxAttempts = 8
|
|
defaultMinDelayMS = 1000
|
|
defaultMaxDelayMS = 300000
|
|
defaultJitterRatio = 0.20
|
|
defaultDNSResolveTimeoutMS = 2000
|
|
defaultSecretsVaultField = "value"
|
|
)
|
|
|
|
// Loader parses callbacks service configuration.
|
|
type Loader interface {
|
|
Load(path string) (*Config, error)
|
|
}
|
|
|
|
// Config is the full callbacks service configuration.
|
|
type Config struct {
|
|
Runtime *RuntimeConfig `yaml:"runtime"`
|
|
Metrics *MetricsConfig `yaml:"metrics"`
|
|
Database *db.Config `yaml:"database"`
|
|
Messaging *messaging.Config `yaml:"messaging"`
|
|
Ingest IngestConfig `yaml:"ingest"`
|
|
Delivery DeliveryConfig `yaml:"delivery"`
|
|
Security SecurityConfig `yaml:"security"`
|
|
Secrets SecretsConfig `yaml:"secrets"`
|
|
}
|
|
|
|
// RuntimeConfig contains process lifecycle settings.
|
|
type RuntimeConfig struct {
|
|
ShutdownTimeoutSeconds int `yaml:"shutdown_timeout_seconds"`
|
|
}
|
|
|
|
func (c *RuntimeConfig) ShutdownTimeout() time.Duration {
|
|
if c == nil || c.ShutdownTimeoutSeconds <= 0 {
|
|
return defaultShutdownTimeoutSeconds * time.Second
|
|
}
|
|
return time.Duration(c.ShutdownTimeoutSeconds) * time.Second
|
|
}
|
|
|
|
// MetricsConfig configures observability endpoints.
|
|
type MetricsConfig struct {
|
|
Address string `yaml:"address"`
|
|
}
|
|
|
|
func (c *MetricsConfig) ListenAddress() string {
|
|
if c == nil || c.Address == "" {
|
|
return defaultMetricsAddress
|
|
}
|
|
return c.Address
|
|
}
|
|
|
|
// IngestConfig configures JetStream ingestion.
|
|
type IngestConfig struct {
|
|
Stream string `yaml:"stream"`
|
|
Subject string `yaml:"subject"`
|
|
Durable string `yaml:"durable"`
|
|
BatchSize int `yaml:"batch_size"`
|
|
FetchTimeoutMS int `yaml:"fetch_timeout_ms"`
|
|
IdleSleepMS int `yaml:"idle_sleep_ms"`
|
|
}
|
|
|
|
func (c *IngestConfig) FetchTimeout() time.Duration {
|
|
if c.FetchTimeoutMS <= 0 {
|
|
return time.Duration(defaultIngestFetchTimeoutMS) * time.Millisecond
|
|
}
|
|
return time.Duration(c.FetchTimeoutMS) * time.Millisecond
|
|
}
|
|
|
|
func (c *IngestConfig) IdleSleep() time.Duration {
|
|
if c.IdleSleepMS <= 0 {
|
|
return time.Duration(defaultIngestIdleSleepMS) * time.Millisecond
|
|
}
|
|
return time.Duration(c.IdleSleepMS) * time.Millisecond
|
|
}
|
|
|
|
// DeliveryConfig controls dispatcher behavior.
|
|
type DeliveryConfig struct {
|
|
WorkerConcurrency int `yaml:"worker_concurrency"`
|
|
WorkerPollMS int `yaml:"worker_poll_ms"`
|
|
LockTTLSeconds int `yaml:"lock_ttl_seconds"`
|
|
RequestTimeoutMS int `yaml:"request_timeout_ms"`
|
|
MaxAttempts int `yaml:"max_attempts"`
|
|
MinDelayMS int `yaml:"min_delay_ms"`
|
|
MaxDelayMS int `yaml:"max_delay_ms"`
|
|
JitterRatio float64 `yaml:"jitter_ratio"`
|
|
}
|
|
|
|
func (c *DeliveryConfig) WorkerPollInterval() time.Duration {
|
|
if c.WorkerPollMS <= 0 {
|
|
return time.Duration(defaultWorkerPollIntervalMS) * time.Millisecond
|
|
}
|
|
return time.Duration(c.WorkerPollMS) * time.Millisecond
|
|
}
|
|
|
|
func (c *DeliveryConfig) LockTTL() time.Duration {
|
|
if c.LockTTLSeconds <= 0 {
|
|
return time.Duration(defaultLockTTLSeconds) * time.Second
|
|
}
|
|
return time.Duration(c.LockTTLSeconds) * time.Second
|
|
}
|
|
|
|
func (c *DeliveryConfig) RequestTimeout() time.Duration {
|
|
if c.RequestTimeoutMS <= 0 {
|
|
return time.Duration(defaultRequestTimeoutMS) * time.Millisecond
|
|
}
|
|
return time.Duration(c.RequestTimeoutMS) * time.Millisecond
|
|
}
|
|
|
|
func (c *DeliveryConfig) MinDelay() time.Duration {
|
|
if c.MinDelayMS <= 0 {
|
|
return time.Duration(defaultMinDelayMS) * time.Millisecond
|
|
}
|
|
return time.Duration(c.MinDelayMS) * time.Millisecond
|
|
}
|
|
|
|
func (c *DeliveryConfig) MaxDelay() time.Duration {
|
|
if c.MaxDelayMS <= 0 {
|
|
return time.Duration(defaultMaxDelayMS) * time.Millisecond
|
|
}
|
|
return time.Duration(c.MaxDelayMS) * time.Millisecond
|
|
}
|
|
|
|
// SecurityConfig controls outbound callback safety checks.
|
|
type SecurityConfig struct {
|
|
RequireHTTPS bool `yaml:"require_https"`
|
|
AllowedHosts []string `yaml:"allowed_hosts"`
|
|
AllowedPorts []int `yaml:"allowed_ports"`
|
|
DNSResolveTimeout int `yaml:"dns_resolve_timeout_ms"`
|
|
}
|
|
|
|
func (c *SecurityConfig) DNSResolveTimeoutMS() time.Duration {
|
|
if c.DNSResolveTimeout <= 0 {
|
|
return time.Duration(defaultDNSResolveTimeoutMS) * time.Millisecond
|
|
}
|
|
return time.Duration(c.DNSResolveTimeout) * time.Millisecond
|
|
}
|
|
|
|
// SecretsConfig controls secret lookup behavior.
|
|
type SecretsConfig struct {
|
|
CacheTTLSeconds int `yaml:"cache_ttl_seconds"`
|
|
Static map[string]string `yaml:"static"`
|
|
Vault VaultSecretsConfig `yaml:"vault"`
|
|
}
|
|
|
|
// VaultSecretsConfig controls Vault KV secret resolution.
|
|
type VaultSecretsConfig struct {
|
|
Address string `yaml:"address"`
|
|
TokenEnv string `yaml:"token_env"`
|
|
Namespace string `yaml:"namespace"`
|
|
MountPath string `yaml:"mount_path"`
|
|
DefaultField string `yaml:"default_field"`
|
|
}
|
|
|
|
func (c *SecretsConfig) CacheTTL() time.Duration {
|
|
if c == nil || c.CacheTTLSeconds <= 0 {
|
|
return 0
|
|
}
|
|
return time.Duration(c.CacheTTLSeconds) * time.Second
|
|
}
|