-
Notifications
You must be signed in to change notification settings - Fork 84
/
package.go
104 lines (89 loc) · 3.96 KB
/
package.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package processor
import (
"context"
"github.com/kyma-incubator/compass/components/director/internal/model"
"github.com/kyma-incubator/compass/components/director/pkg/persistence"
"github.com/kyma-incubator/compass/components/director/pkg/resource"
"github.com/pkg/errors"
)
// PackageService is responsible for the service-layer Package operations.
//
//go:generate mockery --name=PackageService --output=automock --outpkg=automock --case=underscore --disable-version-string
type PackageService interface {
Create(ctx context.Context, resourceType resource.Type, resourceID string, in model.PackageInput, pkgHash uint64) (string, error)
Update(ctx context.Context, resourceType resource.Type, id string, in model.PackageInput, pkgHash uint64) error
Delete(ctx context.Context, resourceType resource.Type, id string) error
ListByApplicationID(ctx context.Context, appID string) ([]*model.Package, error)
ListByApplicationTemplateVersionID(ctx context.Context, appTemplateVersionID string) ([]*model.Package, error)
}
// PackageProcessor defines package processor
type PackageProcessor struct {
transact persistence.Transactioner
packageSvc PackageService
}
// NewPackageProcessor creates new instance of PackageProcessor
func NewPackageProcessor(transact persistence.Transactioner, packageSvc PackageService) *PackageProcessor {
return &PackageProcessor{
transact: transact,
packageSvc: packageSvc,
}
}
// Process re-syncs the packages passed as an argument.
func (pp *PackageProcessor) Process(ctx context.Context, resourceType resource.Type, resourceID string, packages []*model.PackageInput, resourceHashes map[string]uint64) ([]*model.Package, error) {
packagesFromDB, err := pp.listPackagesInTx(ctx, resourceType, resourceID)
if err != nil {
return nil, err
}
for _, pkg := range packages {
pkgHash := resourceHashes[pkg.OrdID]
if err := pp.resyncPackageInTx(ctx, resourceType, resourceID, packagesFromDB, pkg, pkgHash); err != nil {
return nil, err
}
}
packagesFromDB, err = pp.listPackagesInTx(ctx, resourceType, resourceID)
if err != nil {
return nil, err
}
return packagesFromDB, nil
}
func (pp *PackageProcessor) listPackagesInTx(ctx context.Context, resourceType resource.Type, resourceID string) ([]*model.Package, error) {
tx, err := pp.transact.Begin()
if err != nil {
return nil, err
}
defer pp.transact.RollbackUnlessCommitted(ctx, tx)
ctx = persistence.SaveToContext(ctx, tx)
var packagesFromDB []*model.Package
switch resourceType {
case resource.Application:
packagesFromDB, err = pp.packageSvc.ListByApplicationID(ctx, resourceID)
case resource.ApplicationTemplateVersion:
packagesFromDB, err = pp.packageSvc.ListByApplicationTemplateVersionID(ctx, resourceID)
}
if err != nil {
return nil, errors.Wrapf(err, "error while listing packages for %s with id %q", resourceType, resourceID)
}
return packagesFromDB, tx.Commit()
}
func (pp *PackageProcessor) resyncPackageInTx(ctx context.Context, resourceType resource.Type, resourceID string, packagesFromDB []*model.Package, pkg *model.PackageInput, pkgHash uint64) error {
tx, err := pp.transact.Begin()
if err != nil {
return err
}
defer pp.transact.RollbackUnlessCommitted(ctx, tx)
ctx = persistence.SaveToContext(ctx, tx)
if err := pp.resyncPackage(ctx, resourceType, resourceID, packagesFromDB, *pkg, pkgHash); err != nil {
return errors.Wrapf(err, "error while resyncing package with ORD ID %q", pkg.OrdID)
}
return tx.Commit()
}
func (pp *PackageProcessor) resyncPackage(ctx context.Context, resourceType resource.Type, resourceID string, packagesFromDB []*model.Package, pkg model.PackageInput, pkgHash uint64) error {
ctx = addFieldToLogger(ctx, "package_ord_id", pkg.OrdID)
if i, found := searchInSlice(len(packagesFromDB), func(i int) bool {
return packagesFromDB[i].OrdID == pkg.OrdID
}); found {
return pp.packageSvc.Update(ctx, resourceType, packagesFromDB[i].ID, pkg, pkgHash)
}
_, err := pp.packageSvc.Create(ctx, resourceType, resourceID, pkg, pkgHash)
return err
}