Skip to content

Commit

Permalink
refactor config
Browse files Browse the repository at this point in the history
  • Loading branch information
yarlson committed Sep 24, 2023
1 parent 3554391 commit cb8c0bf
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 59 deletions.
8 changes: 4 additions & 4 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ func main() {
flag.Parse()

// Fetch the API Gateway's configuration using the utility function from the internal package.
err, config := config.GetConfig()
cfg, err := config.GetConfig()
if err != nil {
// Log and exit if there's an error loading the configuration.
log.Fatal("Error loading configuration:", err)
}

// Initialize the router with the provided configuration. This router handles
// requests based on the vhost, endpoint, and backend service configurations.
r := router.NewRouter(config)
r := router.NewRouter(cfg)

// Create a new server and configure it.
srv := &http.Server{
Expand Down Expand Up @@ -69,10 +69,10 @@ func main() {
// Log the start of the server and the port on which it is running.
log.Infof("Server is ready to handle requests at %s", serverAddr)

if config.UseTLS {
if cfg.UseTLS {
srv.TLSConfig = &tls.Config{
GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
for vhostName, vhost := range config.Vhosts {
for vhostName, vhost := range cfg.Vhosts {
if vhost.TLS != nil {
// Using wildcard pattern matching to determine the appropriate certificate.
match, err := filepath.Match(vhostName, info.ServerName)
Expand Down
46 changes: 25 additions & 21 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,35 +81,39 @@ type Config struct {

// GetConfig reads the API Gateway's configuration from a JSON file and returns it.
// It handles any issues with reading or parsing the configuration file.
func GetConfig() (error, *Config) {
func GetConfig() (*Config, error) {
content, err := os.ReadFile("config.json")
if err != nil {
return fmt.Errorf("error reading config.json: %w", err), nil
return nil, fmt.Errorf("error reading config.json: %w", err)
}

var config Config
err = json.Unmarshal(content, &config)
if err != nil {
return fmt.Errorf("error parsing config.json: %w", err), nil
config := new(Config) // Use new() to get a pointer directly, prevent local-to-heap migration.
if err = json.Unmarshal(content, config); err != nil {
return nil, fmt.Errorf("error parsing config.json: %w", err)
}

// Check the TLS configurations for all vhosts
vhostsWithSSL := 0
for _, vhost := range config.Vhosts {
if vhost.TLS != nil {
vhostsWithSSL++
}
}
anyVhostWithSSL, allVhostsWithSSL := check(config)

// If there are any vhosts with TLS configured, then all vhosts should have TLS configured.
if vhostsWithSSL > 0 && vhostsWithSSL != len(config.Vhosts) {
return fmt.Errorf("configuration error: either all vhosts should have TLS configured, or none should"), nil
// If there's any vhost with TLS configured but not all of them have, then it's a config error.
if anyVhostWithSSL && !allVhostsWithSSL {
return nil, fmt.Errorf("configuration error: either all vhosts should have TLS configured, or none should")
}

// If there are vhosts with TLS configured, then the API Gateway should use TLS.
if vhostsWithSSL > 0 {
config.UseTLS = true
}
config.UseTLS = anyVhostWithSSL
return config, nil
}

func check(config *Config) (bool, bool) {
// Check if any vhost has TLS configured
anyVhostWithSSL := false
allVhostsWithSSL := true

return err, &config
for _, vhost := range config.Vhosts {
if vhost.TLS != nil {
anyVhostWithSSL = true
} else {
allVhostsWithSSL = false
}
}
return anyVhostWithSSL, allVhostsWithSSL
}
8 changes: 1 addition & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,9 @@ require (
github.com/go-chi/cors v1.2.1
github.com/gorilla/websocket v1.5.0
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.4
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/stretchr/testify v1.8.4 // indirect
golang.org/x/sys v0.11.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
17 changes: 0 additions & 17 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -8,20 +7,8 @@ github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand All @@ -32,10 +19,6 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
15 changes: 5 additions & 10 deletions logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ import (
// L is a logger instance, utilized throughout the application to output structured logs.
var L *logrus.Logger

// JsonLogger is a middleware that wraps around HTTP handlers to provide logging capabilities.
// For every incoming request, it logs key details like the method, URL, remote address,
// response status, bytes written, duration taken, and a unique request ID. The logs
// are written in a structured JSON format to ensure easy parsing and visualization.
const logMessage = "HTTP request" // Define a constant for the log message

func JsonLogger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Capture the start time to compute the duration of the request.
Expand All @@ -23,26 +21,23 @@ func JsonLogger(next http.Handler) http.Handler {
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
next.ServeHTTP(ww, r)

// Set the log format to JSON and log the request details.
logrus.SetFormatter(&logrus.JSONFormatter{})
logrus.WithFields(logrus.Fields{
// Log the request details.
L.WithFields(logrus.Fields{
"method": r.Method,
"url": r.URL.String(),
"remote_addr": r.RemoteAddr,
"status": ww.Status(),
"bytes": ww.BytesWritten(),
"duration": time.Since(start).Seconds() * 1000,
"request_id": r.Context().Value(middleware.RequestIDKey),
}).Info("HTTP request")
}).Info(logMessage)
})
}

func GetLogger() *logrus.Logger {
return L
}

// init initializes the logger instance L and sets its format to JSON
// so that all logs produced are structured accordingly.
func init() {
L = logrus.New()
L.SetFormatter(&logrus.JSONFormatter{})
Expand Down

0 comments on commit cb8c0bf

Please sign in to comment.