128 lines
3.5 KiB
Go
128 lines
3.5 KiB
Go
package callback
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"go.uber.org/zap"
|
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
|
)
|
|
|
|
type CallbackClient interface {
|
|
SendOnSuccess(ctx context.Context, host string, event *models.Event) errors.Error
|
|
SendOnFailure(ctx context.Context, host string, event *models.Event) errors.Error
|
|
}
|
|
|
|
type PaymentRepository interface {
|
|
SetPaymentComplete(ctx context.Context, paymentID string) (*models.Payment, errors.Error)
|
|
}
|
|
|
|
type Deps struct {
|
|
Logger *zap.Logger
|
|
CallbackClient CallbackClient
|
|
PaymentRepository PaymentRepository
|
|
}
|
|
|
|
type Service struct {
|
|
logger *zap.Logger
|
|
callbackClient CallbackClient
|
|
paymentRepository PaymentRepository
|
|
}
|
|
|
|
func New(deps Deps) (*Service, errors.Error) {
|
|
if deps.Logger == nil {
|
|
return nil, errors.NewWithMessage("logger is nil on <NewCallbackService>", errors.ErrInvalidArgs)
|
|
}
|
|
|
|
if deps.CallbackClient == nil {
|
|
return nil, errors.NewWithMessage("CallbackClient is nil on <NewCallbackService>", errors.ErrInvalidArgs)
|
|
}
|
|
|
|
if deps.PaymentRepository == nil {
|
|
return nil, errors.NewWithMessage("PaymentRepository is nil on <NewCallbackService>", errors.ErrInvalidArgs)
|
|
}
|
|
|
|
return &Service{
|
|
logger: deps.Logger,
|
|
callbackClient: deps.CallbackClient,
|
|
paymentRepository: deps.PaymentRepository,
|
|
}, nil
|
|
}
|
|
|
|
func (receiver *Service) OnSuccess(ctx context.Context, event *models.Event) errors.Error {
|
|
waitGroup := sync.WaitGroup{}
|
|
mutex := sync.Mutex{}
|
|
executeErrors := make([]error, 0)
|
|
|
|
for _, callbackURL := range event.Payment.CallbackHostGRPC {
|
|
waitGroup.Add(1)
|
|
|
|
go func(url string) {
|
|
defer waitGroup.Done()
|
|
|
|
if err := receiver.callbackClient.SendOnSuccess(ctx, url, event); err != nil {
|
|
receiver.logger.Error("failid to send callback on <OnSuccess> of <CallbackService>")
|
|
|
|
mutex.Lock()
|
|
executeErrors = append(executeErrors, err)
|
|
mutex.Unlock()
|
|
|
|
return
|
|
}
|
|
|
|
if _, err := receiver.paymentRepository.SetPaymentComplete(ctx, event.Payment.PaymentID); err != nil {
|
|
receiver.logger.Error("failid to set payment complete on <OnSuccess> of <CallbackService>")
|
|
|
|
mutex.Lock()
|
|
executeErrors = append(executeErrors, err)
|
|
mutex.Unlock()
|
|
|
|
return
|
|
}
|
|
}(callbackURL)
|
|
}
|
|
|
|
waitGroup.Wait()
|
|
|
|
if len(executeErrors) >= len(event.Payment.CallbackHostGRPC) {
|
|
receiver.logger.Error("failid to success payment on <OnSuccess> of <CallbackService>", zap.Errors("errors", executeErrors))
|
|
return errors.NewWithMessage("failed to success payment: all operations failed", errors.ErrInternalError)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (receiver *Service) OnFailure(ctx context.Context, event *models.Event) errors.Error {
|
|
waitGroup := sync.WaitGroup{}
|
|
mutex := sync.Mutex{}
|
|
executeErrors := make([]error, 0)
|
|
|
|
for _, callbackURL := range event.Payment.CallbackHostGRPC {
|
|
waitGroup.Add(1)
|
|
|
|
go func(url string) {
|
|
defer waitGroup.Done()
|
|
|
|
if err := receiver.callbackClient.SendOnFailure(ctx, url, event); err != nil {
|
|
receiver.logger.Error("failid to send callback on <OnFailure> of <CallbackService>")
|
|
|
|
mutex.Lock()
|
|
executeErrors = append(executeErrors, err)
|
|
mutex.Unlock()
|
|
|
|
return
|
|
}
|
|
}(callbackURL)
|
|
}
|
|
|
|
waitGroup.Wait()
|
|
|
|
if len(executeErrors) >= len(event.Payment.CallbackHostGRPC) {
|
|
receiver.logger.Error("failid to success payment on <OnFailure> of <CallbackService>", zap.Errors("errors", executeErrors))
|
|
return errors.NewWithMessage("failed to success payment: all operations failed", errors.ErrInternalError)
|
|
}
|
|
|
|
return nil
|
|
}
|