package config import ( "encoding/json" "fmt" "io/ioutil" "os" "github.com/PacktPublishing/Hands-On-Dependency-Injection-in-Go/ch12/acme/internal/logging" ) // DefaultEnvVar is the default environment variable the points to the config file const DefaultEnvVar = "ACME_CONFIG" // Config defines the JSON format for the config file type Config struct { // DSN is the data source name (format: https://github.com/go-sql-driver/mysql/#dsn-data-source-name) DSN string // Address is the IP address and port to bind this rest to Address string // BasePrice is the price of registration BasePrice float64 // ExchangeRateBaseURL is the server and protocol part of the URL from which to load the exchange rate ExchangeRateBaseURL string // ExchangeRateAPIKey is the API for the exchange rate API ExchangeRateAPIKey string // environmental dependencies logger logging.Logger } // Logger returns a reference to the singleton logger func (c *Config) Logger() logging.Logger { if c.logger == nil { c.logger = &logging.LoggerStdOut{} } return c.logger } // RegistrationBasePrice returns the base price for registrations func (c *Config) RegistrationBasePrice() float64 { return c.BasePrice } // DataDSN returns the DSN func (c *Config) DataDSN() string { return c.DSN } // ExchangeBaseURL returns the Base URL from which we can load exchange rates func (c *Config) ExchangeBaseURL() string { return c.ExchangeRateBaseURL } // ExchangeAPIKey returns the DSN func (c *Config) ExchangeAPIKey() string { return c.ExchangeRateAPIKey } // BindAddress returns the host and port this service should bind to func (c *Config) BindAddress() string { return c.Address } // Load returns the config loaded from environment func Load() (*Config, error) { filename, found := os.LookupEnv(DefaultEnvVar) if !found { err := fmt.Errorf("failed to locate file specified by %s", DefaultEnvVar) fmt.Fprintf(os.Stderr, err.Error()) return nil, err } cfg, err := load(filename) if err != nil { fmt.Fprintf(os.Stderr, "failed to load config with err %s", err) return nil, err } return cfg, nil } func load(filename string) (*Config, error) { out := &Config{} bytes, err := ioutil.ReadFile(filename) if err != nil { fmt.Fprintf(os.Stderr, "failed to read config file. err: %s", err) return nil, err } err = json.Unmarshal(bytes, out) if err != nil { fmt.Fprintf(os.Stderr, "failed to parse config file. err : %s", err) return nil, err } return out, nil }