package app import ( "context" "errors" "fmt" "gitea.pena/SQuiz/common/dal" "gitea.pena/SQuiz/common/healthchecks" "gitea.pena/SQuiz/common/middleware" dalBS "gitea.pena/SQuiz/storer/dal" "gitea.pena/SQuiz/storer/service" "github.com/gofiber/fiber/v2" "gitea.pena/PenaSide/hlog" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" "github.com/skeris/appInit" "go.uber.org/zap" ) 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"` S3Endpoint string `env:"S3_ENDPOINT" envDefault:"localhost:3002"` S3AccessKey string `env:"S3_ACCESS_KEY" envDefault:"minio"` S3SecretKey string `env:"S3_SECRET_KEY" envDefault:"miniostorage"` ClientHttpURL string `env:"CLIENT_HTTP_URL" envDefault:"0.0.0.0:1489"` CrtFile string `env:"CRT" default:"server.crt"` KeyFile string `env:"KEY" default:"server.key"` PostgresURL string `env:"POSTGRES_URL" envDefault:"host=localhost port=5432 user=squiz password=Redalert2 dbname=squiz sslmode=disable"` } 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{}) pgdal, err := dal.New(ctx, options.PostgresURL, nil) if err != nil { return nil, err } // Initialize minio client object. minioClient, err := minio.New(options.S3Endpoint, &minio.Options{ Creds: credentials.NewStaticV4(options.S3AccessKey, options.S3SecretKey, ""), Secure: options.IsProd, }) if err != nil { fmt.Println("MINIOERR", options.S3Endpoint, err) return nil, err } blobstore, err := dalBS.New(ctx, minioClient) if err != nil { return nil, err } svc := service.New(blobstore, pgdal) app := fiber.New(fiber.Config{BodyLimit: 70 * 1024 * 1024}) app.Use(middleware.JWTAuth()) app.Get("/liveness", healthchecks.Liveness) app.Get("/readiness", healthchecks.Readiness(&workerErr)) //todo parametrized readiness. should discuss ready reason svc.Register(app) logger.Emit(InfoSvcReady{}) go func() { defer func() { //if pgdal != nil { // pgdal.CloseStorer() //} err := app.Shutdown() if err != nil { logger.Emit(InfoSvcShutdown{Signal: err.Error()}) } }() if options.IsProd { if err := app.ListenTLS(options.ClientHttpURL, options.CrtFile, options.KeyFile); err != nil { logger.Emit(ErrorCanNotServe{ Err: err, }) errChan <- err } } else { if err := app.Listen(options.ClientHttpURL); 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 }