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

     1  package labeldef
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/kyma-incubator/compass/components/director/pkg/resource"
     7  
     8  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
     9  
    10  	"github.com/kyma-incubator/compass/components/director/internal/domain/tenant"
    11  	"github.com/kyma-incubator/compass/components/director/internal/model"
    12  	"github.com/kyma-incubator/compass/components/director/pkg/graphql"
    13  	"github.com/kyma-incubator/compass/components/director/pkg/persistence"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  // Resolver missing godoc
    18  type Resolver struct {
    19  	conv          ModelConverter
    20  	srv           Service
    21  	formationsSrv formationService
    22  	transactioner persistence.Transactioner
    23  }
    24  
    25  // NewResolver missing godoc
    26  func NewResolver(transactioner persistence.Transactioner, srv Service, formationSvc formationService, conv ModelConverter) *Resolver {
    27  	return &Resolver{
    28  		conv:          conv,
    29  		srv:           srv,
    30  		formationsSrv: formationSvc,
    31  		transactioner: transactioner,
    32  	}
    33  }
    34  
    35  // ModelConverter missing godoc
    36  //go:generate mockery --name=ModelConverter --output=automock --outpkg=automock --case=underscore --disable-version-string
    37  type ModelConverter interface {
    38  	// TODO: Use model.LabelDefinitionInput
    39  	FromGraphQL(input graphql.LabelDefinitionInput, tenant string) (model.LabelDefinition, error)
    40  	ToGraphQL(definition model.LabelDefinition) (graphql.LabelDefinition, error)
    41  }
    42  
    43  // Service missing godoc
    44  //go:generate mockery --name=Service --output=automock --outpkg=automock --case=underscore --disable-version-string
    45  type Service interface {
    46  	Get(ctx context.Context, tenant string, key string) (*model.LabelDefinition, error)
    47  	List(ctx context.Context, tenant string) ([]model.LabelDefinition, error)
    48  }
    49  
    50  //go:generate mockery --exported --name=formationService --output=automock --outpkg=automock --case=underscore --disable-version-string
    51  type formationService interface {
    52  	CreateFormation(ctx context.Context, tnt string, formation model.Formation, templateName string) (*model.Formation, error)
    53  	DeleteFormation(ctx context.Context, tnt string, formation model.Formation) (*model.Formation, error)
    54  }
    55  
    56  // CreateLabelDefinition missing godoc
    57  func (r *Resolver) CreateLabelDefinition(ctx context.Context, in graphql.LabelDefinitionInput) (*graphql.LabelDefinition, error) {
    58  	tnt, err := tenant.LoadFromContext(ctx)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	tx, err := r.transactioner.Begin()
    64  	if err != nil {
    65  		return nil, errors.Wrap(err, "while starting transaction")
    66  	}
    67  	defer r.transactioner.RollbackUnlessCommitted(ctx, tx)
    68  
    69  	ld, err := r.conv.FromGraphQL(in, tnt)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	ctx = persistence.SaveToContext(ctx, tx)
    75  
    76  	if _, err = r.srv.Get(ctx, tnt, ld.Key); err == nil {
    77  		return nil, apperrors.NewNotUniqueError(resource.LabelDefinition)
    78  	} else if !apperrors.IsNotFoundError(err) {
    79  		return nil, errors.Wrap(err, "while getting label definition")
    80  	}
    81  
    82  	formations, err := ParseFormationsFromSchema(ld.Schema)
    83  	if err != nil {
    84  		return nil, errors.Wrap(err, "while parsing schema")
    85  	}
    86  	for _, f := range formations {
    87  		if _, err := r.formationsSrv.CreateFormation(ctx, tnt, model.Formation{Name: f}, model.DefaultTemplateName); err != nil {
    88  			return nil, errors.Wrapf(err, "while creating formation with name %s", f)
    89  		}
    90  	}
    91  
    92  	labelDef, err := r.srv.Get(ctx, tnt, ld.Key)
    93  
    94  	if err != nil {
    95  		return nil, errors.Wrap(err, "while getting label definition")
    96  	}
    97  
    98  	out, err := r.conv.ToGraphQL(*labelDef)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  
   103  	if err := tx.Commit(); err != nil {
   104  		return nil, errors.Wrap(err, "while committing transaction")
   105  	}
   106  
   107  	return &out, nil
   108  }
   109  
   110  // LabelDefinitions missing godoc
   111  func (r *Resolver) LabelDefinitions(ctx context.Context) ([]*graphql.LabelDefinition, error) {
   112  	tnt, err := tenant.LoadFromContext(ctx)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  
   117  	tx, err := r.transactioner.Begin()
   118  	if err != nil {
   119  		return nil, errors.Wrap(err, "while starting transaction")
   120  	}
   121  	defer r.transactioner.RollbackUnlessCommitted(ctx, tx)
   122  	ctx = persistence.SaveToContext(ctx, tx)
   123  
   124  	defs, err := r.srv.List(ctx, tnt)
   125  	if err != nil {
   126  		return nil, errors.Wrap(err, "while listing Label Definitions")
   127  	}
   128  
   129  	if err := tx.Commit(); err != nil {
   130  		return nil, errors.Wrap(err, "while committing transaction")
   131  	}
   132  
   133  	out := make([]*graphql.LabelDefinition, 0, len(defs))
   134  	for _, def := range defs {
   135  		c, err := r.conv.ToGraphQL(def)
   136  		if err != nil {
   137  			return nil, err
   138  		}
   139  
   140  		out = append(out, &c)
   141  	}
   142  	return out, nil
   143  }
   144  
   145  // LabelDefinition missing godoc
   146  func (r *Resolver) LabelDefinition(ctx context.Context, key string) (*graphql.LabelDefinition, error) {
   147  	tnt, err := tenant.LoadFromContext(ctx)
   148  	if err != nil {
   149  		return nil, err
   150  	}
   151  
   152  	tx, err := r.transactioner.Begin()
   153  	if err != nil {
   154  		return nil, errors.Wrap(err, "while starting transaction")
   155  	}
   156  	defer r.transactioner.RollbackUnlessCommitted(ctx, tx)
   157  	ctx = persistence.SaveToContext(ctx, tx)
   158  	def, err := r.srv.Get(ctx, tnt, key)
   159  
   160  	if err != nil {
   161  		if apperrors.IsNotFoundError(err) {
   162  			return nil, tx.Commit()
   163  		}
   164  		return nil, errors.Wrap(err, "while getting Label Definition")
   165  	}
   166  	if err := tx.Commit(); err != nil {
   167  		return nil, errors.Wrap(err, "while committing transaction")
   168  	}
   169  	if def == nil {
   170  		return nil, apperrors.NewNotFoundError(resource.LabelDefinition, key)
   171  	}
   172  	c, err := r.conv.ToGraphQL(*def)
   173  	if err != nil {
   174  		return nil, err
   175  	}
   176  	return &c, nil
   177  }
   178  
   179  // UpdateLabelDefinition missing godoc
   180  func (r *Resolver) UpdateLabelDefinition(ctx context.Context, in graphql.LabelDefinitionInput) (*graphql.LabelDefinition, error) {
   181  	tnt, err := tenant.LoadFromContext(ctx)
   182  	if err != nil {
   183  		return nil, err
   184  	}
   185  
   186  	tx, err := r.transactioner.Begin()
   187  	if err != nil {
   188  		return nil, errors.Wrap(err, "while starting transaction")
   189  	}
   190  	defer r.transactioner.RollbackUnlessCommitted(ctx, tx)
   191  
   192  	ctx = persistence.SaveToContext(ctx, tx)
   193  
   194  	ld, err := r.conv.FromGraphQL(in, tnt)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  
   199  	storedLd, err := r.srv.Get(ctx, tnt, ld.Key)
   200  	if err != nil {
   201  		return nil, errors.Wrap(err, "while receiving stored label definition")
   202  	}
   203  
   204  	inputFormations, err := ParseFormationsFromSchema(ld.Schema)
   205  	if err != nil {
   206  		return nil, errors.Wrap(err, "while parsing schema")
   207  	}
   208  	inputFormationsMap := make(map[string]struct{}, len(inputFormations))
   209  	for _, f := range inputFormations {
   210  		inputFormationsMap[f] = struct{}{}
   211  	}
   212  
   213  	storedFormations, err := ParseFormationsFromSchema(storedLd.Schema)
   214  	if err != nil {
   215  		return nil, errors.Wrap(err, "while parsing schema")
   216  	}
   217  
   218  	storedFormationsMap := make(map[string]struct{}, len(storedFormations))
   219  	for _, f := range storedFormations {
   220  		storedFormationsMap[f] = struct{}{}
   221  	}
   222  
   223  	for _, f := range inputFormations {
   224  		if _, ok := storedFormationsMap[f]; !ok {
   225  			if _, err := r.formationsSrv.CreateFormation(ctx, tnt, model.Formation{Name: f}, model.DefaultTemplateName); err != nil {
   226  				return nil, errors.Wrapf(err, "while creating formation with name %s", f)
   227  			}
   228  		}
   229  	}
   230  
   231  	for _, f := range storedFormations {
   232  		if _, ok := inputFormationsMap[f]; !ok {
   233  			if _, err := r.formationsSrv.DeleteFormation(ctx, tnt, model.Formation{Name: f}); err != nil {
   234  				return nil, errors.Wrapf(err, "while deleting formation with name %s", f)
   235  			}
   236  		}
   237  	}
   238  
   239  	updatedLd, err := r.srv.Get(ctx, tnt, in.Key)
   240  	if err != nil {
   241  		return nil, errors.Wrap(err, "while receiving updated label definition")
   242  	}
   243  
   244  	out, err := r.conv.ToGraphQL(*updatedLd)
   245  	if err != nil {
   246  		return nil, err
   247  	}
   248  
   249  	if err := tx.Commit(); err != nil {
   250  		return nil, errors.Wrap(err, "while committing transaction")
   251  	}
   252  
   253  	return &out, nil
   254  }