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 }