fix layout
This commit is contained in:
parent
64d15aff7f
commit
36eec4a2c0
156
app/app.go
156
app/app.go
@ -1,156 +0,0 @@
|
||||
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"
|
||||
"gitea.pena/PenaSide/hlog"
|
||||
"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
|
||||
}
|
25
cmd/main.go
Normal file
25
cmd/main.go
Normal file
@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gitea.pena/SQuiz/storer/internal/app"
|
||||
"gitea.pena/SQuiz/storer/internal/initialize"
|
||||
"go.uber.org/zap"
|
||||
"log"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func main() {
|
||||
config, err := initialize.LoadConfig()
|
||||
if err != nil {
|
||||
log.Fatal("Failed to load config", zap.Error(err))
|
||||
}
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
if err = app.Run(ctx, *config); err != nil {
|
||||
log.Fatal("App exited with error", zap.Error(err))
|
||||
}
|
||||
}
|
2
go.mod
2
go.mod
@ -18,6 +18,7 @@ require (
|
||||
gitea.pena/PenaSide/common v0.0.0-20250103085335-91ea31fee517 // indirect
|
||||
github.com/ClickHouse/clickhouse-go v1.5.4 // indirect
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/caarlos0/env/v8 v8.0.0 // indirect
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
@ -25,6 +26,7 @@ require (
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
|
12
go.sum
12
go.sum
@ -2,8 +2,12 @@ gitea.pena/PenaSide/common v0.0.0-20250103085335-91ea31fee517 h1:EgBe8VcdPwmxbSz
|
||||
gitea.pena/PenaSide/common v0.0.0-20250103085335-91ea31fee517/go.mod h1:91EuBCgcqgJ6mG36n2pds8sPwwfaJytLWOzY3h2YFKU=
|
||||
gitea.pena/PenaSide/hlog v0.0.0-20241125221102-a54c29c002a9 h1:tBkXWNIt8icmkMMnq8MA421RWkUy4OZh5P7C3q8uCu4=
|
||||
gitea.pena/PenaSide/hlog v0.0.0-20241125221102-a54c29c002a9/go.mod h1:sanhSL8aEsfcq21P+eItYiAnKAre+B67nGJmDfk2cf0=
|
||||
gitea.pena/SQuiz/common v0.0.0-20250207214652-9994f2d4d43f h1:458FCN98jVkjAqg3yyspgkUdJnKz3BNMiZosrVtPpv8=
|
||||
gitea.pena/SQuiz/common v0.0.0-20250207214652-9994f2d4d43f/go.mod h1:/YR+uo4RouZshuHPkguk7nAJVKuFt3Z0mTFxUPdlzxQ=
|
||||
gitea.pena/PenaSide/linters-golang v0.0.0-20241207122018-933207374735 h1:jDVeUhGBTXBibmW5dmtJg2m2+z5z2Rf6J4G0LpjVoJ0=
|
||||
gitea.pena/PenaSide/linters-golang v0.0.0-20241207122018-933207374735/go.mod h1:gdd+vOT6up9STkEbxa2qESLIMZFjCmRbkcheFQCVgZU=
|
||||
gitea.pena/SQuiz/common v0.0.0-20250205160239-4ed00d74894b h1:N3DdDWQyTXC0B5mI7OpjxHQuHtt6EJCK+vqRrLqcb1w=
|
||||
gitea.pena/SQuiz/common v0.0.0-20250205160239-4ed00d74894b/go.mod h1:zCrUwDh0APpztKk6NUqTZv+zhjVbWpGBJiJ5z9dAH0U=
|
||||
gitea.pena/SQuiz/common v0.0.0-20250221135056-f98c45e04909 h1:iCiqaJ6a7rGESAEUgtVA9IqhVn0oKiwRk7bryTWPV5w=
|
||||
gitea.pena/SQuiz/common v0.0.0-20250221135056-f98c45e04909/go.mod h1:rQRjqLlLyM71FZcvbM95Nv3ciq44F9DFtUHPZmDK3T8=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
|
||||
github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
|
||||
@ -11,6 +15,8 @@ github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
|
||||
github.com/caarlos0/env/v8 v8.0.0 h1:POhxHhSpuxrLMIdvTGARuZqR4Jjm8AYmoi/JKlcScs0=
|
||||
github.com/caarlos0/env/v8 v8.0.0/go.mod h1:7K4wMY9bH0esiXSSHlfHLX5xKGQMnkH5Fk4TDSSSzfo=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -35,6 +41,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
|
96
internal/app/app.go
Normal file
96
internal/app/app.go
Normal file
@ -0,0 +1,96 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"gitea.pena/SQuiz/storer/internal/initialize"
|
||||
"gitea.pena/SQuiz/storer/internal/server/http"
|
||||
"gitea.pena/SQuiz/storer/pkg/closer"
|
||||
"github.com/gofiber/fiber/v2/log"
|
||||
"go.uber.org/zap"
|
||||
"time"
|
||||
)
|
||||
|
||||
var zapOptions = []zap.Option{
|
||||
zap.AddCaller(),
|
||||
zap.AddCallerSkip(2),
|
||||
zap.AddStacktrace(zap.ErrorLevel),
|
||||
}
|
||||
|
||||
func Run(ctx context.Context, cfg initialize.Config) error {
|
||||
var (
|
||||
err error
|
||||
zapLogger *zap.Logger
|
||||
)
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Error("Recovered from a panic", zap.Any("error", r))
|
||||
}
|
||||
}()
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
if cfg.LoggerProdMode {
|
||||
zapLogger, err = zap.NewProduction(zapOptions...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
zapLogger, err = zap.NewDevelopment(zapOptions...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
shutdownGroup := closer.NewCloserGroup()
|
||||
|
||||
minioClient, err := initialize.NewMinio(cfg)
|
||||
if err != nil {
|
||||
zapLogger.Error("Error initializing minio", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
dalS, err := initialize.NewDALs(ctx, cfg, minioClient)
|
||||
if err != nil {
|
||||
zapLogger.Error("Error initializing dals", zap.Error(err))
|
||||
}
|
||||
|
||||
controllers := initialize.NewControllers(initialize.ControllerDeps{
|
||||
DALs: dalS,
|
||||
})
|
||||
|
||||
srv := http.NewServer(http.ServerConfig{
|
||||
Logger: zapLogger,
|
||||
Controllers: []http.Controller{controllers.HttpControllers.QuizFiles},
|
||||
})
|
||||
|
||||
go func() {
|
||||
if err := srv.Start(cfg.ClientHttpURL); err != nil {
|
||||
zapLogger.Error("HTTP server startup error", zap.Error(err))
|
||||
cancel()
|
||||
}
|
||||
}()
|
||||
|
||||
srv.ListRoutes()
|
||||
|
||||
shutdownGroup.Add(closer.CloserFunc(srv.Shutdown))
|
||||
shutdownGroup.Add(closer.CloserFunc(dalS.PgDAL.Close))
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
timeoutCtx, timeoutCancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer timeoutCancel()
|
||||
if err := shutdownGroup.Call(timeoutCtx); err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
zapLogger.Error("Shutdown timed out", zap.Error(err))
|
||||
} else {
|
||||
zapLogger.Error("Failed to shutdown services gracefully", zap.Error(err))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
zapLogger.Info("Application has stopped")
|
||||
return nil
|
||||
}
|
@ -1,41 +1,30 @@
|
||||
package service
|
||||
package quiz_files
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"io"
|
||||
quizdal "gitea.pena/SQuiz/common/dal"
|
||||
"gitea.pena/SQuiz/common/dal"
|
||||
mw "gitea.pena/SQuiz/common/middleware"
|
||||
"gitea.pena/SQuiz/storer/dal"
|
||||
"gitea.pena/SQuiz/storer/internal/repository"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/rs/xid"
|
||||
"io"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/rs/xid"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
store *dal.Storer
|
||||
dal *quizdal.DAL
|
||||
type QuizFiles struct {
|
||||
stDal *repository.S3
|
||||
pgDal *dal.DAL
|
||||
}
|
||||
|
||||
func New(s *dal.Storer, q *quizdal.DAL) *Service {
|
||||
return &Service{
|
||||
store: s,
|
||||
dal: q,
|
||||
func New(stDal *repository.S3, pgDal *dal.DAL) *QuizFiles {
|
||||
return &QuizFiles{
|
||||
stDal: stDal,
|
||||
pgDal: pgDal,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) Register(app *fiber.App) {
|
||||
app.Put("/quiz/customization", s.UploadCustom)
|
||||
app.Put("/quiz/putImages", s.UploadImages)
|
||||
}
|
||||
|
||||
// MB Size constants
|
||||
const (
|
||||
MB = 1 << 20
|
||||
)
|
||||
|
||||
func (s *Service) UploadCustom(c *fiber.Ctx) error {
|
||||
func (r *QuizFiles) UploadCustom(c *fiber.Ctx) error {
|
||||
accountId, ok := mw.GetAccountId(c)
|
||||
if !ok {
|
||||
return nil
|
||||
@ -57,7 +46,7 @@ func (s *Service) UploadCustom(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusBadRequest).SendString("not valid quiz id provided " + err.Error())
|
||||
}
|
||||
|
||||
quiz, err := s.dal.QuizRepo.GetQuizById(c.Context(), accountId, uint64(squizId))
|
||||
quiz, err := r.pgDal.QuizRepo.GetQuizById(c.Context(), accountId, uint64(squizId))
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusNotAcceptable).SendString("not exists quiz id provided " + err.Error())
|
||||
}
|
||||
@ -82,7 +71,7 @@ func (s *Service) UploadCustom(c *fiber.Ctx) error {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if err := s.store.UploadScript(c.Context(), quiz.Qid, file, fileHeader.Size); err != nil {
|
||||
if err := r.stDal.UploadScript(c.Context(), quiz.Qid, file, fileHeader.Size); err != nil {
|
||||
errm.Lock()
|
||||
defer errm.Unlock()
|
||||
errs = append(errs, errors.New(err.Error()+" => script upload"))
|
||||
@ -104,7 +93,7 @@ func (s *Service) UploadCustom(c *fiber.Ctx) error {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if err := s.store.UploadStyle(c.Context(), quiz.Qid, file, fileHeader.Size); err != nil {
|
||||
if err := r.stDal.UploadStyle(c.Context(), quiz.Qid, file, fileHeader.Size); err != nil {
|
||||
errm.Lock()
|
||||
defer errm.Unlock()
|
||||
errs = append(errs, errors.New(err.Error()+" => style upload"))
|
||||
@ -128,7 +117,7 @@ func (s *Service) UploadCustom(c *fiber.Ctx) error {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if errorsFontUploading := s.store.UploadFonts(c.Context(), quiz.Qid, files, sizes); err != nil {
|
||||
if errorsFontUploading := r.stDal.UploadFonts(c.Context(), quiz.Qid, files, sizes); err != nil {
|
||||
errm.Lock()
|
||||
defer errm.Unlock()
|
||||
errs = append(errs, errorsFontUploading...)
|
||||
@ -144,7 +133,7 @@ func (s *Service) UploadCustom(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
|
||||
func (s *Service) UploadImages(c *fiber.Ctx) error {
|
||||
func (r *QuizFiles) UploadImages(c *fiber.Ctx) error {
|
||||
accountId, ok := mw.GetAccountId(c)
|
||||
if !ok {
|
||||
return nil
|
||||
@ -166,7 +155,7 @@ func (s *Service) UploadImages(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusBadRequest).SendString("not valid quiz id provided " + err.Error())
|
||||
}
|
||||
|
||||
quiz, err := s.dal.QuizRepo.GetQuizById(c.Context(), accountId, uint64(squizId))
|
||||
quiz, err := r.pgDal.QuizRepo.GetQuizById(c.Context(), accountId, uint64(squizId))
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusNotAcceptable).SendString("not exists quiz id provided " + err.Error())
|
||||
}
|
||||
@ -189,7 +178,7 @@ func (s *Service) UploadImages(c *fiber.Ctx) error {
|
||||
defer f.Close()
|
||||
}
|
||||
|
||||
if err := s.store.UploadImages(c.Context(), quiz.Qid, files, sizes); err != nil {
|
||||
if err := r.stDal.UploadImages(c.Context(), quiz.Qid, files, sizes); err != nil {
|
||||
errs = append(errs, err...)
|
||||
}
|
||||
}
|
12
internal/controllers/http_controllers/quiz_files/route.go
Normal file
12
internal/controllers/http_controllers/quiz_files/route.go
Normal file
@ -0,0 +1,12 @@
|
||||
package quiz_files
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
|
||||
func (r *QuizFiles) Register(router fiber.Router) {
|
||||
router.Put("/customization", r.UploadCustom)
|
||||
router.Put("/putImages", r.UploadImages)
|
||||
}
|
||||
|
||||
func (r *QuizFiles) Name() string {
|
||||
return "quiz"
|
||||
}
|
30
internal/initialize/config.go
Normal file
30
internal/initialize/config.go
Normal file
@ -0,0 +1,30 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"github.com/caarlos0/env/v8"
|
||||
"github.com/joho/godotenv"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
LoggerProdMode bool `env:"IS_PROD_LOG" default:"false"`
|
||||
IsProd bool `env:"IS_PROD" default:"false"`
|
||||
S3Endpoint string `env:"S3_ENDPOINT" envDefault:"localhost:9001"`
|
||||
S3AccessKey string `env:"S3_ACCESS_KEY" envDefault:"admin"`
|
||||
S3SecretKey string `env:"S3_SECRET_KEY" envDefault:"admin123"`
|
||||
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=35432 user=squiz password=Redalert2 dbname=squiz sslmode=disable"`
|
||||
}
|
||||
|
||||
func LoadConfig() (*Config, error) {
|
||||
if err := godotenv.Load(); err != nil {
|
||||
log.Print("No .env file found")
|
||||
}
|
||||
var config Config
|
||||
if err := env.Parse(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &config, nil
|
||||
}
|
25
internal/initialize/controllers.go
Normal file
25
internal/initialize/controllers.go
Normal file
@ -0,0 +1,25 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"gitea.pena/SQuiz/storer/internal/controllers/http_controllers/quiz_files"
|
||||
)
|
||||
|
||||
type ControllerDeps struct {
|
||||
DALs *DALs
|
||||
}
|
||||
|
||||
type Controller struct {
|
||||
HttpControllers HttpControllers
|
||||
}
|
||||
|
||||
type HttpControllers struct {
|
||||
QuizFiles *quiz_files.QuizFiles
|
||||
}
|
||||
|
||||
func NewControllers(deps ControllerDeps) *Controller {
|
||||
return &Controller{
|
||||
HttpControllers: HttpControllers{
|
||||
QuizFiles: quiz_files.New(deps.DALs.StDal, deps.DALs.PgDAL),
|
||||
},
|
||||
}
|
||||
}
|
30
internal/initialize/dals.go
Normal file
30
internal/initialize/dals.go
Normal file
@ -0,0 +1,30 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gitea.pena/SQuiz/common/dal"
|
||||
"gitea.pena/SQuiz/storer/internal/repository"
|
||||
"github.com/minio/minio-go/v7"
|
||||
)
|
||||
|
||||
type DALs struct {
|
||||
PgDAL *dal.DAL
|
||||
StDal *repository.S3
|
||||
}
|
||||
|
||||
func NewDALs(ctx context.Context, cfg Config, minioClient *minio.Client) (*DALs, error) {
|
||||
pgDal, err := dal.New(ctx, cfg.PostgresURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stDal, err := repository.New(ctx, minioClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &DALs{
|
||||
PgDAL: pgDal,
|
||||
StDal: stDal,
|
||||
}, nil
|
||||
}
|
17
internal/initialize/minio.go
Normal file
17
internal/initialize/minio.go
Normal file
@ -0,0 +1,17 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
)
|
||||
|
||||
func NewMinio(cfg Config) (*minio.Client, error) {
|
||||
minioClient, err := minio.New(cfg.S3Endpoint, &minio.Options{
|
||||
Creds: credentials.NewStaticV4(cfg.S3AccessKey, cfg.S3SecretKey, ""),
|
||||
Secure: cfg.IsProd,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return minioClient, nil
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package dal
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -16,18 +16,18 @@ const (
|
||||
bucketStyle = "squizstyle"
|
||||
)
|
||||
|
||||
type Storer struct {
|
||||
type S3 struct {
|
||||
client *minio.Client
|
||||
}
|
||||
|
||||
func New(ctx context.Context, minioClient *minio.Client) (*Storer, error) {
|
||||
func New(ctx context.Context, minioClient *minio.Client) (*S3, error) {
|
||||
|
||||
return &Storer{
|
||||
return &S3{
|
||||
client: minioClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Storer) UploadImages(ctx context.Context, quid string, files map[string]io.Reader, sizes map[string]int64) []error {
|
||||
func (s *S3) UploadImages(ctx context.Context, quid string, files map[string]io.Reader, sizes map[string]int64) []error {
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
m sync.Mutex
|
||||
@ -57,7 +57,7 @@ func (s *Storer) UploadImages(ctx context.Context, quid string, files map[string
|
||||
return errs
|
||||
}
|
||||
|
||||
func (s *Storer) UploadFonts(ctx context.Context, quid string, files map[string]io.Reader, sizes map[string]int64) []error {
|
||||
func (s *S3) UploadFonts(ctx context.Context, quid string, files map[string]io.Reader, sizes map[string]int64) []error {
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
m sync.Mutex
|
||||
@ -87,7 +87,7 @@ func (s *Storer) UploadFonts(ctx context.Context, quid string, files map[string]
|
||||
return errs
|
||||
}
|
||||
|
||||
func (s *Storer) UploadScript(ctx context.Context, quid string, file io.Reader, size int64) error {
|
||||
func (s *S3) UploadScript(ctx context.Context, quid string, file io.Reader, size int64) error {
|
||||
if _, err := s.client.PutObject(ctx,
|
||||
bucket,
|
||||
bucketScripts+"/"+fmt.Sprintf("%s.js", quid),
|
||||
@ -100,7 +100,7 @@ func (s *Storer) UploadScript(ctx context.Context, quid string, file io.Reader,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Storer) UploadStyle(ctx context.Context, quid string, file io.Reader, size int64) error {
|
||||
func (s *S3) UploadStyle(ctx context.Context, quid string, file io.Reader, size int64) error {
|
||||
if _, err := s.client.PutObject(ctx,
|
||||
bucket,
|
||||
bucketStyle+"/"+fmt.Sprintf("%s.css", quid),
|
69
internal/server/http/http_server.go
Normal file
69
internal/server/http/http_server.go
Normal file
@ -0,0 +1,69 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"gitea.pena/SQuiz/common/middleware"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type ServerConfig struct {
|
||||
Logger *zap.Logger
|
||||
Controllers []Controller
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Logger *zap.Logger
|
||||
Controllers []Controller
|
||||
app *fiber.App
|
||||
}
|
||||
|
||||
func NewServer(config ServerConfig) *Server {
|
||||
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
|
||||
s := &Server{
|
||||
Logger: config.Logger,
|
||||
Controllers: config.Controllers,
|
||||
app: app,
|
||||
}
|
||||
|
||||
s.registerRoutes()
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Server) Start(addr string) error {
|
||||
if err := s.app.Listen(addr); err != nil {
|
||||
s.Logger.Error("Failed to start server", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) Shutdown(ctx context.Context) error {
|
||||
return s.app.Shutdown()
|
||||
}
|
||||
|
||||
func (s *Server) registerRoutes() {
|
||||
for _, c := range s.Controllers {
|
||||
router := s.app.Group(c.Name())
|
||||
c.Register(router)
|
||||
}
|
||||
}
|
||||
|
||||
type Controller interface {
|
||||
Register(router fiber.Router)
|
||||
Name() string
|
||||
}
|
||||
|
||||
func (s *Server) ListRoutes() {
|
||||
fmt.Println("Registered routes:")
|
||||
for _, stack := range s.app.Stack() {
|
||||
for _, route := range stack {
|
||||
fmt.Printf("%s %s\n", route.Method, route.Path)
|
||||
}
|
||||
}
|
||||
}
|
11
main.go
11
main.go
@ -1,11 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/skeris/appInit"
|
||||
"gitea.pena/SQuiz/storer/app"
|
||||
_ "gitea.pena/PenaSide/linters-golang/pkg/dummy"
|
||||
)
|
||||
|
||||
func main() {
|
||||
appInit.Initialize(app.New, app.Options{})
|
||||
}
|
37
pkg/closer/closer.go
Normal file
37
pkg/closer/closer.go
Normal file
@ -0,0 +1,37 @@
|
||||
package closer
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Closer interface {
|
||||
Close(ctx context.Context) error
|
||||
}
|
||||
|
||||
type CloserFunc func(ctx context.Context) error
|
||||
|
||||
func (cf CloserFunc) Close(ctx context.Context) error {
|
||||
return cf(ctx)
|
||||
}
|
||||
|
||||
type CloserGroup struct {
|
||||
closers []Closer
|
||||
}
|
||||
|
||||
func NewCloserGroup() *CloserGroup {
|
||||
return &CloserGroup{}
|
||||
}
|
||||
|
||||
func (cg *CloserGroup) Add(c Closer) {
|
||||
cg.closers = append(cg.closers, c)
|
||||
}
|
||||
|
||||
func (cg *CloserGroup) Call(ctx context.Context) error {
|
||||
var closeErr error
|
||||
for i := len(cg.closers) - 1; i >= 0; i-- {
|
||||
if err := cg.closers[i].Close(ctx); err != nil && closeErr == nil {
|
||||
closeErr = err
|
||||
}
|
||||
}
|
||||
return closeErr
|
||||
}
|
Loading…
Reference in New Issue
Block a user