142 lines
3.1 KiB
Go
142 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/getkin/kin-openapi/openapi3"
|
|
"github.com/getkin/kin-openapi/openapi3filter"
|
|
"github.com/labstack/echo-contrib/echoprometheus"
|
|
"github.com/labstack/echo-contrib/session"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/labstack/echo/v4/middleware"
|
|
oapiMiddleware "github.com/oapi-codegen/echo-middleware"
|
|
"github.com/wader/gormstore/v2"
|
|
"gorm.io/driver/postgres"
|
|
"gorm.io/gorm"
|
|
|
|
"gitrepo.ru/neonxp/nquest/api"
|
|
appmiddleware "gitrepo.ru/neonxp/nquest/pkg/contextlib"
|
|
"gitrepo.ru/neonxp/nquest/pkg/controller"
|
|
|
|
"gitrepo.ru/neonxp/nquest/pkg/models"
|
|
"gitrepo.ru/neonxp/nquest/pkg/service"
|
|
)
|
|
|
|
var Version = "dev"
|
|
|
|
func main() {
|
|
cfg, err := GetConfig()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error loading config\n: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
db, err := gorm.Open(postgres.Open(cfg.DSN()), &gorm.Config{})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error DB connection\n: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if err := db.AutoMigrate(
|
|
&models.User{},
|
|
&models.Game{},
|
|
&models.GameCursor{},
|
|
&models.Task{},
|
|
&models.Code{},
|
|
&models.File{},
|
|
); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error DB migration\n: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// --[ Services ]--
|
|
userService := service.NewUser(db)
|
|
gameService := service.NewGame(db)
|
|
engineService := service.NewEngine(db)
|
|
uploadService := service.NewFile(db)
|
|
|
|
// --[ HTTP server ]--
|
|
|
|
e := echo.New()
|
|
e.Debug = true
|
|
store := gormstore.New(db, []byte(cfg.Secret))
|
|
|
|
quit := make(chan struct{})
|
|
defer func() {
|
|
close(quit)
|
|
}()
|
|
go store.PeriodicCleanup(12*time.Hour, quit)
|
|
|
|
swagger, err := api.GetSwagger()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
swagger.Servers = []*openapi3.Server{{URL: "/api", Description: "Needed to match path"}}
|
|
|
|
e.Use(
|
|
middleware.Recover(),
|
|
middleware.RequestID(),
|
|
session.Middleware(store),
|
|
middleware.Logger(),
|
|
middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(20)),
|
|
middleware.Gzip(),
|
|
echoprometheus.NewMiddleware("nquest"),
|
|
appmiddleware.User(userService),
|
|
)
|
|
|
|
// --[ Router ]--
|
|
handler := serverRouter{
|
|
Game: &controller.Game{
|
|
GameService: gameService,
|
|
},
|
|
User: &controller.User{
|
|
UserService: userService,
|
|
},
|
|
Engine: &controller.Engine{
|
|
GameService: gameService,
|
|
EngineService: engineService,
|
|
},
|
|
Admin: &controller.Admin{
|
|
GameService: gameService,
|
|
},
|
|
File: &controller.File{
|
|
FileService: uploadService,
|
|
},
|
|
}
|
|
codegen := e.Group("")
|
|
|
|
codegen.Use(
|
|
oapiMiddleware.OapiRequestValidatorWithOptions(
|
|
swagger,
|
|
&oapiMiddleware.Options{
|
|
Options: openapi3filter.Options{
|
|
AuthenticationFunc: authFunc,
|
|
},
|
|
SilenceServersWarning: true,
|
|
},
|
|
),
|
|
)
|
|
|
|
api.RegisterHandlersWithBaseURL(codegen, handler, "/api")
|
|
|
|
e.FileFS("/", "index.html", distIndexHtml)
|
|
e.FileFS("/*", "index.html", distIndexHtml)
|
|
e.StaticFS("/", distDirFS)
|
|
|
|
// --[ System ]--
|
|
e.GET("/metrics", echoprometheus.NewHandler())
|
|
e.Logger.Debugf("backend version %s", Version)
|
|
e.Logger.Fatal(e.Start(cfg.Listen))
|
|
}
|
|
|
|
type serverRouter struct {
|
|
*controller.Game
|
|
*controller.User
|
|
*controller.Engine
|
|
*controller.Admin
|
|
*controller.File
|
|
}
|