package servers import ( "dy-admin/internal/pcmserver/config" "dy-admin/pkg/log" "dy-admin/pkg/middleware" "dy-admin/pkg/rescode" "dy-admin/pkg/version" "errors" "github.com/gin-contrib/pprof" "github.com/gin-gonic/gin" ginprometheus "github.com/zsais/go-gin-prometheus" "golang.org/x/sync/errgroup" "net" "net/http" "strconv" ) type GenericAPIServer struct { middlewares []string InsecureServingInfo *InsecureServingInfo *gin.Engine healthz bool enableMetrics bool enableProfiling bool insecureServer *http.Server } func NewGenericApiServer(cfg *config.Config) (*GenericAPIServer, error) { gin.SetMode(cfg.GenericServerRunOptions.Mode) s := &GenericAPIServer{ middlewares: cfg.GenericServerRunOptions.Middlewares, InsecureServingInfo: &InsecureServingInfo{Address: net.JoinHostPort(cfg.InsecureServing.BindAddress, strconv.Itoa(cfg.InsecureServing.BindPort))}, Engine: gin.New(), healthz: cfg.GenericServerRunOptions.Healthz, enableMetrics: cfg.FeatureOptions.EnableMetrics, enableProfiling: cfg.FeatureOptions.EnableProfiling, } initGenericAPIServer(s) return s, nil } func initGenericAPIServer(s *GenericAPIServer) { // do some setup // s.GET(path, ginSwagger.WrapHandler(swaggerFiles.Handler)) s.Setup() s.InstallMiddlewares() s.InstallAPIs() } func (s *GenericAPIServer) Setup() { gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) { log.Infof("%-6s %-s --> %s (%d handlers)", httpMethod, absolutePath, handlerName, nuHandlers) } } func (s *GenericAPIServer) InstallMiddlewares() { // necessary middlewares s.Use(middleware.RequestID()) s.Use(middleware.Context()) // install custom middlewares for _, m := range s.middlewares { mw, ok := middleware.Middlewares[m] if !ok { log.Warnf("can not find middleware: %s", m) continue } log.Infof("install middleware: %s", m) s.Use(mw) } } func (s *GenericAPIServer) InstallAPIs() { // install healthz handler if s.healthz { s.GET("/healthz", func(c *gin.Context) { rescode.WriteSuccessResponse(c, map[string]string{"status": "ok"}) }) } // install metric handler if s.enableMetrics { prometheus := ginprometheus.NewPrometheus("gin") prometheus.Use(s.Engine) } // install pprof handler if s.enableProfiling { pprof.Register(s.Engine) } s.GET("/version", func(c *gin.Context) { rescode.WriteSuccessResponse(c, version.Get()) }) } func (s *GenericAPIServer) Run() error { s.insecureServer = &http.Server{ Addr: s.InsecureServingInfo.Address, Handler: s, } var eg errgroup.Group eg.Go(func() error { log.Infof("Start to listening the incoming requests on http address: %s", s.InsecureServingInfo.Address) if err := s.insecureServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { log.Fatal(err.Error()) return err } log.Infof("Server on %s stopped", s.InsecureServingInfo.Address) return nil }) if err := eg.Wait(); err != nil { log.Fatal(err.Error()) } return nil } type InsecureServingInfo struct { Address string }