Files
2025-04-10 15:40:22 +02:00

97 lines
3.6 KiB
Go

// Package server initializes and runs the application server.
// It sets up configurations, initializes the database, services, and controllers,
// loads HTML templates, and starts the HTTP server.
package server
import (
"context"
"net/http"
"path/filepath"
"time"
"GoMembership/internal/config"
"GoMembership/internal/controllers"
"GoMembership/internal/middlewares"
"GoMembership/internal/repositories"
"GoMembership/internal/validation"
"GoMembership/internal/routes"
"GoMembership/internal/services"
"GoMembership/pkg/logger"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
var shutdownChannel = make(chan struct{})
var srv *http.Server
// Run initializes the server configuration, sets up services and controllers, and starts the HTTP server.
func Run(db *gorm.DB) {
emailService := services.NewEmailService(config.SMTP.Host, config.SMTP.Port, config.SMTP.User, config.SMTP.Password)
var consentRepo repositories.ConsentRepositoryInterface = &repositories.ConsentRepository{}
consentService := &services.ConsentService{Repo: consentRepo}
var bankAccountRepo repositories.BankAccountRepositoryInterface = &repositories.BankAccountRepository{}
bankAccountService := &services.BankAccountService{Repo: bankAccountRepo}
var membershipRepo repositories.MembershipRepositoryInterface = &repositories.MembershipRepository{}
var subscriptionRepo repositories.SubscriptionsRepositoryInterface = &repositories.SubscriptionsRepository{}
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
licenceService := &services.LicenceService{Repo: licenceRepo}
userService := &services.UserService{DB: db, Licences: licenceRepo}
userController := &controllers.UserController{Service: userService, EmailService: emailService, ConsentService: consentService, LicenceService: licenceService, BankAccountService: bankAccountService, MembershipService: membershipService}
membershipController := &controllers.MembershipController{Service: membershipService, UserService: userService}
licenceController := &controllers.LicenceController{Service: licenceService}
contactController := &controllers.ContactController{EmailService: emailService}
carService := &services.CarService{DB: db}
carController := &controllers.CarController{S: carService, UserService: userService}
router := gin.Default()
// gin.SetMode(gin.ReleaseMode)
router.Static(config.Templates.StaticPath, "./style")
// Load HTML templates
router.LoadHTMLGlob(filepath.Join(config.Templates.HTMLPath, "*"))
router.Use(gin.Logger())
router.Use(middlewares.CORSMiddleware())
router.Use(middlewares.CSPMiddleware())
router.Use(middlewares.SecurityHeadersMiddleware())
limiter := middlewares.NewIPRateLimiter(config.Security.Ratelimits.Limit, config.Security.Ratelimits.Burst)
router.Use(middlewares.RateLimitMiddleware(limiter))
routes.RegisterRoutes(router, userController, membershipController, contactController, licenceController, carController)
validation.SetupValidators(db)
logger.Info.Println("Starting server on :8080")
srv = &http.Server{
Addr: ":8080",
Handler: router,
}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.Error.Fatalf("could not start server: %v", err)
}
}()
// Wait for the shutdown signal
<-shutdownChannel
}
func Shutdown(ctx context.Context) error {
if srv == nil {
return nil
}
// Graceful shutdown with a timeout
shutdownCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
// Attempt to shutdown the server
return srv.Shutdown(shutdownCtx)
}