github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/webhook/resolver.go (about) 1 package webhook 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 8 9 "github.com/kyma-incubator/compass/components/director/pkg/persistence" 10 11 "github.com/pkg/errors" 12 13 "github.com/kyma-incubator/compass/components/director/internal/model" 14 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 15 ) 16 17 // WebhookService missing godoc 18 //go:generate mockery --name=WebhookService --output=automock --outpkg=automock --case=underscore --disable-version-string 19 type WebhookService interface { 20 Get(ctx context.Context, id string, objectType model.WebhookReferenceObjectType) (*model.Webhook, error) 21 ListAllApplicationWebhooks(ctx context.Context, applicationID string) ([]*model.Webhook, error) 22 ListForRuntime(ctx context.Context, runtimeID string) ([]*model.Webhook, error) 23 Create(ctx context.Context, resourceID string, in model.WebhookInput, objectType model.WebhookReferenceObjectType) (string, error) 24 Update(ctx context.Context, id string, in model.WebhookInput, objectType model.WebhookReferenceObjectType) error 25 Delete(ctx context.Context, id string, objectType model.WebhookReferenceObjectType) error 26 } 27 28 // ApplicationService missing godoc 29 //go:generate mockery --name=ApplicationService --output=automock --outpkg=automock --case=underscore --disable-version-string 30 type ApplicationService interface { 31 Exist(ctx context.Context, id string) (bool, error) 32 } 33 34 // ApplicationTemplateService missing godoc 35 //go:generate mockery --name=ApplicationTemplateService --output=automock --outpkg=automock --case=underscore --disable-version-string 36 type ApplicationTemplateService interface { 37 Exists(ctx context.Context, id string) (bool, error) 38 } 39 40 //go:generate mockery --exported --name=runtimeService --output=automock --outpkg=automock --case=underscore --disable-version-string 41 type runtimeService interface { 42 Exist(ctx context.Context, id string) (bool, error) 43 } 44 45 //go:generate mockery --exported --name=formationTemplateService --output=automock --outpkg=automock --case=underscore --disable-version-string 46 type formationTemplateService interface { 47 Exist(ctx context.Context, id string) (bool, error) 48 } 49 50 // WebhookConverter missing godoc 51 //go:generate mockery --name=WebhookConverter --output=automock --outpkg=automock --case=underscore --disable-version-string 52 type WebhookConverter interface { 53 ToGraphQL(in *model.Webhook) (*graphql.Webhook, error) 54 MultipleToGraphQL(in []*model.Webhook) ([]*graphql.Webhook, error) 55 InputFromGraphQL(in *graphql.WebhookInput) (*model.WebhookInput, error) 56 MultipleInputFromGraphQL(in []*graphql.WebhookInput) ([]*model.WebhookInput, error) 57 } 58 59 type existsFunc func(ctx context.Context, id string) (bool, error) 60 61 // Resolver missing godoc 62 type Resolver struct { 63 webhookSvc WebhookService 64 appSvc ApplicationService 65 appTemplateSvc ApplicationTemplateService 66 runtimeSvc runtimeService 67 formationTemplateSvc formationTemplateService 68 webhookConverter WebhookConverter 69 transact persistence.Transactioner 70 } 71 72 // NewResolver missing godoc 73 func NewResolver(transact persistence.Transactioner, webhookSvc WebhookService, applicationService ApplicationService, appTemplateService ApplicationTemplateService, runtimeService runtimeService, formationTemplateService formationTemplateService, webhookConverter WebhookConverter) *Resolver { 74 return &Resolver{ 75 webhookSvc: webhookSvc, 76 appSvc: applicationService, 77 appTemplateSvc: appTemplateService, 78 runtimeSvc: runtimeService, 79 formationTemplateSvc: formationTemplateService, 80 webhookConverter: webhookConverter, 81 transact: transact, 82 } 83 } 84 85 // AddWebhook missing godoc 86 func (r *Resolver) AddWebhook(ctx context.Context, applicationID *string, applicationTemplateID *string, runtimeID *string, formationTemplateID *string, in graphql.WebhookInput) (*graphql.Webhook, error) { 87 tx, err := r.transact.Begin() 88 if err != nil { 89 return nil, err 90 } 91 defer r.transact.RollbackUnlessCommitted(ctx, tx) 92 ctx = persistence.SaveToContext(ctx, tx) 93 94 appSpecified := applicationID != nil && applicationTemplateID == nil && runtimeID == nil && formationTemplateID == nil 95 appTemplateSpecified := applicationID == nil && applicationTemplateID != nil && runtimeID == nil && formationTemplateID == nil 96 runtimeSpecified := applicationID == nil && applicationTemplateID == nil && runtimeID != nil && formationTemplateID == nil 97 formationTemplateSpecified := applicationID == nil && applicationTemplateID == nil && runtimeID == nil && formationTemplateID != nil 98 99 if !(appSpecified || appTemplateSpecified || runtimeSpecified || formationTemplateSpecified) { 100 return nil, apperrors.NewInvalidDataError("exactly one of applicationID, applicationTemplateID, runtimeID or formationTemplateID should be specified") 101 } 102 103 convertedIn, err := r.webhookConverter.InputFromGraphQL(&in) 104 if err != nil { 105 return nil, errors.Wrap(err, "while converting the WebhookInput") 106 } 107 108 var objectID string 109 var objectType model.WebhookReferenceObjectType 110 if appSpecified { 111 objectID = *applicationID 112 objectType = model.ApplicationWebhookReference 113 } else if appTemplateSpecified { 114 objectID = *applicationTemplateID 115 objectType = model.ApplicationTemplateWebhookReference 116 } else if runtimeSpecified { 117 objectID = *runtimeID 118 objectType = model.RuntimeWebhookReference 119 } else if formationTemplateSpecified { 120 objectID = *formationTemplateID 121 objectType = model.FormationTemplateWebhookReference 122 } 123 124 id, err := r.checkForExistenceAndCreate(ctx, *convertedIn, objectID, objectType) 125 if err != nil { 126 return nil, err 127 } 128 129 webhook, err := r.webhookSvc.Get(ctx, id, objectType) 130 if err != nil { 131 return nil, err 132 } 133 134 if err := tx.Commit(); err != nil { 135 return nil, err 136 } 137 138 return r.webhookConverter.ToGraphQL(webhook) 139 } 140 141 // UpdateWebhook missing godoc 142 func (r *Resolver) UpdateWebhook(ctx context.Context, webhookID string, in graphql.WebhookInput) (*graphql.Webhook, error) { 143 tx, err := r.transact.Begin() 144 if err != nil { 145 return nil, err 146 } 147 defer r.transact.RollbackUnlessCommitted(ctx, tx) 148 ctx = persistence.SaveToContext(ctx, tx) 149 150 convertedIn, err := r.webhookConverter.InputFromGraphQL(&in) 151 if err != nil { 152 return nil, errors.Wrap(err, "while converting the WebhookInput") 153 } 154 155 err = r.webhookSvc.Update(ctx, webhookID, *convertedIn, model.UnknownWebhookReference) 156 if err != nil { 157 return nil, err 158 } 159 160 webhook, err := r.webhookSvc.Get(ctx, webhookID, model.UnknownWebhookReference) 161 if err != nil { 162 return nil, err 163 } 164 165 if err := tx.Commit(); err != nil { 166 return nil, err 167 } 168 169 return r.webhookConverter.ToGraphQL(webhook) 170 } 171 172 // DeleteWebhook missing godoc 173 func (r *Resolver) DeleteWebhook(ctx context.Context, webhookID string) (*graphql.Webhook, error) { 174 tx, err := r.transact.Begin() 175 if err != nil { 176 return nil, err 177 } 178 defer r.transact.RollbackUnlessCommitted(ctx, tx) 179 ctx = persistence.SaveToContext(ctx, tx) 180 181 webhook, err := r.webhookSvc.Get(ctx, webhookID, model.UnknownWebhookReference) 182 if err != nil { 183 return nil, err 184 } 185 186 deletedWebhook, err := r.webhookConverter.ToGraphQL(webhook) 187 if err != nil { 188 return nil, errors.Wrap(err, "while converting the Webhook model to GraphQL") 189 } 190 191 err = r.webhookSvc.Delete(ctx, webhookID, model.UnknownWebhookReference) 192 if err != nil { 193 return nil, err 194 } 195 196 if err := tx.Commit(); err != nil { 197 return nil, err 198 } 199 200 return deletedWebhook, nil 201 } 202 203 func (r *Resolver) checkForExistenceAndCreate(ctx context.Context, input model.WebhookInput, objectID string, objectType model.WebhookReferenceObjectType) (string, error) { 204 var ( 205 existsFunc existsFunc 206 ) 207 208 switch objectType { 209 case model.ApplicationWebhookReference: 210 existsFunc = r.appSvc.Exist 211 case model.ApplicationTemplateWebhookReference: 212 existsFunc = r.appTemplateSvc.Exists 213 case model.RuntimeWebhookReference: 214 existsFunc = r.runtimeSvc.Exist 215 case model.FormationTemplateWebhookReference: 216 existsFunc = r.formationTemplateSvc.Exist 217 } 218 219 err := r.genericCheckExistence(ctx, objectID, objectType, existsFunc) 220 if err != nil { 221 return "", err 222 } 223 return r.webhookSvc.Create(ctx, objectID, input, objectType) 224 } 225 226 func (r *Resolver) genericCheckExistence(ctx context.Context, resourceID string, objectType model.WebhookReferenceObjectType, existsFunc existsFunc) error { 227 found, err := existsFunc(ctx, resourceID) 228 if err != nil { 229 return errors.Wrapf(err, "while checking existence of %s", objectType) 230 } 231 232 if !found { 233 return apperrors.NewInvalidDataError(fmt.Sprintf("cannot add %s due to not existing reference entity", objectType)) 234 } 235 return nil 236 }