initial commit
This commit is contained in:
225
pkg/rabbit/config.go
Normal file
225
pkg/rabbit/config.go
Normal file
@@ -0,0 +1,225 @@
|
||||
package rabbitmq
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
// Connection settings
|
||||
URL string `json:"url"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
VHost string `json:"vhost"`
|
||||
UseTLS bool `json:"use_tls"`
|
||||
|
||||
// Connection pool settings
|
||||
MaxConnections int `json:"max_connections"`
|
||||
MaxChannels int `json:"max_channels"`
|
||||
ConnectionTimeout time.Duration `json:"connection_timeout"`
|
||||
HeartbeatInterval time.Duration `json:"heartbeat_interval"`
|
||||
|
||||
// Reconnection settings
|
||||
ReconnectDelay time.Duration `json:"reconnect_delay"`
|
||||
MaxReconnectDelay time.Duration `json:"max_reconnect_delay"`
|
||||
ReconnectAttempts int `json:"reconnect_attempts"`
|
||||
EnableAutoReconnect bool `json:"enable_auto_reconnect"`
|
||||
|
||||
// Publisher settings
|
||||
PublisherConfig PublisherOptions `json:"publisher_config"`
|
||||
|
||||
// Health check settings
|
||||
HealthCheckInterval time.Duration `json:"health_check_interval"`
|
||||
}
|
||||
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
Host: "localhost",
|
||||
Port: 5672,
|
||||
Username: "guest",
|
||||
Password: "guest",
|
||||
VHost: "/",
|
||||
UseTLS: false,
|
||||
MaxConnections: 10,
|
||||
MaxChannels: 100,
|
||||
ConnectionTimeout: 30 * time.Second,
|
||||
HeartbeatInterval: 60 * time.Second,
|
||||
ReconnectDelay: 5 * time.Second,
|
||||
MaxReconnectDelay: 5 * time.Minute,
|
||||
ReconnectAttempts: 10,
|
||||
EnableAutoReconnect: true,
|
||||
PublisherConfig: PublisherOptions{
|
||||
ConfirmMode: true,
|
||||
Mandatory: false,
|
||||
Immediate: false,
|
||||
RetryAttempts: 3,
|
||||
RetryDelay: 1 * time.Second,
|
||||
ConfirmTimeout: 10 * time.Second,
|
||||
},
|
||||
HealthCheckInterval: 30 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) BuildConnectionString() string {
|
||||
if c.URL != "" {
|
||||
return c.URL
|
||||
}
|
||||
|
||||
scheme := "amqp"
|
||||
if c.UseTLS {
|
||||
scheme = "amqps"
|
||||
}
|
||||
|
||||
// Build URL
|
||||
u := &url.URL{
|
||||
Scheme: scheme,
|
||||
Host: fmt.Sprintf("%s:%d", c.Host, c.Port),
|
||||
Path: c.VHost,
|
||||
}
|
||||
|
||||
if c.Username != "" && c.Password != "" {
|
||||
u.User = url.UserPassword(c.Username, c.Password)
|
||||
}
|
||||
|
||||
return u.String()
|
||||
}
|
||||
|
||||
func (c *Config) Validate() error {
|
||||
if c.URL == "" {
|
||||
if c.Host == "" {
|
||||
return NewConfigurationError("host", c.Host, "host cannot be empty when URL is not provided")
|
||||
}
|
||||
if c.Port <= 0 || c.Port > 65535 {
|
||||
return NewConfigurationError("port", c.Port, "port must be between 1 and 65535")
|
||||
}
|
||||
} else {
|
||||
if _, err := url.Parse(c.URL); err != nil {
|
||||
return NewConfigurationError("url", c.URL, fmt.Sprintf("invalid URL format: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
if c.MaxConnections <= 0 {
|
||||
return NewConfigurationError("max_connections", c.MaxConnections, "max_connections must be greater than 0")
|
||||
}
|
||||
|
||||
if c.MaxChannels <= 0 {
|
||||
return NewConfigurationError("max_channels", c.MaxChannels, "max_channels must be greater than 0")
|
||||
}
|
||||
|
||||
if c.ConnectionTimeout <= 0 {
|
||||
return NewConfigurationError("connection_timeout", c.ConnectionTimeout, "connection_timeout must be greater than 0")
|
||||
}
|
||||
|
||||
if c.HeartbeatInterval < 0 {
|
||||
return NewConfigurationError("heartbeat_interval", c.HeartbeatInterval, "heartbeat_interval cannot be negative")
|
||||
}
|
||||
|
||||
if c.ReconnectDelay <= 0 {
|
||||
return NewConfigurationError("reconnect_delay", c.ReconnectDelay, "reconnect_delay must be greater than 0")
|
||||
}
|
||||
|
||||
if c.MaxReconnectDelay < c.ReconnectDelay {
|
||||
return NewConfigurationError("max_reconnect_delay", c.MaxReconnectDelay, "max_reconnect_delay must be greater than or equal to reconnect_delay")
|
||||
}
|
||||
|
||||
if c.ReconnectAttempts < 0 {
|
||||
return NewConfigurationError("reconnect_attempts", c.ReconnectAttempts, "reconnect_attempts cannot be negative")
|
||||
}
|
||||
|
||||
if c.HealthCheckInterval < 0 {
|
||||
return NewConfigurationError("health_check_interval", c.HealthCheckInterval, "health_check_interval cannot be negative")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) validatePublisherConfig() error {
|
||||
if c.PublisherConfig.RetryAttempts < 0 {
|
||||
return NewConfigurationError("publisher.retry_attempts", c.PublisherConfig.RetryAttempts, "retry_attempts cannot be negative")
|
||||
}
|
||||
|
||||
if c.PublisherConfig.RetryDelay < 0 {
|
||||
return NewConfigurationError("publisher.retry_delay", c.PublisherConfig.RetryDelay, "retry_delay cannot be negative")
|
||||
}
|
||||
|
||||
if c.PublisherConfig.ConfirmTimeout <= 0 {
|
||||
return NewConfigurationError("publisher.confirm_timeout", c.PublisherConfig.ConfirmTimeout, "confirm_timeout must be greater than 0")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) ApplyDefaults() {
|
||||
defaults := DefaultConfig()
|
||||
|
||||
if c.Host == "" && c.URL == "" {
|
||||
c.Host = defaults.Host
|
||||
}
|
||||
if c.Port == 0 {
|
||||
c.Port = defaults.Port
|
||||
}
|
||||
if c.Username == "" {
|
||||
c.Username = defaults.Username
|
||||
}
|
||||
if c.Password == "" {
|
||||
c.Password = defaults.Password
|
||||
}
|
||||
if c.VHost == "" {
|
||||
c.VHost = defaults.VHost
|
||||
}
|
||||
if c.MaxConnections == 0 {
|
||||
c.MaxConnections = defaults.MaxConnections
|
||||
}
|
||||
if c.MaxChannels == 0 {
|
||||
c.MaxChannels = defaults.MaxChannels
|
||||
}
|
||||
if c.ConnectionTimeout == 0 {
|
||||
c.ConnectionTimeout = defaults.ConnectionTimeout
|
||||
}
|
||||
if c.HeartbeatInterval == 0 {
|
||||
c.HeartbeatInterval = defaults.HeartbeatInterval
|
||||
}
|
||||
if c.ReconnectDelay == 0 {
|
||||
c.ReconnectDelay = defaults.ReconnectDelay
|
||||
}
|
||||
if c.MaxReconnectDelay == 0 {
|
||||
c.MaxReconnectDelay = defaults.MaxReconnectDelay
|
||||
}
|
||||
if c.ReconnectAttempts == 0 {
|
||||
c.ReconnectAttempts = defaults.ReconnectAttempts
|
||||
}
|
||||
|
||||
if c.HealthCheckInterval == 0 {
|
||||
c.HealthCheckInterval = defaults.HealthCheckInterval
|
||||
}
|
||||
|
||||
// Apply publisher defaults
|
||||
if c.PublisherConfig.RetryAttempts == 0 {
|
||||
c.PublisherConfig.RetryAttempts = defaults.PublisherConfig.RetryAttempts
|
||||
}
|
||||
if c.PublisherConfig.RetryDelay == 0 {
|
||||
c.PublisherConfig.RetryDelay = defaults.PublisherConfig.RetryDelay
|
||||
}
|
||||
if c.PublisherConfig.ConfirmTimeout == 0 {
|
||||
c.PublisherConfig.ConfirmTimeout = defaults.PublisherConfig.ConfirmTimeout
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (c *Config) Clone() *Config {
|
||||
clone := *c
|
||||
|
||||
// Deep copy publisher config
|
||||
clone.PublisherConfig = c.PublisherConfig
|
||||
if c.PublisherConfig.Args != nil {
|
||||
clone.PublisherConfig.Args = make(map[string]interface{})
|
||||
for k, v := range c.PublisherConfig.Args {
|
||||
clone.PublisherConfig.Args[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return &clone
|
||||
}
|
||||
Reference in New Issue
Block a user