server.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package app
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "os/signal"
  8. "strconv"
  9. "syscall"
  10. "time"
  11. "git.linuxforward.com/byop/byop-engine/auth"
  12. "git.linuxforward.com/byop/byop-engine/cloud"
  13. "git.linuxforward.com/byop/byop-engine/config"
  14. "git.linuxforward.com/byop/byop-engine/dbmanager"
  15. "git.linuxforward.com/byop/byop-engine/handlers"
  16. mw "git.linuxforward.com/byop/byop-engine/middleware"
  17. "github.com/gin-gonic/gin"
  18. "github.com/pkg/errors"
  19. "github.com/sirupsen/logrus"
  20. )
  21. type App struct {
  22. entry *logrus.Entry
  23. cnf *config.Config
  24. ctx context.Context
  25. cancelFunc context.CancelFunc
  26. rtr *gin.Engine
  27. // Database
  28. dbManager dbmanager.DbManager[dbmanager.Entity]
  29. dbFactory *dbmanager.DbManagerFactory
  30. // Services
  31. authService auth.Service
  32. tokenStore auth.TokenStore
  33. // Common Handlers
  34. authHandler *handlers.AuthHandler
  35. clientHandler *handlers.ClientHandler
  36. // Resource Handlers
  37. providerHandler *handlers.ProviderHandler
  38. deploymentHandler *handlers.DeploymentHandler
  39. templateHandler *handlers.TemplateHandler
  40. ticketHandler *handlers.TicketHandler
  41. monitoringHandler *handlers.MonitoringHandler
  42. }
  43. func NewApp(cnf *config.Config) (*App, error) {
  44. ctx, cancelFunc := context.WithCancel(context.Background())
  45. app := &App{
  46. entry: logrus.WithField("component", "app"),
  47. cnf: cnf,
  48. ctx: ctx,
  49. cancelFunc: cancelFunc,
  50. }
  51. // Initialize router first
  52. if cnf.Debug {
  53. gin.SetMode(gin.DebugMode)
  54. } else {
  55. // Set gin to release mode for production
  56. // This will disable debug logs and enable performance optimizations
  57. gin.SetMode(gin.ReleaseMode)
  58. }
  59. app.rtr = gin.New()
  60. app.rtr.Use(gin.Recovery())
  61. app.rtr.Use(mw.Logger)
  62. // Initialize database connection
  63. if err := app.initDatabase(); err != nil {
  64. return nil, errors.Wrap(err, "initialize database")
  65. }
  66. // Initialize services and handlers
  67. if err := app.initServices(); err != nil {
  68. return nil, errors.Wrap(err, "initialize services")
  69. }
  70. if err := app.initHandlers(); err != nil {
  71. return nil, errors.Wrap(err, "initialize handlers")
  72. }
  73. // Set up routes after all handlers are initialized
  74. app.setupRoutes()
  75. return app, nil
  76. }
  77. func (a *App) Run() error {
  78. srv := &http.Server{
  79. Addr: fmt.Sprintf(":%s", strconv.Itoa(a.cnf.Server.Port)),
  80. Handler: a.rtr,
  81. }
  82. go func() {
  83. a.entry.WithField("address", srv.Addr).Info("Starting server...")
  84. // Handle TLS if configured
  85. if a.cnf.Server.Tls.Enabled {
  86. a.entry.Info("Starting server with TLS...")
  87. err := srv.ListenAndServeTLS(a.cnf.Server.Tls.CertFile, a.cnf.Server.Tls.KeyFile)
  88. if err != nil && err != http.ErrServerClosed {
  89. a.entry.WithError(err).Fatal("Failed to start server")
  90. }
  91. } else {
  92. err := srv.ListenAndServe()
  93. if err != nil && err != http.ErrServerClosed {
  94. a.entry.WithError(err).Fatal("Failed to start server")
  95. }
  96. }
  97. a.entry.Info("Server stopped")
  98. }()
  99. quit := make(chan os.Signal, 1)
  100. signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
  101. <-quit
  102. a.entry.Info("Stopping server...")
  103. ctxTimeout, cancelFunc := context.WithTimeout(context.Background(), 30*time.Second)
  104. defer cancelFunc()
  105. err := srv.Shutdown(ctxTimeout)
  106. if err != nil {
  107. return fmt.Errorf("shutdown server: %w", err)
  108. }
  109. a.entry.Info("Server stopped successfully")
  110. return nil
  111. }
  112. func (a *App) initServices() error {
  113. // Initialize token store
  114. a.tokenStore = auth.NewMemoryTokenStore(time.Duration(a.cnf.Auth.CleanupInterval))
  115. // Initialize authentication service
  116. a.authService = auth.NewJWTService(
  117. []byte(a.cnf.Auth.PrivateKey),
  118. time.Duration(a.cnf.Auth.TokenDuration),
  119. a.tokenStore,
  120. )
  121. // Initialize providers
  122. if err := a.loadProviders(); err != nil {
  123. return errors.Wrap(err, "load providers")
  124. }
  125. a.entry.Info("Services initialized successfully")
  126. return nil
  127. }
  128. func (a *App) initHandlers() error {
  129. // Initialize authentication handler
  130. a.authHandler = handlers.NewAuthHandler(a.authService)
  131. // Initialize resource handlers
  132. a.providerHandler = handlers.NewProviderHandler()
  133. // Create managers for each entity type
  134. clientDbManager, err := a.dbFactory.CreateClientManager()
  135. if err != nil {
  136. return fmt.Errorf("create client db manager: %w", err)
  137. }
  138. if err := clientDbManager.Connect(); err != nil {
  139. return fmt.Errorf("connect to client database: %w", err)
  140. }
  141. a.clientHandler = handlers.NewClientHandler(clientDbManager)
  142. // Initialize other handlers...
  143. a.entry.Info("Handlers initialized successfully")
  144. return nil
  145. }
  146. func (a *App) loadProviders() error {
  147. for name, config := range a.cnf.Providers {
  148. provider, ok := cloud.GetProvider(name)
  149. if !ok {
  150. return fmt.Errorf("provider %s not found", name)
  151. }
  152. err := provider.Initialize(config)
  153. if err != nil {
  154. return fmt.Errorf("initialize provider %s: %w", name, err)
  155. }
  156. a.entry.WithField("provider", name).Info("Provider initialized")
  157. }
  158. a.entry.Info("All providers loaded successfully")
  159. return nil
  160. }
  161. func (a *App) setupRoutes() {
  162. // API version group
  163. v1 := a.rtr.Group("/api/v1")
  164. // Auth routes - no middleware required
  165. a.authHandler.RegisterRoutes(v1)
  166. // Protected routes - require authentication
  167. protected := v1.Group("/")
  168. protected.Use(mw.Auth(a.authService)) // Auth middleware with service dependency
  169. // Register resource routes
  170. providers := protected.Group("/providers")
  171. a.providerHandler.RegisterRoutes(providers)
  172. clients := protected.Group("/clients")
  173. a.clientHandler.RegisterRoutes(clients)
  174. // Register other resource routes...
  175. a.entry.Info("Routes configured successfully")
  176. }
  177. func (a *App) initDatabase() error {
  178. a.dbFactory = dbmanager.NewDbManagerFactory(a.cnf.Database.Type)
  179. a.entry.Info("Database factory initialized successfully")
  180. return nil
  181. }