codeword/internal/app/app.go

123 lines
3.5 KiB
Go
Raw Normal View History

2023-12-29 11:30:20 +00:00
package app
import (
2024-01-03 13:50:11 +00:00
"codeword/internal/adapters/client"
2023-12-29 11:30:20 +00:00
controller "codeword/internal/controller/recovery"
"codeword/internal/initialize"
"codeword/internal/repository"
httpserver "codeword/internal/server/http"
"codeword/internal/services"
2023-12-29 16:09:06 +00:00
"codeword/internal/utils/encrypt"
2024-01-01 14:13:54 +00:00
"codeword/internal/worker/recovery_worker"
2023-12-29 11:30:20 +00:00
"context"
2024-01-03 13:50:11 +00:00
"github.com/gofiber/fiber/v2"
2023-12-29 18:02:50 +00:00
"go.mongodb.org/mongo-driver/mongo"
2023-12-29 11:30:20 +00:00
"go.uber.org/zap"
"time"
)
func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
logger.Info("Запуск приложения", zap.String("AppName", cfg.AppName))
2023-12-29 12:41:26 +00:00
mdb, err := initialize.InitializeMongoDB(ctx, cfg)
if err != nil {
logger.Error("Failed to initialize MongoDB", zap.Error(err))
return err
}
2023-12-31 12:22:03 +00:00
rdb, err := initialize.InitializeRedis(ctx, cfg)
2023-12-29 16:09:06 +00:00
encryptService := encrypt.New(&encrypt.EncryptDeps{
PublicKey: cfg.PublicCurveKey,
PrivateKey: cfg.PrivateCurveKey,
SignSecret: cfg.SignSecret,
})
2023-12-31 12:22:03 +00:00
codewordRepo := repository.NewCodewordRepository(repository.Deps{Rdb: rdb, Mdb: mdb.Collection("codeword")})
userRepo := repository.NewUserRepository(repository.Deps{Rdb: nil, Mdb: mdb.Collection("users")})
2023-12-29 18:02:50 +00:00
2024-01-03 13:50:11 +00:00
recoveryEmailSender := client.NewRecoveryEmailSender(client.RecoveryEmailSenderDeps{
SmtpApiUrl: cfg.SmtpApiUrl,
SmtpHost: cfg.SmtpHost,
SmtpPort: cfg.SmtpPort,
SmtpSender: cfg.SmtpSender,
Username: cfg.SmtpUsername,
Password: cfg.SmtpPassword,
ApiKey: cfg.SmtpApiKey,
FiberClient: &fiber.Client{},
Logger: logger,
})
2023-12-29 18:02:50 +00:00
recoveryService := services.NewRecoveryService(services.Deps{
2023-12-31 12:22:03 +00:00
Logger: logger,
CodewordRepository: codewordRepo,
UserRepository: userRepo,
EncryptService: encryptService,
2023-12-29 18:02:50 +00:00
})
2023-12-29 11:30:20 +00:00
recoveryController := controller.NewRecoveryController(logger, recoveryService)
2023-12-29 12:41:26 +00:00
2024-01-03 13:50:11 +00:00
recoveryWC := recovery_worker.NewRecoveryWC(recovery_worker.Deps{
Logger: logger,
Redis: rdb,
EmailSender: recoveryEmailSender,
})
2024-01-01 14:13:54 +00:00
go recoveryWC.Start(ctx)
2023-12-29 11:30:20 +00:00
server := httpserver.NewServer(httpserver.ServerConfig{
Logger: logger,
RecoveryController: recoveryController,
})
go func() {
2023-12-29 12:41:26 +00:00
if err := server.Start(cfg.HTTPHost + ":" + cfg.HTTPPort); err != nil {
2023-12-29 11:30:20 +00:00
logger.Error("Ошибка запуска сервера", zap.Error(err))
}
}()
<-ctx.Done()
2023-12-29 18:02:50 +00:00
if err := shutdownApp(server, mdb, logger); err != nil {
2023-12-29 11:30:20 +00:00
return err
}
logger.Info("Приложение остановлено")
return nil
}
2023-12-29 18:02:50 +00:00
// TODO возможно стоит вынести в отдельные файлы или отказаться от разделения на отдельные методы
func shutdownApp(server *httpserver.Server, mdb *mongo.Database, logger *zap.Logger) error {
if err := shutdownHTTPServer(server, logger); err != nil {
return err
}
if err := shutdownMongoDB(mdb, logger); err != nil {
return err
}
return nil
}
func shutdownHTTPServer(server *httpserver.Server, logger *zap.Logger) error {
2023-12-29 11:30:20 +00:00
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
2023-12-29 18:02:50 +00:00
logger.Error("Ошибка при остановке HTTP-сервера", zap.Error(err))
return err
}
return nil
}
func shutdownMongoDB(mdb *mongo.Database, logger *zap.Logger) error {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := mdb.Client().Disconnect(ctx); err != nil {
logger.Error("Ошибка при закрытии соединения с MongoDB", zap.Error(err))
2023-12-29 11:30:20 +00:00
return err
}
return nil
}