forked from kyma-project/kyma
-
Notifications
You must be signed in to change notification settings - Fork 0
/
entity_operation.go
155 lines (117 loc) · 3.9 KB
/
entity_operation.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package memory
import (
"time"
"github.com/kyma-project/kyma/components/remote-environment-broker/internal"
"github.com/pkg/errors"
pTime "github.com/kyma-project/kyma/components/remote-environment-broker/platform/time"
)
// NewInstanceOperation returns new instance of InstanceOperation storage.
func NewInstanceOperation() *InstanceOperation {
return &InstanceOperation{
storage: make(map[internal.InstanceID]map[internal.OperationID]*internal.InstanceOperation),
}
}
// InstanceOperation implements in-memory storage InstanceOperation.
type InstanceOperation struct {
threadSafeStorage
storage map[internal.InstanceID]map[internal.OperationID]*internal.InstanceOperation
nowProvider pTime.NowProvider
}
// WithTimeProvider allows for passing custom time provider.
// Used mostly in testing.
func (s *InstanceOperation) WithTimeProvider(nowProvider func() time.Time) *InstanceOperation {
s.nowProvider = nowProvider
return s
}
// Insert inserts object into storage.
func (s *InstanceOperation) Insert(io *internal.InstanceOperation) error {
defer unlock(s.lockW())
if io == nil {
return errors.New("entity may not be nil")
}
if io.InstanceID.IsZero() || io.OperationID.IsZero() {
return errors.New("both instance and operation id must be set")
}
if _, found := s.storage[io.InstanceID]; !found {
s.storage[io.InstanceID] = make(map[internal.OperationID]*internal.InstanceOperation)
}
if _, found := s.storage[io.InstanceID][io.OperationID]; found {
return alreadyExistsError{}
}
for oID := range s.storage[io.InstanceID] {
if s.storage[io.InstanceID][oID].State == internal.OperationStateInProgress {
return activeOperationInProgressError{}
}
}
io.CreatedAt = s.nowProvider.Now()
s.storage[io.InstanceID][io.OperationID] = io
return nil
}
// Get returns object from storage.
func (s *InstanceOperation) Get(iID internal.InstanceID, opID internal.OperationID) (*internal.InstanceOperation, error) {
defer unlock(s.lockR())
return s.get(iID, opID)
}
func (s *InstanceOperation) get(iID internal.InstanceID, opID internal.OperationID) (*internal.InstanceOperation, error) {
if iID.IsZero() || opID.IsZero() {
return nil, errors.New("both instance and operation id must be set")
}
if _, found := s.storage[iID]; !found {
return nil, notFoundError{}
}
io, found := s.storage[iID][opID]
if !found {
return nil, notFoundError{}
}
return io, nil
}
// GetAll returns all objects from storage.
func (s *InstanceOperation) GetAll(iID internal.InstanceID) ([]*internal.InstanceOperation, error) {
defer unlock(s.lockR())
out := []*internal.InstanceOperation{}
opsForInstance, found := s.storage[iID]
if !found {
return nil, notFoundError{}
}
for i := range opsForInstance {
out = append(out, opsForInstance[i])
}
return out, nil
}
// UpdateState modifies state on object in storage.
func (s *InstanceOperation) UpdateState(iID internal.InstanceID, opID internal.OperationID, state internal.OperationState) error {
defer unlock(s.lockW())
op, err := s.get(iID, opID)
if err != nil {
return err
}
op.State = state
op.StateDescription = nil
//s.logStateChange(iID, opID, state, nil)
return nil
}
// UpdateStateDesc updates both state and description for single operation.
// If desc is nil than description will be removed.
func (s *InstanceOperation) UpdateStateDesc(iID internal.InstanceID, opID internal.OperationID, state internal.OperationState, desc *string) error {
defer unlock(s.lockW())
op, err := s.get(iID, opID)
if err != nil {
return err
}
op.State = state
op.StateDescription = desc
//s.logStateChange(iID, opID, state, desc)
return nil
}
// Remove removes object from storage.
func (s *InstanceOperation) Remove(iID internal.InstanceID, opID internal.OperationID) error {
defer unlock(s.lockW())
if _, err := s.get(iID, opID); err != nil {
return err
}
delete(s.storage[iID], opID)
if len(s.storage[iID]) == 0 {
delete(s.storage, iID)
}
return nil
}