diff --git a/cmd/productapp/command/serve.go b/cmd/productapp/command/serve.go index 6f60c82f..9bcb2775 100644 --- a/cmd/productapp/command/serve.go +++ b/cmd/productapp/command/serve.go @@ -1,13 +1,16 @@ package command import ( - "fmt" + "context" "log" - "net/http" "os" "os/signal" + "strconv" "syscall" + "time" + "git.gocasts.ir/ebhomengo/niki/productapp" + "git.gocasts.ir/ebhomengo/niki/repository/mysql" "github.com/spf13/cobra" ) @@ -25,27 +28,53 @@ var serveCmd = &cobra.Command{ func serve() { log.Println("Product Service Starting...") - // TODO: Initialize database connection - // TODO: Initialize service dependencies - // TODO: Setup HTTP server with routes + cfg := productapp.Config{ + HTTPServer: productapp.HTTPServerConfig{ + Port: getEnvInt("HTTP_PORT", 8080), + }, + Database: mysql.Config{ + Username: getEnv("DB_USERNAME", "root"), + Password: getEnv("DB_PASSWORD", ""), + Port: getEnvInt("DB_PORT", 3306), + Host: getEnv("DB_HOST", "localhost"), + DBName: getEnv("DB_NAME", "niki_db"), + }, + } + + if p, err := strconv.Atoi(port); err == nil && p > 0 { + cfg.HTTPServer.Port = p + } + + app := productapp.Setup(cfg) - // Setup graceful shutdown go func() { - sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) - <-sigCh - log.Println("Shutting down Product Service gracefully...") - os.Exit(0) + app.Start() }() - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "Product Service OK!") - }) + quit := make(chan os.Signal, 1) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + <-quit - log.Printf("Product Service listening on port %s", port) - if err := http.ListenAndServe(":"+port, nil); err != nil { - log.Fatalf("Failed to start server: %v", err) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + if err := app.Stop(ctx); err != nil { + log.Fatalf("Server shutdown error: %v", err) } + + log.Println("Product Service stopped.") +} + +func getEnvInt(key string, defaultValue int) int { + val := os.Getenv(key) + if val == "" { + return defaultValue + } + n, err := strconv.Atoi(val) + if err != nil { + return defaultValue + } + return n } func init() { diff --git a/productapp/app.go b/productapp/app.go index fc658cbf..53791556 100644 --- a/productapp/app.go +++ b/productapp/app.go @@ -1,8 +1,64 @@ package productapp -import "net/http" +import ( + "context" + "fmt" + "log" + + httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server" + producthttp "git.gocasts.ir/ebhomengo/niki/productapp/delivery/http" + productdb "git.gocasts.ir/ebhomengo/niki/productapp/repository/database" + "git.gocasts.ir/ebhomengo/niki/repository/mysql" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" +) + +type HTTPServerConfig struct { + Port int +} + +type Config struct { + HTTPServer HTTPServerConfig + Database mysql.Config +} type Application struct { Config Config - HTTPServer *http.Server + HTTPServer *producthttp.Server + DB *productdb.DB + Echo *echo.Echo +} + +func Setup(cfg Config) *Application { + db := mysql.New(cfg.Database) + productDB := productdb.New(db) + + e := echo.New() + e.Use(middleware.Recover()) + + hsrv := &httpserver.Server{ + Router: e, + } + + srv := producthttp.NewServer(hsrv) + srv.RegisterRoutes() + + return &Application{ + Config: cfg, + HTTPServer: srv, + DB: productDB, + Echo: e, + } +} + +func (app *Application) Start() { + address := fmt.Sprintf(":%d", app.Config.HTTPServer.Port) + log.Printf("Product Service listening on %s", address) + if err := app.Echo.Start(address); err != nil { + log.Fatalf("Failed to start server: %v", err) + } +} + +func (app *Application) Stop(ctx context.Context) error { + return app.Echo.Shutdown(ctx) } diff --git a/productapp/config.go b/productapp/config.go index 64c7837d..3b63d7be 100644 --- a/productapp/config.go +++ b/productapp/config.go @@ -1,4 +1 @@ package productapp - -type Config struct { -} diff --git a/productapp/delivery/http/server.go b/productapp/delivery/http/server.go index c5adfb44..2b20c191 100644 --- a/productapp/delivery/http/server.go +++ b/productapp/delivery/http/server.go @@ -20,4 +20,7 @@ func (s *Server) Serve() { func (s *Server) Stop() {} -func (s *Server) RegisterRoutes() {} +func (s *Server) RegisterRoutes() { + r := s.HTTPServer.Router + r.GET("health-check", s.Handler.HealthCheck) +}