core/app/app.go

168 lines
4.4 KiB
Go
Raw Normal View History

2024-02-19 17:48:04 +00:00
package app
import (
"context"
"errors"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/skeris/appInit"
"github.com/themakers/hlog"
"go.uber.org/zap"
2024-03-25 09:47:18 +00:00
"penahub.gitlab.yandexcloud.net/backend/penahub_common/privilege"
2024-02-19 17:48:04 +00:00
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/healthchecks"
2024-03-25 09:47:18 +00:00
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/middleware"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils"
"penahub.gitlab.yandexcloud.net/backend/quiz/core.git/clients/auth"
2024-02-19 17:48:04 +00:00
"penahub.gitlab.yandexcloud.net/backend/quiz/core.git/service"
"penahub.gitlab.yandexcloud.net/backend/quiz/core.git/tools"
"time"
2024-02-19 17:48:04 +00:00
)
type App struct {
logger *zap.Logger
err chan error
}
func (a App) GetLogger() *zap.Logger {
return a.logger
}
func (a App) GetErr() chan error {
return a.err
}
var (
errInvalidOptions = errors.New("invalid options")
)
var zapOptions = []zap.Option{
zap.AddCaller(),
zap.AddCallerSkip(2),
zap.AddStacktrace(zap.ErrorLevel),
}
var _ appInit.CommonApp = (*App)(nil)
type Options struct {
LoggerProdMode bool `env:"IS_PROD_LOG" default:"false"`
IsProd bool `env:"IS_PROD" default:"false"`
NumberPort string `env:"PORT" default:"1488"`
CrtFile string `env:"CRT" default:"server.crt"`
KeyFile string `env:"KEY" default:"server.key"`
2024-03-25 09:47:18 +00:00
PostgresCredentials string `env:"PG_CRED" default:"host=localhost port=5432 user=squiz password=Redalert2 dbname=squiz sslmode=disable"`
HubAdminUrl string `env:"HUB_ADMIN_URL" default:"http://localhost:8001/"`
2024-03-25 09:47:18 +00:00
ServiceName string `env:"SERVICE_NAME" default:"squiz"`
AuthServiceURL string `env:"AUTH_URL"`
RedirectURL string `env:"REDIRECT_URL" default:"https://squiz.pena.digital"`
PubKey string `env:"PUBLIC_KEY"`
PrivKey string `env:"PRIVATE_KEY"`
2024-02-19 17:48:04 +00:00
}
func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) {
var (
err, workerErr error
zapLogger *zap.Logger
errChan = make(chan error)
options Options
ok bool
)
if options, ok = opts.(Options); !ok {
return App{}, errInvalidOptions
}
if options.LoggerProdMode {
zapLogger, err = zap.NewProduction(zapOptions...)
if err != nil {
return nil, err
}
} else {
zapLogger, err = zap.NewDevelopment(zapOptions...)
if err != nil {
return nil, err
}
}
zapLogger = zapLogger.With(
zap.String("SvcCommit", ver.Commit),
zap.String("SvcVersion", ver.Release),
zap.String("SvcBuildTime", ver.BuildTime),
)
logger := hlog.New(zapLogger)
logger.Emit(InfoSvcStarted{})
2024-03-25 09:47:18 +00:00
authClient := auth.NewAuthClient(options.AuthServiceURL)
2024-02-19 17:48:04 +00:00
2024-03-25 09:47:18 +00:00
pgdal, err := dal.New(ctx, options.PostgresCredentials, authClient)
2024-02-19 17:48:04 +00:00
if err != nil {
fmt.Println("NEW", err)
return nil, err
}
if err := pgdal.Init(); err != nil {
fmt.Println("INIT", err)
return nil, err
}
2024-03-25 09:47:18 +00:00
clientData := privilege.Client{
URL: options.HubAdminUrl,
ServiceName: options.ServiceName,
Privileges: model.Privileges,
}
fiberClient := &fiber.Client{}
privilegeController := privilege.NewPrivilege(clientData, fiberClient)
go tools.PublishPrivilege(privilegeController, 10, 5*time.Minute)
2024-03-25 09:47:18 +00:00
encrypt := utils.NewEncrypt(options.PubKey, options.PrivKey)
2024-02-19 17:48:04 +00:00
app := fiber.New()
2024-03-25 09:47:18 +00:00
app.Use(middleware.JWTAuth())
2024-02-19 17:48:04 +00:00
app.Get("/liveness", healthchecks.Liveness)
app.Get("/readiness", healthchecks.Readiness(&workerErr)) //todo parametrized readiness. should discuss ready reason
2024-03-22 12:42:52 +00:00
svc := service.New(service.Deps{
Dal: pgdal,
RedirectURl: options.RedirectURL,
2024-03-25 09:47:18 +00:00
Encrypt: encrypt,
2024-03-22 12:42:52 +00:00
})
2024-02-19 17:48:04 +00:00
svc.Register(app)
logger.Emit(InfoSvcReady{})
go func() {
defer func() {
if pgdal != nil {
pgdal.Close()
}
err := app.Shutdown()
logger.Emit(InfoSvcShutdown{Signal: err.Error()})
}()
if options.IsProd {
if err := app.ListenTLS(fmt.Sprintf(":%s", options.NumberPort), options.CrtFile, options.KeyFile); err != nil {
logger.Emit(ErrorCanNotServe{
Err: err,
})
errChan <- err
}
} else {
if err := app.Listen(fmt.Sprintf(":%s", options.NumberPort)); err != nil {
logger.Emit(ErrorCanNotServe{
Err: err,
})
errChan <- err
}
}
errChan <- nil
}()
// todo implement helper func for service app type. such as server preparing, logger preparing, healthchecks and etc.
return &App{
logger: zapLogger,
err: errChan,
}, err
}