From 5cecd74c2d9a3a6dcf86c5792dadad96de6ce5dc Mon Sep 17 00:00:00 2001 From: vinitparekh17 Date: Fri, 4 Oct 2024 11:49:40 +0530 Subject: [PATCH] chore: Add health check to Dice service in Docker Compose --- README.md | 8 +++- config/config.go | 46 ++++++++++++++----- docker-compose.yml | 11 +++-- internal/db/dicedb.go | 4 +- internal/middleware/cors.go | 2 +- .../ratelimiter_integration_test.go | 12 ++--- .../tests/stress/ratelimiter_stress_test.go | 4 +- main.go | 2 +- util/helpers.go | 2 +- 9 files changed, 63 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 3e01521..3f3f250 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,14 @@ $ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/ins ``` Steps to clone and run: -``` +```sh $ git clone https://github.com/dicedb/playground-mono $ cd playground-mono $ go run main.go ``` + +### Using Docker + +```sh +docker compose up -d +``` \ No newline at end of file diff --git a/config/config.go b/config/config.go index 08eaeaa..cc7416d 100644 --- a/config/config.go +++ b/config/config.go @@ -11,12 +11,18 @@ import ( // Config holds the application configuration type Config struct { - DiceDBAddr string - ServerPort string - RequestLimitPerMin int64 // Field for the request limit - RequestWindowSec float64 // Field for the time window in float64 - AllowedOrigins []string // Field for the allowed origins - IsTestEnv bool + DiceDB struct { + Addr string // Field for the Dice address + Username string // Field for the username + Password string // Field for the password + } + Server struct { + Port string // Field for the server port + IsTestEnv bool + RequestLimitPerMin int64 // Field for the request limit + RequestWindowSec float64 // Field for the time window in float64 + AllowedOrigins []string // Field for the allowed origins + } } // LoadConfig loads the application configuration from environment variables or defaults @@ -27,12 +33,28 @@ func LoadConfig() *Config { } return &Config{ - DiceDBAddr: getEnv("DICEDB_ADDR", "localhost:7379"), // Default DiceDB address - ServerPort: getEnv("SERVER_PORT", ":8080"), // Default server port - RequestLimitPerMin: getEnvInt("REQUEST_LIMIT_PER_MIN", 1000), // Default request limit - RequestWindowSec: getEnvFloat64("REQUEST_WINDOW_SEC", 60), // Default request window in float64 - AllowedOrigins: getEnvArray("ALLOWED_ORIGINS", []string{"http://localhost:3000"}), // Default allowed origins - IsTestEnv: getEnvBool("IS_TEST_ENVIRONMENT", false), // Default test env + DiceDB: struct { + Addr string + Username string + Password string + }{ + Addr: getEnv("DICEDB_ADDR", "localhost:7379"), // Default Dice address + Username: getEnv("DICEDB_USERNAME", "dice"), // Default username + Password: getEnv("DICEDB_PASSWORD", ""), // Default password + }, + Server: struct { + Port string + IsTestEnv bool + RequestLimitPerMin int64 + RequestWindowSec float64 + AllowedOrigins []string + }{ + Port: getEnv("SERVER_PORT", ":8080"), + IsTestEnv: getEnvBool("IS_TEST_ENVIRONMENT", false), // Default server port + RequestLimitPerMin: getEnvInt("REQUEST_LIMIT_PER_MIN", 1000), // Default request limit + RequestWindowSec: getEnvFloat64("REQUEST_WINDOW_SEC", 60), // Default request window in float64 + AllowedOrigins: getEnvArray("ALLOWED_ORIGINS", []string{"http://localhost:3000"}), // Default allowed origins + }, } } diff --git a/docker-compose.yml b/docker-compose.yml index 56fb735..a63bb45 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,6 +3,11 @@ services: image: dicedb/dicedb:latest ports: - "7379" + healthcheck: + test: ["CMD", "PING"] + interval: 10s + timeout: 3s + retries: 3 networks: - dice-network @@ -14,9 +19,9 @@ services: depends_on: - dicedb environment: - - DICE_ADDR=dicedb:7379 - - DICE_USERNAME=${DICE_USERNAME} - - DICE_PASSWORD=${DICE_PASSWORD} + - DICEDB_ADDR=dicedb:7379 + - DICEDB_USERNAME=${DICE_USERNAME} + - DICEDB_PASSWORD=${DICE_PASSWORD} networks: - dice-network diff --git a/internal/db/dicedb.go b/internal/db/dicedb.go index 7da8f9f..f2731f9 100644 --- a/internal/db/dicedb.go +++ b/internal/db/dicedb.go @@ -36,7 +36,9 @@ func (db *DiceDB) CloseDiceDB() { func InitDiceClient(configValue *config.Config) (*DiceDB, error) { diceClient := dicedb.NewClient(&dicedb.Options{ - Addr: configValue.DiceDBAddr, + Addr: configValue.DiceDB.Addr, + Username: configValue.DiceDB.Username, + Password: configValue.DiceDB.Password, DialTimeout: 10 * time.Second, MaxRetries: 10, }) diff --git a/internal/middleware/cors.go b/internal/middleware/cors.go index 3e75120..e05c842 100644 --- a/internal/middleware/cors.go +++ b/internal/middleware/cors.go @@ -8,7 +8,7 @@ import ( // Updated enableCors function to return a boolean indicating if OPTIONS was handled func handleCors(w http.ResponseWriter, r *http.Request) bool { configValue := config.LoadConfig() - allAllowedOrigins := configValue.AllowedOrigins + allAllowedOrigins := configValue.Server.AllowedOrigins origin := r.Header.Get("Origin") allowed := false diff --git a/internal/tests/integration/ratelimiter_integration_test.go b/internal/tests/integration/ratelimiter_integration_test.go index 9d82a41..017ba95 100644 --- a/internal/tests/integration/ratelimiter_integration_test.go +++ b/internal/tests/integration/ratelimiter_integration_test.go @@ -12,8 +12,8 @@ import ( func TestRateLimiterWithinLimit(t *testing.T) { configValue := config.LoadConfig() - limit := configValue.RequestLimitPerMin - window := configValue.RequestWindowSec + limit := configValue.Server.RequestLimitPerMin + window := configValue.Server.RequestWindowSec w, r, rateLimiter := util.SetupRateLimiter(limit, window) @@ -25,8 +25,8 @@ func TestRateLimiterWithinLimit(t *testing.T) { func TestRateLimiterExceedsLimit(t *testing.T) { configValue := config.LoadConfig() - limit := configValue.RequestLimitPerMin - window := configValue.RequestWindowSec + limit := configValue.Server.RequestLimitPerMin + window := configValue.Server.RequestWindowSec w, r, rateLimiter := util.SetupRateLimiter(limit, window) @@ -43,8 +43,8 @@ func TestRateLimiterExceedsLimit(t *testing.T) { func TestRateLimitHeadersSet(t *testing.T) { configValue := config.LoadConfig() - limit := configValue.RequestLimitPerMin - window := configValue.RequestWindowSec + limit := configValue.Server.RequestLimitPerMin + window := configValue.Server.RequestWindowSec w, r, rateLimiter := util.SetupRateLimiter(limit, window) diff --git a/internal/tests/stress/ratelimiter_stress_test.go b/internal/tests/stress/ratelimiter_stress_test.go index 75c14f1..79872e6 100644 --- a/internal/tests/stress/ratelimiter_stress_test.go +++ b/internal/tests/stress/ratelimiter_stress_test.go @@ -14,8 +14,8 @@ import ( func TestRateLimiterUnderStress(t *testing.T) { configValue := config.LoadConfig() - limit := configValue.RequestLimitPerMin - window := configValue.RequestWindowSec + limit := configValue.Server.RequestLimitPerMin + window := configValue.Server.RequestWindowSec _, r, rateLimiter := util.SetupRateLimiter(limit, window) diff --git a/main.go b/main.go index 99c98e3..32134a0 100644 --- a/main.go +++ b/main.go @@ -20,7 +20,7 @@ func main() { // Create mux and register routes mux := http.NewServeMux() - httpServer := server.NewHTTPServer(":8080", mux, diceClient, configValue.RequestLimitPerMin, configValue.RequestWindowSec) + httpServer := server.NewHTTPServer(":8080", mux, diceClient, configValue.Server.RequestLimitPerMin, configValue.Server.RequestWindowSec) mux.HandleFunc("/health", httpServer.HealthCheck) mux.HandleFunc("/shell/exec/{cmd}", httpServer.CliHandler) mux.HandleFunc("/search", httpServer.SearchHandler) diff --git a/util/helpers.go b/util/helpers.go index 3ce7f74..0e9854f 100644 --- a/util/helpers.go +++ b/util/helpers.go @@ -55,7 +55,7 @@ func ParseHTTPRequest(r *http.Request) (*cmds.CommandRequest, error) { configValue := config.LoadConfig() // Check if the command is blocklisted - if err := BlockListedCommand(command); err != nil && !configValue.IsTestEnv { + if err := BlockListedCommand(command); err != nil && !configValue.Server.IsTestEnv { return nil, err }