generic_api_server.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package servers
  2. import (
  3. "dy-admin/internal/pcmserver/config"
  4. "dy-admin/pkg/log"
  5. "dy-admin/pkg/middleware"
  6. "dy-admin/pkg/rescode"
  7. "dy-admin/pkg/version"
  8. "errors"
  9. "github.com/gin-contrib/pprof"
  10. "github.com/gin-gonic/gin"
  11. ginprometheus "github.com/zsais/go-gin-prometheus"
  12. "golang.org/x/sync/errgroup"
  13. "net"
  14. "net/http"
  15. "strconv"
  16. )
  17. type GenericAPIServer struct {
  18. middlewares []string
  19. InsecureServingInfo *InsecureServingInfo
  20. *gin.Engine
  21. healthz bool
  22. enableMetrics bool
  23. enableProfiling bool
  24. insecureServer *http.Server
  25. }
  26. func NewGenericApiServer(cfg *config.Config) (*GenericAPIServer, error) {
  27. gin.SetMode(cfg.GenericServerRunOptions.Mode)
  28. s := &GenericAPIServer{
  29. middlewares: cfg.GenericServerRunOptions.Middlewares,
  30. InsecureServingInfo: &InsecureServingInfo{Address: net.JoinHostPort(cfg.InsecureServing.BindAddress, strconv.Itoa(cfg.InsecureServing.BindPort))},
  31. Engine: gin.New(),
  32. healthz: cfg.GenericServerRunOptions.Healthz,
  33. enableMetrics: cfg.FeatureOptions.EnableMetrics,
  34. enableProfiling: cfg.FeatureOptions.EnableProfiling,
  35. }
  36. initGenericAPIServer(s)
  37. return s, nil
  38. }
  39. func initGenericAPIServer(s *GenericAPIServer) {
  40. // do some setup
  41. // s.GET(path, ginSwagger.WrapHandler(swaggerFiles.Handler))
  42. s.Setup()
  43. s.InstallMiddlewares()
  44. s.InstallAPIs()
  45. }
  46. func (s *GenericAPIServer) Setup() {
  47. gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
  48. log.Infof("%-6s %-s --> %s (%d handlers)", httpMethod, absolutePath, handlerName, nuHandlers)
  49. }
  50. }
  51. func (s *GenericAPIServer) InstallMiddlewares() {
  52. // necessary middlewares
  53. s.Use(middleware.RequestID())
  54. s.Use(middleware.Context())
  55. // install custom middlewares
  56. for _, m := range s.middlewares {
  57. mw, ok := middleware.Middlewares[m]
  58. if !ok {
  59. log.Warnf("can not find middleware: %s", m)
  60. continue
  61. }
  62. log.Infof("install middleware: %s", m)
  63. s.Use(mw)
  64. }
  65. }
  66. func (s *GenericAPIServer) InstallAPIs() {
  67. // install healthz handler
  68. if s.healthz {
  69. s.GET("/healthz", func(c *gin.Context) {
  70. rescode.WriteSuccessResponse(c, map[string]string{"status": "ok"})
  71. })
  72. }
  73. // install metric handler
  74. if s.enableMetrics {
  75. prometheus := ginprometheus.NewPrometheus("gin")
  76. prometheus.Use(s.Engine)
  77. }
  78. // install pprof handler
  79. if s.enableProfiling {
  80. pprof.Register(s.Engine)
  81. }
  82. s.GET("/version", func(c *gin.Context) {
  83. rescode.WriteSuccessResponse(c, version.Get())
  84. })
  85. }
  86. func (s *GenericAPIServer) Run() error {
  87. s.insecureServer = &http.Server{
  88. Addr: s.InsecureServingInfo.Address,
  89. Handler: s,
  90. }
  91. var eg errgroup.Group
  92. eg.Go(func() error {
  93. log.Infof("Start to listening the incoming requests on http address: %s", s.InsecureServingInfo.Address)
  94. if err := s.insecureServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
  95. log.Fatal(err.Error())
  96. return err
  97. }
  98. log.Infof("Server on %s stopped", s.InsecureServingInfo.Address)
  99. return nil
  100. })
  101. if err := eg.Wait(); err != nil {
  102. log.Fatal(err.Error())
  103. }
  104. return nil
  105. }
  106. type InsecureServingInfo struct {
  107. Address string
  108. }