github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/formationassignment/status_service.go (about) 1 package formationassignment 2 3 import ( 4 "context" 5 "encoding/json" 6 7 "github.com/kyma-incubator/compass/components/director/internal/domain/tenant" 8 "github.com/kyma-incubator/compass/components/director/internal/model" 9 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 10 "github.com/kyma-incubator/compass/components/director/pkg/formationconstraint" 11 "github.com/kyma-incubator/compass/components/director/pkg/log" 12 "github.com/kyma-incubator/compass/components/director/pkg/resource" 13 "github.com/pkg/errors" 14 ) 15 16 // formationAssignmentStatusService service encapsulates all the specifics around persisting the state reported by notification receiver for a formation assignment 17 type formationAssignmentStatusService struct { 18 repo FormationAssignmentRepository 19 constraintEngine constraintEngine 20 faNotificationService faNotificationService 21 } 22 23 // NewFormationAssignmentStatusService creates formation assignment status service 24 func NewFormationAssignmentStatusService(repo FormationAssignmentRepository, constraintEngine constraintEngine, faNotificationService faNotificationService) *formationAssignmentStatusService { 25 return &formationAssignmentStatusService{ 26 repo: repo, 27 constraintEngine: constraintEngine, 28 faNotificationService: faNotificationService, 29 } 30 } 31 32 // UpdateWithConstraints updates a Formation Assignment and enforces NotificationStatusReturned constraints before and after the update 33 func (fau *formationAssignmentStatusService) UpdateWithConstraints(ctx context.Context, fa *model.FormationAssignment, operation model.FormationOperation) error { 34 id := fa.ID 35 36 log.C(ctx).Infof("Updating formation assignment with ID: %q", id) 37 38 tenantID, err := tenant.LoadFromContext(ctx) 39 if err != nil { 40 return errors.Wrapf(err, "while loading tenant from context") 41 } 42 43 joinPointDetails, err := fau.faNotificationService.PrepareDetailsForNotificationStatusReturned(ctx, tenantID, fa, operation) 44 if err != nil { 45 return errors.Wrap(err, "while preparing details for NotificationStatusReturned") 46 } 47 joinPointDetails.Location = formationconstraint.PreNotificationStatusReturned 48 if err := fau.constraintEngine.EnforceConstraints(ctx, formationconstraint.PreNotificationStatusReturned, joinPointDetails, joinPointDetails.Formation.FormationTemplateID); err != nil { 49 return errors.Wrapf(err, "while enforcing constraints for target operation %q and constraint type %q", model.NotificationStatusReturned, model.PreOperation) 50 } 51 52 if exists, err := fau.repo.Exists(ctx, id, tenantID); err != nil { 53 return errors.Wrapf(err, "while ensuring formation assignment with ID: %q exists", id) 54 } else if !exists { 55 return apperrors.NewNotFoundError(resource.FormationAssignment, id) 56 } 57 58 if err = fau.repo.Update(ctx, fa); err != nil { 59 return errors.Wrapf(err, "while updating formation assignment with ID: %q", id) 60 } 61 62 joinPointDetails.Location = formationconstraint.PostNotificationStatusReturned 63 if err := fau.constraintEngine.EnforceConstraints(ctx, formationconstraint.PostNotificationStatusReturned, joinPointDetails, joinPointDetails.Formation.FormationTemplateID); err != nil { 64 return errors.Wrapf(err, "while enforcing constraints for target operation %q and constraint type %q", model.NotificationStatusReturned, model.PostOperation) 65 } 66 67 return nil 68 } 69 70 // SetAssignmentToErrorStateWithConstraints updates Formation Assignment state to error state using the errorMessage, errorCode and state parameters. 71 // Also, it enforces NotificationStatusReturned constraints before and after the update. 72 func (fau *formationAssignmentStatusService) SetAssignmentToErrorStateWithConstraints(ctx context.Context, assignment *model.FormationAssignment, errorMessage string, errorCode AssignmentErrorCode, state model.FormationAssignmentState, operation model.FormationOperation) error { 73 assignment.State = string(state) 74 assignmentError := AssignmentErrorWrapper{AssignmentError{ 75 Message: errorMessage, 76 ErrorCode: errorCode, 77 }} 78 marshaled, err := json.Marshal(assignmentError) 79 if err != nil { 80 return errors.Wrapf(err, "While preparing error message for assignment with ID %q", assignment.ID) 81 } 82 assignment.Value = marshaled 83 if err := fau.UpdateWithConstraints(ctx, assignment, operation); err != nil { 84 return errors.Wrapf(err, "While updating formation assignment with id %q", assignment.ID) 85 } 86 log.C(ctx).Infof("Assignment with ID %s set to state %s", assignment.ID, assignment.State) 87 return nil 88 } 89 90 // DeleteWithConstraints deletes a Formation Assignment matching ID `id` and enforces NotificationStatusReturned constraints before and after delete. 91 func (fau *formationAssignmentStatusService) DeleteWithConstraints(ctx context.Context, id string) error { 92 log.C(ctx).Infof("Deleting formation assignment with ID: %q", id) 93 94 tenantID, err := tenant.LoadFromContext(ctx) 95 if err != nil { 96 return errors.Wrapf(err, "while loading tenant from context") 97 } 98 99 fa, err := fau.repo.Get(ctx, id, tenantID) 100 if err != nil { 101 return errors.Wrapf(err, "while getting formation assignment with id %q for tenant with id %q", id, tenantID) 102 } 103 104 joinPointDetails, err := fau.faNotificationService.PrepareDetailsForNotificationStatusReturned(ctx, tenantID, fa, model.UnassignFormation) 105 if err != nil { 106 return errors.Wrap(err, "while preparing details for NotificationStatusReturned") 107 } 108 joinPointDetails.Location = formationconstraint.PreNotificationStatusReturned 109 if err = fau.constraintEngine.EnforceConstraints(ctx, formationconstraint.PreNotificationStatusReturned, joinPointDetails, joinPointDetails.Formation.FormationTemplateID); err != nil { 110 return errors.Wrapf(err, "while enforcing constraints for target operation %q and constraint type %q", model.NotificationStatusReturned, model.PreOperation) 111 } 112 113 if err = fau.repo.Delete(ctx, id, tenantID); err != nil { 114 return errors.Wrapf(err, "while deleting formation assignment with ID: %q", id) 115 } 116 117 joinPointDetails.Location = formationconstraint.PostNotificationStatusReturned 118 if err = fau.constraintEngine.EnforceConstraints(ctx, formationconstraint.PostNotificationStatusReturned, joinPointDetails, joinPointDetails.Formation.FormationTemplateID); err != nil { 119 return errors.Wrapf(err, "while enforcing constraints for target operation %q and constraint type %q", model.NotificationStatusReturned, model.PostOperation) 120 } 121 122 return nil 123 }