Init Eslogad
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"eslogad-be/config"
|
||||
"eslogad-be/internal/client"
|
||||
"eslogad-be/internal/handler"
|
||||
"eslogad-be/internal/middleware"
|
||||
"eslogad-be/internal/processor"
|
||||
"eslogad-be/internal/repository"
|
||||
"eslogad-be/internal/router"
|
||||
"eslogad-be/internal/service"
|
||||
"eslogad-be/internal/validator"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
server *http.Server
|
||||
db *gorm.DB
|
||||
router *router.Router
|
||||
shutdown chan os.Signal
|
||||
}
|
||||
|
||||
func NewApp(db *gorm.DB) *App {
|
||||
return &App{
|
||||
db: db,
|
||||
shutdown: make(chan os.Signal, 1),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) Initialize(cfg *config.Config) error {
|
||||
repos := a.initRepositories()
|
||||
processors := a.initProcessors(cfg, repos)
|
||||
services := a.initServices(processors, repos, cfg)
|
||||
middlewares := a.initMiddleware(services)
|
||||
healthHandler := handler.NewHealthHandler()
|
||||
fileHandler := handler.NewFileHandler(services.fileService)
|
||||
|
||||
a.router = router.NewRouter(
|
||||
cfg,
|
||||
handler.NewAuthHandler(services.authService),
|
||||
middlewares.authMiddleware,
|
||||
healthHandler,
|
||||
handler.NewUserHandler(services.userService, &validator.UserValidatorImpl{}),
|
||||
fileHandler,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) Start(port string) error {
|
||||
engine := a.router.Init()
|
||||
|
||||
a.server = &http.Server{
|
||||
Addr: ":" + port,
|
||||
Handler: engine,
|
||||
ReadTimeout: 15 * time.Second,
|
||||
WriteTimeout: 15 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
}
|
||||
|
||||
signal.Notify(a.shutdown, os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
log.Printf("Server starting on port %s", port)
|
||||
if err := a.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Fatalf("Failed to start server: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
<-a.shutdown
|
||||
log.Println("Shutting down server...")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := a.server.Shutdown(ctx); err != nil {
|
||||
log.Printf("Server forced to shutdown: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println("Server exited gracefully")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) Shutdown() {
|
||||
close(a.shutdown)
|
||||
}
|
||||
|
||||
type repositories struct {
|
||||
userRepo *repository.UserRepositoryImpl
|
||||
userProfileRepo *repository.UserProfileRepository
|
||||
titleRepo *repository.TitleRepository
|
||||
}
|
||||
|
||||
func (a *App) initRepositories() *repositories {
|
||||
return &repositories{
|
||||
userRepo: repository.NewUserRepository(a.db),
|
||||
userProfileRepo: repository.NewUserProfileRepository(a.db),
|
||||
titleRepo: repository.NewTitleRepository(a.db),
|
||||
}
|
||||
}
|
||||
|
||||
type processors struct {
|
||||
userProcessor *processor.UserProcessorImpl
|
||||
}
|
||||
|
||||
func (a *App) initProcessors(cfg *config.Config, repos *repositories) *processors {
|
||||
return &processors{
|
||||
userProcessor: processor.NewUserProcessor(repos.userRepo, repos.userProfileRepo),
|
||||
}
|
||||
}
|
||||
|
||||
type services struct {
|
||||
userService *service.UserServiceImpl
|
||||
authService *service.AuthServiceImpl
|
||||
fileService *service.FileServiceImpl
|
||||
}
|
||||
|
||||
func (a *App) initServices(processors *processors, repos *repositories, cfg *config.Config) *services {
|
||||
authConfig := cfg.Auth()
|
||||
jwtSecret := authConfig.AccessTokenSecret()
|
||||
authService := service.NewAuthService(processors.userProcessor, jwtSecret)
|
||||
|
||||
userSvc := service.NewUserService(processors.userProcessor, repos.titleRepo)
|
||||
|
||||
// File storage client and service
|
||||
fileCfg := cfg.S3Config
|
||||
s3Client := client.NewFileClient(fileCfg)
|
||||
fileSvc := service.NewFileService(s3Client, processors.userProcessor, "profile", "documents")
|
||||
|
||||
return &services{
|
||||
userService: userSvc,
|
||||
authService: authService,
|
||||
fileService: fileSvc,
|
||||
}
|
||||
}
|
||||
|
||||
type middlewares struct {
|
||||
authMiddleware *middleware.AuthMiddleware
|
||||
}
|
||||
|
||||
func (a *App) initMiddleware(services *services) *middlewares {
|
||||
return &middlewares{
|
||||
authMiddleware: middleware.NewAuthMiddleware(services.authService),
|
||||
}
|
||||
}
|
||||
|
||||
type validators struct {
|
||||
userValidator *validator.UserValidatorImpl
|
||||
}
|
||||
|
||||
func (a *App) initValidators() *validators {
|
||||
return &validators{
|
||||
userValidator: validator.NewUserValidator(),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
*gin.Engine
|
||||
}
|
||||
|
||||
func generateServerID() string {
|
||||
return uuid.New().String()
|
||||
}
|
||||
|
||||
func (s Server) Listen(address string) error {
|
||||
fmt.Printf("API server listening at: %s\n\n", address)
|
||||
return s.Run(address)
|
||||
}
|
||||
|
||||
func (s Server) StartScheduler() {
|
||||
fmt.Printf("Scheduler started\n")
|
||||
}
|
||||
Reference in New Issue
Block a user