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 }