Files
oneterm/backend/pkg/server/router/router.go
2024-03-28 19:38:48 +08:00

122 lines
2.9 KiB
Go

package router
import (
"context"
"encoding/gob"
"fmt"
"net/http"
"os"
"time"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/viper"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"github.com/veops/oneterm/docs"
"github.com/veops/oneterm/pkg/conf"
"github.com/veops/oneterm/pkg/logger"
"github.com/veops/oneterm/pkg/server/router/middleware"
"github.com/veops/oneterm/pkg/util"
)
var routeGroup []*GroupRoute
func Server(cfg *conf.ConfigYaml) *http.Server {
routeConfig()
srv := &http.Server{
Addr: fmt.Sprintf("%s:%d", cfg.Http.Host, cfg.Http.Port),
Handler: setupRouter(),
}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.L.Error(err.Error())
os.Exit(1)
}
}()
logger.L.Info(fmt.Sprintf("start on server:%s", srv.Addr))
return srv
}
func GracefulExit(srv *http.Server, ch chan struct{}) {
<-ch
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
logger.L.Error(err.Error())
}
logger.L.Info("Shutdown server ...")
}
func routeConfig() {
var commonRoute []Route
commonRoute = append(commonRoute, routes...)
routeGroup = []*GroupRoute{
{
Prefix: "/api/oneterm/v1",
GroupMiddleware: gin.HandlersChain{
middleware.Error2Resp(),
middleware.RecoveryWithWriter(),
},
SubRoutes: commonRoute,
},
{
Prefix: "",
SubRoutes: baseRoutes,
},
}
}
func setupRouter() *gin.Engine {
r := gin.New()
r.SetTrustedProxies([]string{"0.0.0.0/0", "::/0"})
r.MaxMultipartMemory = 128 << 20
r.Use(
middleware.GinLogger(logger.L),
middleware.LogRequest(),
middleware.Cors(),
middleware.GinRecovery(logger.L, true))
// sso
gob.Register(map[string]any{}) // important!
store := cookie.NewStore([]byte(viper.GetString("gateway.secretKey")))
r.Use(sessions.Sessions("session", store))
routeGroupsMap := make(map[string]*gin.RouterGroup)
for _, gRoute := range routeGroup {
if _, ok := routeGroupsMap[gRoute.Prefix]; !ok {
routeGroupsMap[gRoute.Prefix] = r.Group(gRoute.Prefix)
}
for _, gMiddleware := range gRoute.GroupMiddleware {
routeGroupsMap[gRoute.Prefix].Use(gMiddleware)
}
for _, subRoute := range gRoute.SubRoutes {
length := len(subRoute.Middleware) + 2
routes := make([]any, length)
routes[0] = subRoute.Pattern
for i, v := range subRoute.Middleware {
routes[i+1] = v
}
routes[length-1] = subRoute.HandlerFunc
util.CallReflect(
routeGroupsMap[gRoute.Prefix],
subRoute.Method,
routes...)
}
}
r.Handle("GET", "/metrics", gin.WrapH(promhttp.Handler()))
// swagger
docs.SwaggerInfo.Title = "ONETERM API"
docs.SwaggerInfo.BasePath = "/api/oneterm/v1"
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
return r
}