type THelper struct {
dockerContainer testcontainers.Container
postgresPool postgres.Client
m *migrate.Migrate
}
func SetupPostgresSQL(ctx context.Context) (*THelper, error) {
resource := testcontainers.ContainerRequest{
Image: "postgres:latest",
ExposedPorts: []string{"5432/tcp"},
WaitingFor: wait.ForListeningPort("5432/tcp"),
Env: map[string]string{
"POSTGRES_DB": "web",
"POSTGRES_PASSWORD": "postgres",
"POSTGRES_USER": "postgres",
},
}
dockerpool, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: resource,
Started: true,
})
if err != nil {
return nil, fmt.Errorf("failed to start postgres container: %w", err)
}
port, err := dockerpool.MappedPort(ctx, "5432")
if err != nil {
return nil, fmt.Errorf("failed to get mapped port: %w", err)
}
host, err := dockerpool.Host(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get host: %w", err)
}
dbURI := fmt.Sprintf("postgres://postgres:postgres@%v:%v/%s?sslmode=disable", host, port.Port(), "web")
// TODO: подумать над путем к миграциям
m, err := migrate.New("file://D:/dev/webshop/migrations", dbURI)
if err != nil {
return nil, fmt.Errorf("failed to create migrate instance: %w", err)
}
postgresPool, err := postgres.NewPool(ctx, dbURI)
if err != nil {
return nil, fmt.Errorf("failed to create postgres pool: %w", err)
}
return &THelper{
dockerContainer: dockerpool,
postgresPool: postgresPool,
cfg: cfg,
m: m,
}, nil
}
func (p *THelper) GetPostgresPool() postgres.Client {
return p.postgresPool
}
func (p *THelper) GetDockerContainer() testcontainers.Container {
return p.dockerContainer
}
func (p *THelper) RemoveContainer() error {
return p.dockerContainer.Terminate(context.Background())
}
func (p *THelper) MigrateUp() error {
return p.m.Up()
}
func (p *THelper) MigrateDown() error {
return p.m.Down()
}
type WebService struct {
uRepo *userRepo.UsersRepository
rRepo *roleRepo.RolesRepository
rSessionsRepo *refreshSessionsRepo.RefreshSessionsRepository
activateCodesRepo *activationCodesRepo.ActivationCodesRepository
ramblerSMTP *sender.RamblerSMTPServer
jwt *jwtAuth.JWT
}
func NewWebService(
uRepo *userRepo.UsersRepository,
rRepo *roleRepo.RolesRepository,
rSessionsRepo *refreshSessionsRepo.RefreshSessionsRepository,
activateCodesRepo *activationCodesRepo.ActivationCodesRepository,
ramblerSMTP *sender.RamblerSMTPServer,
jwt *jwtAuth.JWT,
) *WebService {
return &WebService{
uRepo: uRepo,
rRepo: rRepo,
rSessionsRepo: rSessionsRepo,
activateCodesRepo: activateCodesRepo,
ramblerSMTP: ramblerSMTP,
jwt: jwt,
}
}
type THelper struct {
dockerContainer testcontainers.Container
cfg *config.App
postgresPool postgres.Client
m *migrate.Migrate
}
func SetupPostgresSQL(ctx context.Context) (*THelper, error) {
cfg := config.LoadYML()
resource := testcontainers.ContainerRequest{
Image: "postgres:latest",
ExposedPorts: []string{"5432/tcp"},
WaitingFor: wait.ForListeningPort("5432/tcp"),
Env: map[string]string{
"POSTGRES_DB": "web",
"POSTGRES_PASSWORD": "postgres",
"POSTGRES_USER": "postgres",
},
}
dockerpool, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: resource,
Started: true,
})
if err != nil {
return nil, fmt.Errorf("failed to start postgres container: %w", err)
}
port, err := dockerpool.MappedPort(ctx, "5432")
if err != nil {
return nil, fmt.Errorf("failed to get mapped port: %w", err)
}
host, err := dockerpool.Host(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get host: %w", err)
}
dbURI := fmt.Sprintf("postgres://postgres:postgres@%v:%v/%s?sslmode=disable", host, port.Port(), "web")
// TODO: подумать над путем к миграциям
m, err := migrate.New("file://D:/dev/webshop/migrations", dbURI)
if err != nil {
return nil, fmt.Errorf("failed to create migrate instance: %w", err)
}
postgresPool, err := postgres.NewPool(ctx, dbURI)
if err != nil {
return nil, fmt.Errorf("failed to create postgres pool: %w", err)
}
return &THelper{
dockerContainer: dockerpool,
postgresPool: postgresPool,
cfg: cfg,
m: m,
}, nil
}
func (p *THelper) GetPostgresPool() postgres.Client {
return p.postgresPool
}
func (p *THelper) GetDockerContainer() testcontainers.Container {
return p.dockerContainer
}
func (p *THelper) RemoveContainer() error {
return p.dockerContainer.Terminate(context.Background())
}
func (p *THelper) GetConfig() *config.App {
return p.cfg
}
func (p *THelper) MigrateUp() error {
return p.m.Up()
}
func (p *THelper) MigrateDown() error {
return p.m.Down()
}
type App struct {
AppVersion string `yaml:"app_version"`
Domain string `yaml:"domain"`
Server `yaml:"server"`
JWT `yaml:"jwt"`
RamblerSMTP `yaml:"rambler_smtp"`
Logger `yaml:"logger"`
PostgresSQL `yaml:"postgres"`
}
type Server struct {
Port string `yaml:"port"`
CookieName string `yaml:"cookie_name"`
Mode string `yaml:"mode"`
ReadTimeout time.Duration `yaml:"read_timeout"`
WriteTimeout time.Duration `yaml:"write_timeout"`
SSL bool `yaml:"ssl"`
Debug bool `yaml:"debug"`
}
type JWT struct {
Secret string `yaml:"secret"`
AccessTTL time.Duration `yaml:"accessTTL"`
RefreshTTL time.Duration `yaml:"refreshTTL"`
}
type RamblerSMTP struct {
Host string `yaml:"host"`
Port string `yaml:"port"`
Email string `yaml:"email"`
Password string `yaml:"password"`
}
type Logger struct {
DisableCaller bool `yaml:"disable_caller"`
DisableStacktrace bool `yaml:"disable_stacktrace"`
Level string `yaml:"level"`
}
type PostgresSQL struct {
Host string `yaml:"host"`
Port string `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password"`
DBName string `yaml:"db_name"`
SSLMode string `yaml:"ssl_mode"`
}
var (
//configPath string
instance *App
once sync.Once
)
// LoadYML returns a completed instance of the App.
func LoadYML() *App {
once.Do(func() {
instance = &App{}
if err := cleanenv.ReadConfig("./config/config.yml", instance); err != nil {
log.Fatal(err)
}
})
return instance
}