github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/formationtemplate/service.go (about)

     1  package formationtemplate
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/kyma-incubator/compass/components/director/internal/model"
     7  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
     8  	"github.com/kyma-incubator/compass/components/director/pkg/log"
     9  	"github.com/kyma-incubator/compass/components/director/pkg/resource"
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  // FormationTemplateRepository represents the FormationTemplate repository layer
    14  //go:generate mockery --name=FormationTemplateRepository --output=automock --outpkg=automock --case=underscore --disable-version-string
    15  type FormationTemplateRepository interface {
    16  	Create(ctx context.Context, item *model.FormationTemplate) error
    17  	Get(ctx context.Context, id string) (*model.FormationTemplate, error)
    18  	List(ctx context.Context, tenantID string, pageSize int, cursor string) (*model.FormationTemplatePage, error)
    19  	Update(ctx context.Context, model *model.FormationTemplate) error
    20  	Delete(ctx context.Context, id, tenantID string) error
    21  	Exists(ctx context.Context, id string) (bool, error)
    22  }
    23  
    24  // UIDService generates UUIDs for new entities
    25  //go:generate mockery --name=UIDService --output=automock --outpkg=automock --case=underscore --disable-version-string
    26  type UIDService interface {
    27  	Generate() string
    28  }
    29  
    30  // TenantService is responsible for service-layer tenant operations
    31  //go:generate mockery --name=TenantService --output=automock --outpkg=automock --case=underscore --disable-version-string
    32  type TenantService interface {
    33  	ExtractTenantIDForTenantScopedFormationTemplates(ctx context.Context) (string, error)
    34  }
    35  
    36  // WebhookRepository is responsible for repo-layer Webhook operations
    37  //go:generate mockery --name=WebhookRepository --output=automock --outpkg=automock --case=underscore --disable-version-string
    38  type WebhookRepository interface {
    39  	CreateMany(ctx context.Context, tenant string, items []*model.Webhook) error
    40  }
    41  
    42  // WebhookService represents the Webhook service layer
    43  //go:generate mockery --name=WebhookService --output=automock --outpkg=automock --case=underscore --disable-version-string
    44  type WebhookService interface {
    45  	ListForFormationTemplate(ctx context.Context, tenant, formationTemplateID string) ([]*model.Webhook, error)
    46  }
    47  
    48  type service struct {
    49  	repo           FormationTemplateRepository
    50  	uidSvc         UIDService
    51  	converter      FormationTemplateConverter
    52  	tenantSvc      TenantService
    53  	webhookRepo    WebhookRepository
    54  	webhookService WebhookService
    55  }
    56  
    57  // NewService creates a FormationTemplate service
    58  func NewService(repo FormationTemplateRepository, uidSvc UIDService, converter FormationTemplateConverter, tenantSvc TenantService, webhookRepo WebhookRepository, webhookService WebhookService) *service {
    59  	return &service{
    60  		repo:           repo,
    61  		uidSvc:         uidSvc,
    62  		converter:      converter,
    63  		tenantSvc:      tenantSvc,
    64  		webhookRepo:    webhookRepo,
    65  		webhookService: webhookService,
    66  	}
    67  }
    68  
    69  // Create creates a FormationTemplate using `in`
    70  func (s *service) Create(ctx context.Context, in *model.FormationTemplateInput) (string, error) {
    71  	formationTemplateID := s.uidSvc.Generate()
    72  
    73  	if in != nil {
    74  		log.C(ctx).Debugf("ID %s generated for Formation Template with name %s", formationTemplateID, in.Name)
    75  	}
    76  
    77  	tenantID, err := s.tenantSvc.ExtractTenantIDForTenantScopedFormationTemplates(ctx)
    78  	if err != nil {
    79  		return "", err
    80  	}
    81  
    82  	formationTemplateModel := s.converter.FromModelInputToModel(in, formationTemplateID, tenantID)
    83  
    84  	err = s.repo.Create(ctx, formationTemplateModel)
    85  	if err != nil {
    86  		return "", errors.Wrapf(err, "while creating Formation Template with name %s", in.Name)
    87  	}
    88  
    89  	if err = s.webhookRepo.CreateMany(ctx, tenantID, formationTemplateModel.Webhooks); err != nil {
    90  		return "", errors.Wrapf(err, "while creating Webhooks for Formation Template with ID: %s", formationTemplateID)
    91  	}
    92  
    93  	return formationTemplateID, nil
    94  }
    95  
    96  func (s *service) Exist(ctx context.Context, id string) (bool, error) {
    97  	return s.repo.Exists(ctx, id)
    98  }
    99  
   100  // Get queries FormationTemplate matching ID `id`
   101  func (s *service) Get(ctx context.Context, id string) (*model.FormationTemplate, error) {
   102  	formationTemplate, err := s.repo.Get(ctx, id)
   103  	if err != nil {
   104  		return nil, errors.Wrapf(err, "while getting Formation Template with id %s", id)
   105  	}
   106  
   107  	return formationTemplate, nil
   108  }
   109  
   110  // List pagination lists FormationTemplate based on `pageSize` and `cursor`
   111  func (s *service) List(ctx context.Context, pageSize int, cursor string) (*model.FormationTemplatePage, error) {
   112  	if pageSize < 1 || pageSize > 200 {
   113  		return nil, apperrors.NewInvalidDataError("page size must be between 1 and 200")
   114  	}
   115  
   116  	tenantID, err := s.tenantSvc.ExtractTenantIDForTenantScopedFormationTemplates(ctx)
   117  	if err != nil {
   118  		return nil, err
   119  	}
   120  
   121  	return s.repo.List(ctx, tenantID, pageSize, cursor)
   122  }
   123  
   124  // Update updates a FormationTemplate matching ID `id` using `in`
   125  func (s *service) Update(ctx context.Context, id string, in *model.FormationTemplateInput) error {
   126  	exists, err := s.repo.Exists(ctx, id)
   127  	if err != nil {
   128  		return errors.Wrapf(err, "while ensuring Formation Template with ID %s exists", id)
   129  	} else if !exists {
   130  		return apperrors.NewNotFoundError(resource.FormationTemplate, id)
   131  	}
   132  
   133  	tenantID, err := s.tenantSvc.ExtractTenantIDForTenantScopedFormationTemplates(ctx)
   134  	if err != nil {
   135  		return err
   136  	}
   137  
   138  	err = s.repo.Update(ctx, s.converter.FromModelInputToModel(in, id, tenantID))
   139  	if err != nil {
   140  		return errors.Wrapf(err, "while updating Formation Template with ID %s", id)
   141  	}
   142  
   143  	return nil
   144  }
   145  
   146  // Delete deletes a FormationTemplate matching ID `id`
   147  func (s *service) Delete(ctx context.Context, id string) error {
   148  	tenantID, err := s.tenantSvc.ExtractTenantIDForTenantScopedFormationTemplates(ctx)
   149  	if err != nil {
   150  		return err
   151  	}
   152  
   153  	if err := s.repo.Delete(ctx, id, tenantID); err != nil {
   154  		return errors.Wrapf(err, "while deleting Formation Template with ID %s", id)
   155  	}
   156  
   157  	return nil
   158  }
   159  
   160  // ListWebhooksForFormationTemplate lists webhooks for a FormationTemplate matching ID `formationTemplateID`
   161  func (s *service) ListWebhooksForFormationTemplate(ctx context.Context, formationTemplateID string) ([]*model.Webhook, error) {
   162  	tenantID, err := s.tenantSvc.ExtractTenantIDForTenantScopedFormationTemplates(ctx)
   163  	if err != nil {
   164  		return nil, err
   165  	}
   166  
   167  	return s.webhookService.ListForFormationTemplate(ctx, tenantID, formationTemplateID)
   168  }