rts-sim-testing-service/starter/init.go

141 lines
3.8 KiB
Go

package starter
import (
"fmt"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"joylink.club/bj-rtsts-server/api"
"joylink.club/bj-rtsts-server/docs"
"joylink.club/bj-rtsts-server/middleware"
"joylink.club/bj-rtsts-server/mqtt"
"joylink.club/bj-rtsts-server/third_party"
"log/slog"
"net"
"net/http"
"os"
"runtime/debug"
"strings"
"joylink.club/bj-rtsts-server/db/dbquery"
"joylink.club/bj-rtsts-server/dto"
"joylink.club/bj-rtsts-server/sys_error"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
sloggin "github.com/samber/slog-gin"
"joylink.club/bj-rtsts-server/config"
"joylink.club/bj-rtsts-server/db"
"joylink.club/bj-rtsts-server/logger"
)
func Start() {
engine := initServer()
mqtt.Startup(mqtt.NewMqttOptions(config.Config.Messaging.Mqtt.Address, config.Config.Messaging.Mqtt.Username, config.Config.Messaging.Mqtt.Password))
third_party.Init()
authMiddleware := middleware.InitGinJwtMiddleware()
router := engine.Group("/api")
api.InitUserRouter(router, authMiddleware)
api.InitDraftingRouter(router, authMiddleware)
api.InitPublishedGiRouter(router, authMiddleware)
api.InitSimulationRouter(router, authMiddleware)
api.InitCategoryRouter(router, authMiddleware)
api.InitProjectRouter(router, authMiddleware)
api.InitTrainManageRouter(router, authMiddleware)
api.InitProjectLinkRouter(router, authMiddleware)
api.InitAuthRouter(router, authMiddleware)
api.InitProjectRunConfigRouter(router, authMiddleware)
docs.SwaggerInfo.Title = "CBTC测试系统API"
engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
serverConfig := config.Config.Server
if serverConfig.Port == 0 {
serverConfig.Port = 8080
}
engine.Run(fmt.Sprintf(":%d", config.Config.Server.Port))
}
func initServer() *gin.Engine {
config.LoadConfig()
err := logger.InitLogger()
if err != nil {
panic(err)
}
err = db.InitDb()
if err != nil {
panic(err)
}
dbquery.SetDefault(db.DB)
engine := gin.New()
conf := cors.DefaultConfig()
conf.AllowHeaders = []string{"*"}
conf.AllowAllOrigins = true
engine.Use(sloggin.New(slog.Default()))
engine.Use(cors.New(conf))
// gin panic 异常处理,默认处理为
engine.Use(customRecoveryWithSlog(slog.Default(), true, func(c *gin.Context, e interface{}) {
be, ok := e.(*sys_error.BusinessError)
if !ok {
e, ok := e.(error)
if ok {
be = sys_error.New("未知错误", e)
} else {
be = sys_error.New("未知错误", fmt.Errorf("%v", e))
}
}
c.Error(be)
statusCode := http.StatusInternalServerError
if be.ErrorCode > 0 {
statusCode = http.StatusForbidden
}
c.JSON(statusCode, &dto.ErrorDto{
Tip: be.UserMsg,
Message: be.Error(),
})
c.Writer.WriteHeaderNow()
c.Abort()
}))
return engine
}
func customRecoveryWithSlog(logger *slog.Logger, stack bool, recovery gin.RecoveryFunc) gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
if err := recover(); err != nil {
// Check for a broken connection, as it is not really a
// condition that warrants a panic stack trace.
var brokenPipe bool
if ne, ok := err.(*net.OpError); ok {
if se, ok := ne.Err.(*os.SyscallError); ok {
if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
brokenPipe = true
}
}
}
if brokenPipe {
logger.Error(c.Request.URL.Path,
"error", err,
)
// If the connection is dead, we can't write a status to it.
c.Error(err.(error)) // nolint: errcheck
c.Abort()
return
}
if stack {
logger.Error("请求处理Panic异常", "error", err, "stack", string(debug.Stack()))
} else {
logger.Error("请求处理Panic异常",
"error", err,
)
}
recovery(c, err)
}
}()
c.Next()
}
}