github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/bundle/service.go (about) 1 package bundle 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/log" 9 10 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 11 12 "github.com/kyma-incubator/compass/components/director/internal/domain/tenant" 13 "github.com/kyma-incubator/compass/components/director/internal/model" 14 "github.com/pkg/errors" 15 ) 16 17 // BundleRepository missing godoc 18 // 19 //go:generate mockery --name=BundleRepository --output=automock --outpkg=automock --case=underscore --disable-version-string 20 type BundleRepository interface { 21 Create(ctx context.Context, tenant string, item *model.Bundle) error 22 CreateGlobal(ctx context.Context, model *model.Bundle) error 23 Update(ctx context.Context, tenant string, item *model.Bundle) error 24 UpdateGlobal(ctx context.Context, model *model.Bundle) error 25 Delete(ctx context.Context, tenant, id string) error 26 DeleteGlobal(ctx context.Context, id string) error 27 Exists(ctx context.Context, tenant, id string) (bool, error) 28 GetByID(ctx context.Context, tenant, id string) (*model.Bundle, error) 29 GetByIDGlobal(ctx context.Context, id string) (*model.Bundle, error) 30 GetForApplication(ctx context.Context, tenant string, id string, applicationID string) (*model.Bundle, error) 31 ListByResourceIDNoPaging(ctx context.Context, tenantID, appID string, resourceType resource.Type) ([]*model.Bundle, error) 32 ListByApplicationIDs(ctx context.Context, tenantID string, applicationIDs []string, pageSize int, cursor string) ([]*model.BundlePage, error) 33 } 34 35 // UIDService missing godoc 36 // 37 //go:generate mockery --name=UIDService --output=automock --outpkg=automock --case=underscore --disable-version-string 38 type UIDService interface { 39 Generate() string 40 } 41 42 type service struct { 43 bndlRepo BundleRepository 44 apiSvc APIService 45 eventSvc EventService 46 documentSvc DocumentService 47 48 uidService UIDService 49 } 50 51 // NewService missing godoc 52 func NewService(bndlRepo BundleRepository, apiSvc APIService, eventSvc EventService, documentSvc DocumentService, uidService UIDService) *service { 53 return &service{ 54 bndlRepo: bndlRepo, 55 apiSvc: apiSvc, 56 eventSvc: eventSvc, 57 documentSvc: documentSvc, 58 uidService: uidService, 59 } 60 } 61 62 // Create missing godoc 63 func (s *service) Create(ctx context.Context, resourceType resource.Type, resourceID string, in model.BundleCreateInput) (string, error) { 64 return s.CreateBundle(ctx, resourceType, resourceID, in, 0) 65 } 66 67 // CreateBundle Creates bundle for an application with given id 68 func (s *service) CreateBundle(ctx context.Context, resourceType resource.Type, resourceID string, in model.BundleCreateInput, bndlHash uint64) (string, error) { 69 id := s.uidService.Generate() 70 bndl := in.ToBundle(id, resourceType, resourceID, bndlHash) 71 72 if err := s.createBundle(ctx, bndl, resourceType); err != nil { 73 return "", errors.Wrapf(err, "error occurred while creating a Bundle with id %s and name %s for %s with id %s", id, bndl.Name, resourceType, resourceID) 74 } 75 76 log.C(ctx).Infof("Successfully created a Bundle with id %s and name %s for %s with id %s", id, bndl.Name, resourceType, resourceID) 77 78 log.C(ctx).Infof("Creating related resources in Bundle with id %s and name %s for %s with id %s", id, bndl.Name, resourceType, resourceID) 79 if err := s.createRelatedResources(ctx, in, id, resourceType, resourceID); err != nil { 80 return "", errors.Wrapf(err, "while creating related resources for %s with id %s", resourceType, resourceID) 81 } 82 83 return id, nil 84 } 85 86 // CreateMultiple missing godoc 87 func (s *service) CreateMultiple(ctx context.Context, resourceType resource.Type, resourceID string, in []*model.BundleCreateInput) error { 88 if in == nil { 89 return nil 90 } 91 92 for _, bndl := range in { 93 if bndl == nil { 94 continue 95 } 96 97 if _, err := s.Create(ctx, resourceType, resourceID, *bndl); err != nil { 98 return errors.Wrapf(err, "while creating Bundle for %s with id %s", resourceType, resourceID) 99 } 100 } 101 102 return nil 103 } 104 105 // Update missing godoc 106 func (s *service) Update(ctx context.Context, resourceType resource.Type, id string, in model.BundleUpdateInput) error { 107 return s.UpdateBundle(ctx, resourceType, id, in, 0) 108 } 109 110 // UpdateBundle missing godoc 111 func (s *service) UpdateBundle(ctx context.Context, resourceType resource.Type, id string, in model.BundleUpdateInput, bndlHash uint64) error { 112 bndl, err := s.getBundle(ctx, id, resourceType) 113 if err != nil { 114 return errors.Wrapf(err, "while getting Bundle with id %s", id) 115 } 116 117 bndl.SetFromUpdateInput(in, bndlHash) 118 119 if err = s.updateBundle(ctx, bndl, resourceType); err != nil { 120 return errors.Wrapf(err, "while updating Bundle with id %s", id) 121 } 122 123 return nil 124 } 125 126 // Delete deletes a bundle by id 127 func (s *service) Delete(ctx context.Context, resourceType resource.Type, id string) error { 128 if err := s.deleteBundle(ctx, id, resourceType); err != nil { 129 return errors.Wrapf(err, "while deleting Bundle with id %s", id) 130 } 131 132 log.C(ctx).Infof("Successfully deleted a bundle with ID %s", id) 133 134 return nil 135 } 136 137 // Exist missing godoc 138 func (s *service) Exist(ctx context.Context, id string) (bool, error) { 139 tnt, err := tenant.LoadFromContext(ctx) 140 if err != nil { 141 return false, errors.Wrap(err, "while loading tenant from context") 142 } 143 144 exist, err := s.bndlRepo.Exists(ctx, tnt, id) 145 if err != nil { 146 return false, errors.Wrapf(err, "while getting Bundle with ID: [%s]", id) 147 } 148 149 return exist, nil 150 } 151 152 // Get missing godoc 153 func (s *service) Get(ctx context.Context, id string) (*model.Bundle, error) { 154 tnt, err := tenant.LoadFromContext(ctx) 155 if err != nil { 156 return nil, errors.Wrap(err, "while loading tenant from context") 157 } 158 159 bndl, err := s.bndlRepo.GetByID(ctx, tnt, id) 160 if err != nil { 161 return nil, errors.Wrapf(err, "while getting Bundle with ID: [%s]", id) 162 } 163 164 return bndl, nil 165 } 166 167 // GetForApplication missing godoc 168 func (s *service) GetForApplication(ctx context.Context, id string, applicationID string) (*model.Bundle, error) { 169 tnt, err := tenant.LoadFromContext(ctx) 170 if err != nil { 171 return nil, err 172 } 173 174 bndl, err := s.bndlRepo.GetForApplication(ctx, tnt, id, applicationID) 175 if err != nil { 176 return nil, errors.Wrapf(err, "while getting Bundle with ID: [%s]", id) 177 } 178 179 return bndl, nil 180 } 181 182 // ListByApplicationIDNoPaging missing godoc 183 func (s *service) ListByApplicationIDNoPaging(ctx context.Context, appID string) ([]*model.Bundle, error) { 184 tnt, err := tenant.LoadFromContext(ctx) 185 if err != nil { 186 return nil, err 187 } 188 189 return s.bndlRepo.ListByResourceIDNoPaging(ctx, tnt, appID, resource.Application) 190 } 191 192 // ListByApplicationTemplateVersionIDNoPaging lists bundles by Application Template Version ID without tenant isolation 193 func (s *service) ListByApplicationTemplateVersionIDNoPaging(ctx context.Context, appTemplateVersionID string) ([]*model.Bundle, error) { 194 return s.bndlRepo.ListByResourceIDNoPaging(ctx, "", appTemplateVersionID, resource.ApplicationTemplateVersion) 195 } 196 197 // ListByApplicationIDs missing godoc 198 func (s *service) ListByApplicationIDs(ctx context.Context, applicationIDs []string, pageSize int, cursor string) ([]*model.BundlePage, error) { 199 tnt, err := tenant.LoadFromContext(ctx) 200 if err != nil { 201 return nil, err 202 } 203 204 if pageSize < 1 || pageSize > 200 { 205 return nil, apperrors.NewInvalidDataError("page size must be between 1 and 200") 206 } 207 208 return s.bndlRepo.ListByApplicationIDs(ctx, tnt, applicationIDs, pageSize, cursor) 209 } 210 211 func (s *service) createRelatedResources(ctx context.Context, in model.BundleCreateInput, bundleID string, resourceType resource.Type, resourceID string) error { 212 for i := range in.APIDefinitions { 213 if _, err := s.apiSvc.CreateInBundle(ctx, resourceType, resourceID, bundleID, *in.APIDefinitions[i], in.APISpecs[i]); err != nil { 214 return errors.Wrapf(err, "while creating APIs for bundle with id %q", bundleID) 215 } 216 } 217 218 for i := range in.EventDefinitions { 219 if _, err := s.eventSvc.CreateInBundle(ctx, resourceType, resourceID, bundleID, *in.EventDefinitions[i], in.EventSpecs[i]); err != nil { 220 return errors.Wrapf(err, "while creating Event for bundle with id %q", bundleID) 221 } 222 } 223 224 for _, document := range in.Documents { 225 if _, err := s.documentSvc.CreateInBundle(ctx, resourceType, resourceID, bundleID, *document); err != nil { 226 return errors.Wrapf(err, "while creating Document for bundle with id %q", bundleID) 227 } 228 } 229 230 return nil 231 } 232 233 func (s *service) createBundle(ctx context.Context, bundle *model.Bundle, resourceType resource.Type) error { 234 if resourceType.IsTenantIgnorable() { 235 return s.bndlRepo.CreateGlobal(ctx, bundle) 236 } 237 238 tnt, err := tenant.LoadFromContext(ctx) 239 if err != nil { 240 return err 241 } 242 243 return s.bndlRepo.Create(ctx, tnt, bundle) 244 } 245 246 func (s *service) getBundle(ctx context.Context, bundleID string, resourceType resource.Type) (*model.Bundle, error) { 247 if resourceType.IsTenantIgnorable() { 248 return s.bndlRepo.GetByIDGlobal(ctx, bundleID) 249 } 250 251 return s.Get(ctx, bundleID) 252 } 253 254 func (s *service) updateBundle(ctx context.Context, bndl *model.Bundle, resourceType resource.Type) error { 255 if resourceType.IsTenantIgnorable() { 256 return s.bndlRepo.UpdateGlobal(ctx, bndl) 257 } 258 259 tnt, err := tenant.LoadFromContext(ctx) 260 if err != nil { 261 return err 262 } 263 264 return s.bndlRepo.Update(ctx, tnt, bndl) 265 } 266 267 func (s *service) deleteBundle(ctx context.Context, bundleID string, resourceType resource.Type) error { 268 if resourceType.IsTenantIgnorable() { 269 return s.bndlRepo.DeleteGlobal(ctx, bundleID) 270 } 271 272 tnt, err := tenant.LoadFromContext(ctx) 273 if err != nil { 274 return err 275 } 276 277 return s.bndlRepo.Delete(ctx, tnt, bundleID) 278 }