add service
All checks were successful
Deploy Smart Search Backend Test / deploy (push) Successful in 2m55s
All checks were successful
Deploy Smart Search Backend Test / deploy (push) Successful in 2m55s
This commit is contained in:
@@ -2,13 +2,14 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"os"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
_ "github.com/jackc/pgx/v5/stdlib"
|
_ "github.com/jackc/pgx/v5/stdlib"
|
||||||
rkboot "github.com/rookie-ninja/rk-boot/v2"
|
rkboot "github.com/rookie-ninja/rk-boot/v2"
|
||||||
rkentry "github.com/rookie-ninja/rk-entry/v2/entry"
|
rkentry "github.com/rookie-ninja/rk-entry/v2/entry"
|
||||||
rkgrpc "github.com/rookie-ninja/rk-grpc/v2/boot"
|
rkgrpc "github.com/rookie-ninja/rk-grpc/v2/boot"
|
||||||
|
"go.uber.org/zap"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
"git.techease.ru/Smart-search/smart-search-back/internal/config"
|
"git.techease.ru/Smart-search/smart-search-back/internal/config"
|
||||||
@@ -19,50 +20,51 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cfg, err := config.Load("config/config.yaml")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to load config: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
if err := database.RunMigrations(cfg.DatabaseURL()); err != nil {
|
|
||||||
log.Fatalf("Failed to run migrations: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pool, err := pgxpool.New(ctx, cfg.DatabaseURL())
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to connect to database: %v", err)
|
|
||||||
}
|
|
||||||
defer pool.Close()
|
|
||||||
|
|
||||||
if err := pool.Ping(ctx); err != nil {
|
|
||||||
log.Fatalf("Failed to ping database: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("Successfully connected to database")
|
|
||||||
|
|
||||||
boot := rkboot.NewBoot(rkboot.WithBootConfigPath("config/boot.yaml", nil))
|
boot := rkboot.NewBoot(rkboot.WithBootConfigPath("config/boot.yaml", nil))
|
||||||
|
|
||||||
grpcEntry := rkgrpc.GetGrpcEntry("smart-search-service")
|
loggerEntry := rkentry.GlobalAppCtx.GetLoggerEntry("smart-search-logger")
|
||||||
if grpcEntry == nil {
|
|
||||||
log.Fatal("Failed to get gRPC entry from rk-boot")
|
|
||||||
}
|
|
||||||
|
|
||||||
loggerEntry := rkentry.GlobalAppCtx.GetLoggerEntry("smart-search-service")
|
|
||||||
if loggerEntry == nil {
|
if loggerEntry == nil {
|
||||||
loggerEntry = rkentry.GlobalAppCtx.GetLoggerEntryDefault()
|
loggerEntry = rkentry.GlobalAppCtx.GetLoggerEntryDefault()
|
||||||
}
|
}
|
||||||
logger := loggerEntry.Logger
|
logger := loggerEntry.Logger
|
||||||
|
|
||||||
|
cfg, err := config.Load("config/config.yaml")
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatal("Failed to load config", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
if err := database.RunMigrations(cfg.DatabaseURL(), logger); err != nil {
|
||||||
|
logger.Fatal("Failed to run migrations", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
pool, err := pgxpool.New(ctx, cfg.DatabaseURL())
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatal("Failed to connect to database", zap.Error(err))
|
||||||
|
}
|
||||||
|
defer pool.Close()
|
||||||
|
|
||||||
|
if err := pool.Ping(ctx); err != nil {
|
||||||
|
logger.Fatal("Failed to ping database", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("Successfully connected to database")
|
||||||
|
|
||||||
|
grpcEntry := rkgrpc.GetGrpcEntry("smart-search-service")
|
||||||
|
if grpcEntry == nil {
|
||||||
|
logger.Fatal("Failed to get gRPC entry from rk-boot")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
sessionRepo := repository.NewSessionRepository(pool)
|
sessionRepo := repository.NewSessionRepository(pool)
|
||||||
inviteRepo := repository.NewInviteRepository(pool)
|
inviteRepo := repository.NewInviteRepository(pool)
|
||||||
|
|
||||||
sessionCleaner := worker.NewSessionCleaner(ctx, sessionRepo)
|
sessionCleaner := worker.NewSessionCleaner(ctx, sessionRepo, logger)
|
||||||
sessionCleaner.Start()
|
sessionCleaner.Start()
|
||||||
defer sessionCleaner.Stop()
|
defer sessionCleaner.Stop()
|
||||||
|
|
||||||
inviteCleaner := worker.NewInviteCleaner(ctx, inviteRepo)
|
inviteCleaner := worker.NewInviteCleaner(ctx, inviteRepo, logger)
|
||||||
inviteCleaner.Start()
|
inviteCleaner.Start()
|
||||||
defer inviteCleaner.Stop()
|
defer inviteCleaner.Stop()
|
||||||
|
|
||||||
@@ -81,9 +83,9 @@ func main() {
|
|||||||
|
|
||||||
boot.Bootstrap(ctx)
|
boot.Bootstrap(ctx)
|
||||||
|
|
||||||
log.Println("gRPC server started via rk-boot")
|
logger.Info("gRPC server started via rk-boot")
|
||||||
|
|
||||||
boot.WaitForShutdownSig(ctx)
|
boot.WaitForShutdownSig(ctx)
|
||||||
|
|
||||||
log.Println("Server stopped gracefully")
|
logger.Info("Server stopped gracefully")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
---
|
---
|
||||||
logger:
|
logger:
|
||||||
- name: smart-search-logger
|
- name: smart-search-logger
|
||||||
description: "Application logger for smart-search service"
|
|
||||||
default: true
|
default: true
|
||||||
zap:
|
zap:
|
||||||
level: error
|
level: info
|
||||||
development: false
|
|
||||||
encoding: console
|
encoding: console
|
||||||
outputPaths: ["stdout"]
|
outputPaths: ["stdout"]
|
||||||
errorOutputPaths: ["stderr"]
|
errorOutputPaths: ["stderr"]
|
||||||
disableCaller: false
|
|
||||||
disableStacktrace: false
|
|
||||||
|
|
||||||
grpc:
|
grpc:
|
||||||
- name: smart-search-service
|
- name: smart-search-service
|
||||||
@@ -19,16 +15,17 @@ grpc:
|
|||||||
enableReflection: true
|
enableReflection: true
|
||||||
enableRkGwOption: true
|
enableRkGwOption: true
|
||||||
loggerEntry: smart-search-logger
|
loggerEntry: smart-search-logger
|
||||||
eventEntry: smart-search-logger
|
|
||||||
middleware:
|
middleware:
|
||||||
logging:
|
logging:
|
||||||
enabled: true
|
enabled: true
|
||||||
loggerEncoding: "console"
|
loggerEncoding: console
|
||||||
loggerOutputPaths: ["stdout"]
|
loggerOutputPaths: ["stdout"]
|
||||||
|
eventEncoding: console
|
||||||
|
eventOutputPaths: []
|
||||||
meta:
|
meta:
|
||||||
enabled: true
|
enabled: false
|
||||||
trace:
|
trace:
|
||||||
enabled: true
|
enabled: false
|
||||||
prometheus:
|
prometheus:
|
||||||
enabled: true
|
enabled: true
|
||||||
auth:
|
auth:
|
||||||
|
|||||||
3
go.mod
3
go.mod
@@ -17,6 +17,7 @@ require (
|
|||||||
github.com/testcontainers/testcontainers-go/modules/postgres v0.40.0
|
github.com/testcontainers/testcontainers-go/modules/postgres v0.40.0
|
||||||
github.com/xuri/excelize/v2 v2.10.0
|
github.com/xuri/excelize/v2 v2.10.0
|
||||||
go.uber.org/zap v1.27.1
|
go.uber.org/zap v1.27.1
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260114163908-3f89685c29c3
|
||||||
google.golang.org/grpc v1.78.0
|
google.golang.org/grpc v1.78.0
|
||||||
google.golang.org/protobuf v1.36.11
|
google.golang.org/protobuf v1.36.11
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
@@ -95,7 +96,6 @@ require (
|
|||||||
github.com/spf13/cast v1.10.0 // indirect
|
github.com/spf13/cast v1.10.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.10 // indirect
|
github.com/spf13/pflag v1.0.10 // indirect
|
||||||
github.com/spf13/viper v1.21.0 // indirect
|
github.com/spf13/viper v1.21.0 // indirect
|
||||||
github.com/stretchr/objx v0.5.2 // indirect
|
|
||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/tiendc/go-deepcopy v1.7.1 // indirect
|
github.com/tiendc/go-deepcopy v1.7.1 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||||
@@ -126,7 +126,6 @@ require (
|
|||||||
golang.org/x/sys v0.40.0 // indirect
|
golang.org/x/sys v0.40.0 // indirect
|
||||||
golang.org/x/text v0.33.0 // indirect
|
golang.org/x/text v0.33.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260114163908-3f89685c29c3 // indirect
|
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
nhooyr.io/websocket v1.8.6 // indirect
|
nhooyr.io/websocket v1.8.6 // indirect
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ import (
|
|||||||
|
|
||||||
_ "github.com/jackc/pgx/v5/stdlib"
|
_ "github.com/jackc/pgx/v5/stdlib"
|
||||||
"github.com/pressly/goose/v3"
|
"github.com/pressly/goose/v3"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RunMigrations(databaseURL string) error {
|
func RunMigrations(databaseURL string, logger *zap.Logger) error {
|
||||||
return RunMigrationsFromPath(databaseURL, "migrations")
|
return RunMigrationsFromPath(databaseURL, "migrations", logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunMigrationsFromPath(databaseURL, migrationsDir string) error {
|
func RunMigrationsFromPath(databaseURL, migrationsDir string, logger *zap.Logger) error {
|
||||||
db, err := sql.Open("pgx", databaseURL)
|
db, err := sql.Open("pgx", databaseURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open database connection for migrations: %w", err)
|
return fmt.Errorf("failed to open database connection for migrations: %w", err)
|
||||||
@@ -28,6 +29,8 @@ func RunMigrationsFromPath(databaseURL, migrationsDir string) error {
|
|||||||
return fmt.Errorf("failed to set goose dialect: %w", err)
|
return fmt.Errorf("failed to set goose dialect: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goose.SetLogger(&gooseLogger{logger: logger})
|
||||||
|
|
||||||
absPath, err := filepath.Abs(migrationsDir)
|
absPath, err := filepath.Abs(migrationsDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to resolve migrations path: %w", err)
|
return fmt.Errorf("failed to resolve migrations path: %w", err)
|
||||||
@@ -39,3 +42,15 @@ func RunMigrationsFromPath(databaseURL, migrationsDir string) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type gooseLogger struct {
|
||||||
|
logger *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *gooseLogger) Fatalf(format string, v ...interface{}) {
|
||||||
|
l.logger.Fatal(fmt.Sprintf(format, v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *gooseLogger) Printf(format string, v ...interface{}) {
|
||||||
|
l.logger.Info(fmt.Sprintf(format, v...))
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package worker
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"git.techease.ru/Smart-search/smart-search-back/internal/repository"
|
"git.techease.ru/Smart-search/smart-search-back/internal/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,13 +14,15 @@ type InviteCleaner struct {
|
|||||||
ctx context.Context
|
ctx context.Context
|
||||||
ticker *time.Ticker
|
ticker *time.Ticker
|
||||||
done chan bool
|
done chan bool
|
||||||
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInviteCleaner(ctx context.Context, inviteRepo repository.InviteRepository) *InviteCleaner {
|
func NewInviteCleaner(ctx context.Context, inviteRepo repository.InviteRepository, logger *zap.Logger) *InviteCleaner {
|
||||||
return &InviteCleaner{
|
return &InviteCleaner{
|
||||||
inviteRepo: inviteRepo,
|
inviteRepo: inviteRepo,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
done: make(chan bool),
|
done: make(chan bool),
|
||||||
|
logger: logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,13 +39,13 @@ func (w *InviteCleaner) Start() {
|
|||||||
case <-w.done:
|
case <-w.done:
|
||||||
return
|
return
|
||||||
case <-w.ctx.Done():
|
case <-w.ctx.Done():
|
||||||
log.Println("Invite cleaner context cancelled, stopping worker")
|
w.logger.Info("Invite cleaner context cancelled, stopping worker")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.Println("Invite cleaner worker started (runs every 6 hours)")
|
w.logger.Info("Invite cleaner worker started (runs every 6 hours)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *InviteCleaner) Stop() {
|
func (w *InviteCleaner) Stop() {
|
||||||
@@ -53,17 +56,17 @@ func (w *InviteCleaner) Stop() {
|
|||||||
case w.done <- true:
|
case w.done <- true:
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
log.Println("Invite cleaner worker stopped")
|
w.logger.Info("Invite cleaner worker stopped")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *InviteCleaner) deactivateExpiredInvites() {
|
func (w *InviteCleaner) deactivateExpiredInvites() {
|
||||||
count, err := w.inviteRepo.DeactivateExpired(w.ctx)
|
count, err := w.inviteRepo.DeactivateExpired(w.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error deactivating expired invites: %v", err)
|
w.logger.Error("Error deactivating expired invites", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
log.Printf("Deactivated %d expired invite codes", count)
|
w.logger.Info("Deactivated expired invite codes", zap.Int("count", count))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package worker
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"git.techease.ru/Smart-search/smart-search-back/internal/repository"
|
"git.techease.ru/Smart-search/smart-search-back/internal/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,13 +14,15 @@ type SessionCleaner struct {
|
|||||||
ctx context.Context
|
ctx context.Context
|
||||||
ticker *time.Ticker
|
ticker *time.Ticker
|
||||||
done chan bool
|
done chan bool
|
||||||
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSessionCleaner(ctx context.Context, sessionRepo repository.SessionRepository) *SessionCleaner {
|
func NewSessionCleaner(ctx context.Context, sessionRepo repository.SessionRepository, logger *zap.Logger) *SessionCleaner {
|
||||||
return &SessionCleaner{
|
return &SessionCleaner{
|
||||||
sessionRepo: sessionRepo,
|
sessionRepo: sessionRepo,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
done: make(chan bool),
|
done: make(chan bool),
|
||||||
|
logger: logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,13 +39,13 @@ func (w *SessionCleaner) Start() {
|
|||||||
case <-w.done:
|
case <-w.done:
|
||||||
return
|
return
|
||||||
case <-w.ctx.Done():
|
case <-w.ctx.Done():
|
||||||
log.Println("Session cleaner context cancelled, stopping worker")
|
w.logger.Info("Session cleaner context cancelled, stopping worker")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.Println("Session cleaner worker started (runs every hour)")
|
w.logger.Info("Session cleaner worker started (runs every hour)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SessionCleaner) Stop() {
|
func (w *SessionCleaner) Stop() {
|
||||||
@@ -53,17 +56,17 @@ func (w *SessionCleaner) Stop() {
|
|||||||
case w.done <- true:
|
case w.done <- true:
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
log.Println("Session cleaner worker stopped")
|
w.logger.Info("Session cleaner worker stopped")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SessionCleaner) cleanExpiredSessions() {
|
func (w *SessionCleaner) cleanExpiredSessions() {
|
||||||
count, err := w.sessionRepo.DeleteExpired(w.ctx)
|
count, err := w.sessionRepo.DeleteExpired(w.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error cleaning expired sessions: %v", err)
|
w.logger.Error("Error cleaning expired sessions", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
log.Printf("Cleaned %d expired sessions", count)
|
w.logger.Info("Cleaned expired sessions", zap.Int("count", count))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gojuno/minimock/v3"
|
"github.com/gojuno/minimock/v3"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"git.techease.ru/Smart-search/smart-search-back/internal/mocks"
|
"git.techease.ru/Smart-search/smart-search-back/internal/mocks"
|
||||||
)
|
)
|
||||||
@@ -17,6 +18,7 @@ type WorkerSuite struct {
|
|||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
ctrl *minimock.Controller
|
ctrl *minimock.Controller
|
||||||
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWorkerSuite(t *testing.T) {
|
func TestWorkerSuite(t *testing.T) {
|
||||||
@@ -26,6 +28,7 @@ func TestWorkerSuite(t *testing.T) {
|
|||||||
func (s *WorkerSuite) SetupTest() {
|
func (s *WorkerSuite) SetupTest() {
|
||||||
s.ctx, s.cancel = context.WithCancel(context.Background())
|
s.ctx, s.cancel = context.WithCancel(context.Background())
|
||||||
s.ctrl = minimock.NewController(s.T())
|
s.ctrl = minimock.NewController(s.T())
|
||||||
|
s.logger = zap.NewNop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WorkerSuite) TearDownTest() {
|
func (s *WorkerSuite) TearDownTest() {
|
||||||
@@ -42,7 +45,7 @@ func (s *WorkerSuite) TestSessionCleaner_StartStop() {
|
|||||||
return 5, nil
|
return 5, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
cleaner := NewSessionCleaner(s.ctx, sessionRepo)
|
cleaner := NewSessionCleaner(s.ctx, sessionRepo, s.logger)
|
||||||
|
|
||||||
cleaner.Start()
|
cleaner.Start()
|
||||||
|
|
||||||
@@ -62,7 +65,7 @@ func (s *WorkerSuite) TestSessionCleaner_ContextCancellation() {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
cleaner := NewSessionCleaner(s.ctx, sessionRepo)
|
cleaner := NewSessionCleaner(s.ctx, sessionRepo, s.logger)
|
||||||
|
|
||||||
cleaner.Start()
|
cleaner.Start()
|
||||||
|
|
||||||
@@ -84,7 +87,7 @@ func (s *WorkerSuite) TestInviteCleaner_StartStop() {
|
|||||||
return 3, nil
|
return 3, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
cleaner := NewInviteCleaner(s.ctx, inviteRepo)
|
cleaner := NewInviteCleaner(s.ctx, inviteRepo, s.logger)
|
||||||
|
|
||||||
cleaner.Start()
|
cleaner.Start()
|
||||||
|
|
||||||
@@ -104,7 +107,7 @@ func (s *WorkerSuite) TestInviteCleaner_ContextCancellation() {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
cleaner := NewInviteCleaner(s.ctx, inviteRepo)
|
cleaner := NewInviteCleaner(s.ctx, inviteRepo, s.logger)
|
||||||
|
|
||||||
cleaner.Start()
|
cleaner.Start()
|
||||||
|
|
||||||
@@ -124,7 +127,7 @@ func (s *WorkerSuite) TestSessionCleaner_ConcurrentStops() {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
cleaner := NewSessionCleaner(s.ctx, sessionRepo)
|
cleaner := NewSessionCleaner(s.ctx, sessionRepo, s.logger)
|
||||||
|
|
||||||
cleaner.Start()
|
cleaner.Start()
|
||||||
|
|
||||||
@@ -151,7 +154,7 @@ func (s *WorkerSuite) TestInviteCleaner_ConcurrentStops() {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
cleaner := NewInviteCleaner(s.ctx, inviteRepo)
|
cleaner := NewInviteCleaner(s.ctx, inviteRepo, s.logger)
|
||||||
|
|
||||||
cleaner.Start()
|
cleaner.Start()
|
||||||
|
|
||||||
@@ -180,7 +183,7 @@ func (s *WorkerSuite) TestSessionCleaner_MultipleStartStop() {
|
|||||||
return 2, nil
|
return 2, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
cleaner := NewSessionCleaner(s.ctx, sessionRepo)
|
cleaner := NewSessionCleaner(s.ctx, sessionRepo, s.logger)
|
||||||
|
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
cleaner.Start()
|
cleaner.Start()
|
||||||
@@ -200,7 +203,7 @@ func (s *WorkerSuite) TestInviteCleaner_MultipleStartStop() {
|
|||||||
return 1, nil
|
return 1, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
cleaner := NewInviteCleaner(s.ctx, inviteRepo)
|
cleaner := NewInviteCleaner(s.ctx, inviteRepo, s.logger)
|
||||||
|
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
cleaner.Start()
|
cleaner.Start()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
@@ -88,20 +89,31 @@ func ToGRPCError(err error, zapLogger *zap.Logger, method string) error {
|
|||||||
return status.Error(codes.Internal, "internal server error")
|
return status.Error(codes.Internal, "internal server error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var grpcCode codes.Code
|
||||||
switch appErr.Code {
|
switch appErr.Code {
|
||||||
case AuthInvalidCredentials, AuthMissing, AuthInvalidToken, RefreshInvalid:
|
case AuthInvalidCredentials, AuthMissing, AuthInvalidToken, RefreshInvalid:
|
||||||
return status.Error(codes.Unauthenticated, appErr.Message)
|
grpcCode = codes.Unauthenticated
|
||||||
case PermissionDenied:
|
case PermissionDenied:
|
||||||
return status.Error(codes.PermissionDenied, appErr.Message)
|
grpcCode = codes.PermissionDenied
|
||||||
case InviteLimitReached:
|
case InviteLimitReached:
|
||||||
return status.Error(codes.ResourceExhausted, appErr.Message)
|
grpcCode = codes.ResourceExhausted
|
||||||
case InsufficientBalance, InviteInvalidOrExpired:
|
case InsufficientBalance:
|
||||||
return status.Error(codes.FailedPrecondition, appErr.Message)
|
grpcCode = codes.FailedPrecondition
|
||||||
|
case InviteInvalidOrExpired:
|
||||||
|
grpcCode = codes.NotFound
|
||||||
case EmailAlreadyExists:
|
case EmailAlreadyExists:
|
||||||
return status.Error(codes.AlreadyExists, appErr.Message)
|
grpcCode = codes.AlreadyExists
|
||||||
case UserNotFound, RequestNotFound:
|
case UserNotFound, RequestNotFound:
|
||||||
return status.Error(codes.NotFound, appErr.Message)
|
grpcCode = codes.NotFound
|
||||||
default:
|
default:
|
||||||
return status.Error(codes.Unknown, appErr.Message)
|
grpcCode = codes.Unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
st, err := status.New(grpcCode, appErr.Message).WithDetails(&errdetails.ErrorInfo{
|
||||||
|
Reason: appErr.Code,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return status.Error(grpcCode, appErr.Message)
|
||||||
|
}
|
||||||
|
return st.Err()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ func (s *IntegrationSuite) TestAuthHandler_RegisterInvalidInviteCode() {
|
|||||||
|
|
||||||
st, ok := status.FromError(err)
|
st, ok := status.FromError(err)
|
||||||
s.True(ok)
|
s.True(ok)
|
||||||
s.Equal(codes.FailedPrecondition, st.Code())
|
s.Equal(codes.NotFound, st.Code())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *IntegrationSuite) TestAuthHandler_RegisterExpiredInviteCode() {
|
func (s *IntegrationSuite) TestAuthHandler_RegisterExpiredInviteCode() {
|
||||||
@@ -232,7 +232,7 @@ func (s *IntegrationSuite) TestAuthHandler_RegisterExpiredInviteCode() {
|
|||||||
|
|
||||||
st, ok := status.FromError(err)
|
st, ok := status.FromError(err)
|
||||||
s.True(ok)
|
s.True(ok)
|
||||||
s.Equal(codes.FailedPrecondition, st.Code())
|
s.Equal(codes.NotFound, st.Code())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *IntegrationSuite) TestAuthHandler_RegisterExhaustedInviteCode() {
|
func (s *IntegrationSuite) TestAuthHandler_RegisterExhaustedInviteCode() {
|
||||||
@@ -270,7 +270,7 @@ func (s *IntegrationSuite) TestAuthHandler_RegisterExhaustedInviteCode() {
|
|||||||
|
|
||||||
st, ok := status.FromError(err)
|
st, ok := status.FromError(err)
|
||||||
s.True(ok)
|
s.True(ok)
|
||||||
s.Equal(codes.FailedPrecondition, st.Code())
|
s.Equal(codes.NotFound, st.Code())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *IntegrationSuite) TestAuthHandler_RegisterDuplicateEmail() {
|
func (s *IntegrationSuite) TestAuthHandler_RegisterDuplicateEmail() {
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ func (s *IntegrationSuite) SetupSuite() {
|
|||||||
s.T().Logf("PostgreSQL connection string: %s", connStr)
|
s.T().Logf("PostgreSQL connection string: %s", connStr)
|
||||||
|
|
||||||
s.T().Log("Running migrations...")
|
s.T().Log("Running migrations...")
|
||||||
err = database.RunMigrationsFromPath(connStr, "../migrations")
|
logger, _ := zap.NewDevelopment()
|
||||||
|
err = database.RunMigrationsFromPath(connStr, "../migrations", logger)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
s.T().Log("Creating connection pool...")
|
s.T().Log("Creating connection pool...")
|
||||||
@@ -94,7 +95,6 @@ func (s *IntegrationSuite) SetupSuite() {
|
|||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
s.T().Log("Creating gRPC server...")
|
s.T().Log("Creating gRPC server...")
|
||||||
logger, _ := zap.NewDevelopment()
|
|
||||||
|
|
||||||
authHandler, userHandler, inviteHandler, requestHandler, supplierHandler := grpchandlers.NewHandlers(
|
authHandler, userHandler, inviteHandler, requestHandler, supplierHandler := grpchandlers.NewHandlers(
|
||||||
pool,
|
pool,
|
||||||
|
|||||||
Reference in New Issue
Block a user