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  }