Skip to content

Commit

Permalink
👌 Apply review feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
sameersubudhi committed Jan 23, 2024
1 parent 1440f8c commit 3c94036
Show file tree
Hide file tree
Showing 4 changed files with 425 additions and 38 deletions.
2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"github.com/spf13/viper"
)

var apiServer *api.HTTPServerWrapper
var apiServer *api.HTTPServer

func main() {
ctx, cancel := context.WithCancel(context.Background())
Expand Down
14 changes: 7 additions & 7 deletions pkg/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
"github.com/gin-gonic/gin"
)

// HTTPServerWrapper embeds the http.Server along with the various other properties.
type HTTPServerWrapper struct {
// HTTPServer embeds the http.Server along with the various other properties.
type HTTPServer struct {
server *http.Server
ctx context.Context
logger log.Logger
Expand All @@ -25,7 +25,7 @@ type HTTPServerWrapper struct {
}

// Start starts the HTTP API server.
func (w *HTTPServerWrapper) Start() {
func (w *HTTPServer) Start() {
defer w.wg.Done()

w.logger.Infof("Starting the HTTP server on %s.", w.server.Addr)
Expand All @@ -36,7 +36,7 @@ func (w *HTTPServerWrapper) Start() {
}

// Stop gracefully shuts down the HTTP API server.
func (w *HTTPServerWrapper) Stop() error {
func (w *HTTPServer) Stop() error {
err := w.server.Shutdown(w.ctx)
if err == nil {
w.logger.Infof("Successfully stopped the HTTP server.")
Expand All @@ -56,7 +56,7 @@ func getGinModeFromSysLogLevel(sysLogLevel string) string {
}

// NewHTTPServer creates a router instance and sets up the necessary routes/handlers.
func NewHTTPServer(ctx context.Context, logger log.Logger, wg *sync.WaitGroup, config *config.Config, errorChan chan error) *HTTPServerWrapper {
func NewHTTPServer(ctx context.Context, logger log.Logger, wg *sync.WaitGroup, config *config.Config, errorChan chan error) *HTTPServer {
gin.SetMode(getGinModeFromSysLogLevel(config.System.LogLevel))

router := gin.Default()
Expand All @@ -78,11 +78,11 @@ func NewHTTPServer(ctx context.Context, logger log.Logger, wg *sync.WaitGroup, c
port := config.Api.Server.Port
addr := fmt.Sprintf("%s:%d", host, port)

server := &HTTPServerWrapper{
server := &HTTPServer{
&http.Server{
Addr: addr,
Handler: router,
ReadHeaderTimeout: 10 * time.Second, // TODO: Check appropriate value
ReadHeaderTimeout: 10 * time.Second,
},
ctx,
logger,
Expand Down
66 changes: 36 additions & 30 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,84 +25,90 @@ type System struct {
}

type Api struct {
Server struct {
Host string `mapstructure:"host"`
Port uint `mapstructure:"port"`
} `mapstructure:"server"`
Server *Server `mapstructure:"server"`
BasePath string `mapstructure:"base_path"`
RegisterVersions []string `mapstructure:"register_versions"`
}

type Server struct {
Host string `mapstructure:"host"`
Port uint `mapstructure:"port"`
}

type FaultDetector struct {
}

func formatError(validationErrors error) error {
if validationErrors == nil {
return nil
}

// Beautify the error message
validationErrorSplits := strings.Split(validationErrors.Error(), ";")
formattedErrorStr := strings.Join(validationErrorSplits, "\n\t-")

return fmt.Errorf("fix the following %d config validation fail(s) to continue:\n\t- %s", len(validationErrorSplits), formattedErrorStr)
}

func (c *Config) Validate() error {
var validationErrors error

sysConfigError := validateSystemConfig(c)
apiConfigError := validateApiConfig(c)
fdConfigError := validateFaultDetectorConfig(c)
sysConfigError := c.System.Validate()
apiConfigError := c.Api.Validate()
fdConfigError := c.FaultDetector.Validate()

validationErrors = multierr.Combine(sysConfigError, apiConfigError, fdConfigError)

if validationErrors != nil {
// Beautify the error message
validationErrorSplits := strings.Split(validationErrors.Error(), ";")
formattedErrorStr := strings.Join(validationErrorSplits, "\n\t- ")

return fmt.Errorf("fix the following %d config validation fail(s) to continue:\n\t - %s", len(validationErrorSplits), formattedErrorStr)
}

return validationErrors
return formatError(validationErrors)
}

func validateSystemConfig(c *Config) error {
func (c *System) Validate() error {
var validationErrors error

allowedLogLevels := []string{log.LevelTrace, log.LevelDebug, log.LevelInfo, log.LevelWarn, log.LevelError, log.LevelFatal}
if !utils.Contains(allowedLogLevels, c.System.LogLevel) {
validationErrors = multierr.Append(validationErrors, fmt.Errorf("system.log_level expected one of %s, received: '%s'", allowedLogLevels, c.System.LogLevel))
if !utils.Contains(allowedLogLevels, c.LogLevel) {
validationErrors = multierr.Append(validationErrors, fmt.Errorf("system.log_level expected one of %s, received: '%s'", allowedLogLevels, c.LogLevel))
}

return validationErrors
}

func validateApiConfig(c *Config) error {
func (c *Api) Validate() error {
var validationErrors error

validationErrors = multierr.Append(validationErrors, validateApiServerConfig(c))
validationErrors = multierr.Append(validationErrors, c.Server.Validate())

basePath := c.Api.BasePath
basePath := c.BasePath
basePathRegex := `^/?api$`
basePathMatched, _ := regexp.MatchString(basePathRegex, basePath)
if !basePathMatched {
validationErrors = multierr.Append(validationErrors, fmt.Errorf("api.base_path expected to match regex: `%v`, received: '%s'", basePathRegex, basePath))
validationErrors = multierr.Append(validationErrors, fmt.Errorf("api.base_path expected to match regex: `%s`, received: '%s'", basePathRegex, basePath))
}

registerVersions := c.Api.RegisterVersions
registerVersions := c.RegisterVersions
registerVersionRegex := `^v[1-9]\d*$`
registerVersionRegexCompiled, _ := regexp.Compile(registerVersionRegex)
for _, version := range registerVersions {
registerVersionMatched := registerVersionRegexCompiled.MatchString(version)
if !registerVersionMatched {
validationErrors = multierr.Append(validationErrors, fmt.Errorf("api.register_versions entry expected to match regex: `%v`, received: '%s'", registerVersionRegex, version))
validationErrors = multierr.Append(validationErrors, fmt.Errorf("api.register_versions entry expected to match regex: `%s`, received: '%s'", registerVersionRegex, version))
}
}

return validationErrors
}

func validateApiServerConfig(c *Config) error {
func (c *Server) Validate() error {
var validationErrors error

host := c.Api.Server.Host
host := c.Host
hostRegex := `^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`
hostMatched, _ := regexp.MatchString(hostRegex, host)
if !hostMatched {
validationErrors = multierr.Append(validationErrors, fmt.Errorf("api.server.host expected to match regex: `%v`, received: '%s'", hostRegex, host))
validationErrors = multierr.Append(validationErrors, fmt.Errorf("api.server.host expected to match regex: `%s`, received: '%s'", hostRegex, host))
}

port := c.Api.Server.Port
port := c.Port
minPortNum := uint(0)
maxPortNum := uint(math.Pow(2, 16) - 1)
if port < minPortNum || port > maxPortNum {
Expand All @@ -112,6 +118,6 @@ func validateApiServerConfig(c *Config) error {
return validationErrors
}

func validateFaultDetectorConfig(c *Config) error {
func (c *FaultDetector) Validate() error {
return nil
}
Loading

0 comments on commit 3c94036

Please sign in to comment.