[RIC-198]- No reassociations during e2t shutdown + fix tests
[ric-plt/e2mgr.git] / E2Manager / managers / e2t_instances_manager.go
1 //
2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 2019 Nokia
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //      http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 //  This source code is part of the near-RT RIC (RAN Intelligent Controller)
19 //  platform project (RICP).
20
21 package managers
22
23 import (
24         "e2mgr/e2managererrors"
25         "e2mgr/logger"
26         "e2mgr/services"
27         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
28         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
29         "math"
30         "sync"
31         "time"
32 )
33
34 type E2TInstancesManager struct {
35         rnibDataService services.RNibDataService
36         logger          *logger.Logger
37         mux             sync.Mutex
38 }
39
40 type IE2TInstancesManager interface {
41         GetE2TAddresses() ([]string, error)
42         GetE2TInstance(e2tAddress string) (*entities.E2TInstance, error)
43         GetE2TInstances() ([]*entities.E2TInstance, error)
44         GetE2TInstancesNoLogs() ([]*entities.E2TInstance, error)
45         AddE2TInstance(e2tAddress string) error
46         RemoveE2TInstance(e2tAddress string) error
47         SelectE2TInstance() (string, error)
48         AddRansToInstance(e2tAddress string, ranNames []string) error
49         RemoveRanFromInstance(ranName string, e2tAddress string) error
50         ResetKeepAliveTimestamp(e2tAddress string) error
51         ClearRansOfAllE2TInstances() error
52         SetE2tInstanceState(e2tAddress string, currentState entities.E2TInstanceState, newState entities.E2TInstanceState) error
53 }
54
55 func NewE2TInstancesManager(rnibDataService services.RNibDataService, logger *logger.Logger) *E2TInstancesManager {
56         return &E2TInstancesManager{
57                 rnibDataService: rnibDataService,
58                 logger:          logger,
59         }
60 }
61
62 func (m *E2TInstancesManager) GetE2TInstance(e2tAddress string) (*entities.E2TInstance, error) {
63         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
64
65         if err != nil {
66
67                 _, ok := err.(*common.ResourceNotFoundError)
68
69                 if !ok {
70                         m.logger.Errorf("#E2TInstancesManager.GetE2TInstance - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
71                 } else {
72                         m.logger.Infof("#E2TInstancesManager.GetE2TInstance - E2T Instance address: %s not found on DB", e2tAddress)
73                 }
74         }
75
76         return e2tInstance, err
77 }
78
79 func (m *E2TInstancesManager) GetE2TInstancesNoLogs() ([]*entities.E2TInstance, error) {
80         e2tAddresses, err := m.rnibDataService.GetE2TAddressesNoLogs()
81
82         if err != nil {
83                 _, ok := err.(*common.ResourceNotFoundError)
84
85                 if !ok {
86                         m.logger.Errorf("#E2TInstancesManager.GetE2TInstancesNoLogs - Failed retrieving E2T addresses. error: %s", err)
87                         return nil, e2managererrors.NewRnibDbError()
88                 }
89
90                 return []*entities.E2TInstance{}, nil
91         }
92
93         if len(e2tAddresses) == 0 {
94                 return []*entities.E2TInstance{}, nil
95         }
96
97         e2tInstances, err := m.rnibDataService.GetE2TInstancesNoLogs(e2tAddresses)
98
99         if err != nil {
100                 _, ok := err.(*common.ResourceNotFoundError)
101
102                 if !ok {
103                         m.logger.Errorf("#E2TInstancesManager.GetE2TInstancesNoLogs - Failed retrieving E2T instances list. error: %s", err)
104                 }
105                 return e2tInstances, err
106         }
107
108         return e2tInstances, nil
109 }
110
111 func (m *E2TInstancesManager) GetE2TAddresses() ([]string, error) {
112         e2tAddresses, err := m.rnibDataService.GetE2TAddresses()
113
114         if err != nil {
115
116                 _, ok := err.(*common.ResourceNotFoundError)
117
118                 if !ok {
119                         m.logger.Errorf("#E2TInstancesManager.GetE2TAddresses - Failed retrieving E2T addresses. error: %s", err)
120                         return nil, e2managererrors.NewRnibDbError()
121                 }
122
123         }
124
125         return e2tAddresses, nil
126 }
127
128 func (m *E2TInstancesManager) GetE2TInstances() ([]*entities.E2TInstance, error) {
129         e2tAddresses, err := m.GetE2TAddresses()
130
131         if err != nil {
132                 return nil, e2managererrors.NewRnibDbError()
133         }
134
135         if len(e2tAddresses) == 0 {
136                 m.logger.Infof("#E2TInstancesManager.GetE2TInstances - Empty E2T addresses list")
137                 return []*entities.E2TInstance{}, nil
138         }
139
140         e2tInstances, err := m.rnibDataService.GetE2TInstances(e2tAddresses)
141
142         if err != nil {
143                 m.logger.Errorf("#E2TInstancesManager.GetE2TInstances - Failed retrieving E2T instances list. error: %s", err)
144                 return e2tInstances, e2managererrors.NewRnibDbError()
145         }
146
147         if len(e2tInstances) == 0 {
148                 m.logger.Warnf("#E2TInstancesManager.GetE2TInstances - Empty E2T instances list")
149                 return e2tInstances, nil
150         }
151
152         return e2tInstances, nil
153 }
154
155 func (m *E2TInstancesManager) ResetKeepAliveTimestampsForAllE2TInstances() {
156
157         e2tInstances, err := m.GetE2TInstances()
158
159         if err != nil {
160                 m.logger.Errorf("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - Couldn't reset timestamps due to a DB error")
161                 return
162         }
163
164         if len(e2tInstances) == 0 {
165                 m.logger.Infof("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - No instances, ignoring reset")
166                 return
167         }
168
169         for _, v := range e2tInstances {
170
171                 if v.State != entities.Active {
172                         continue
173                 }
174
175                 v.KeepAliveTimestamp = time.Now().UnixNano()
176
177                 err := m.rnibDataService.SaveE2TInstance(v)
178
179                 if err != nil {
180                         m.logger.Errorf("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - E2T address: %s - failed resetting e2t instance keep alive timestamp. error: %s", v.Address, err)
181                 }
182         }
183
184         m.logger.Infof("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - Done with reset")
185 }
186
187 func findActiveE2TInstanceWithMinimumAssociatedRans(e2tInstances []*entities.E2TInstance) *entities.E2TInstance {
188         var minInstance *entities.E2TInstance
189         minAssociatedRanCount := math.MaxInt32
190
191         for _, v := range e2tInstances {
192                 if v.State == entities.Active && len(v.AssociatedRanList) < minAssociatedRanCount {
193                         minAssociatedRanCount = len(v.AssociatedRanList)
194                         minInstance = v
195                 }
196         }
197
198         return minInstance
199 }
200
201 func (m *E2TInstancesManager) AddE2TInstance(e2tAddress string) error {
202
203         m.mux.Lock()
204         defer m.mux.Unlock()
205
206         e2tInstance := entities.NewE2TInstance(e2tAddress)
207         err := m.rnibDataService.SaveE2TInstance(e2tInstance)
208
209         if err != nil {
210                 m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed saving E2T instance. error: %s", e2tInstance.Address, err)
211                 return err
212         }
213
214         e2tAddresses, err := m.rnibDataService.GetE2TAddresses()
215
216         if err != nil {
217
218                 _, ok := err.(*common.ResourceNotFoundError)
219
220                 if !ok {
221                         m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed retrieving E2T addresses list. error: %s", e2tInstance.Address, err)
222                         return err
223                 }
224         }
225
226         e2tAddresses = append(e2tAddresses, e2tInstance.Address)
227
228         err = m.rnibDataService.SaveE2TAddresses(e2tAddresses)
229
230         if err != nil {
231                 m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed saving E2T addresses list. error: %s", e2tInstance.Address, err)
232                 return err
233         }
234
235         m.logger.Infof("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - successfully added E2T instance", e2tInstance.Address)
236         return nil
237 }
238
239 func (m *E2TInstancesManager) RemoveRanFromInstance(ranName string, e2tAddress string) error {
240
241         m.mux.Lock()
242         defer m.mux.Unlock()
243
244         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
245
246         if err != nil {
247                 m.logger.Errorf("#E2TInstancesManager.RemoveRanFromInstance - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
248                 return e2managererrors.NewRnibDbError()
249         }
250
251         i := 0 // output index
252         for _, v := range e2tInstance.AssociatedRanList {
253                 if v != ranName {
254                         // copy and increment index
255                         e2tInstance.AssociatedRanList[i] = v
256                         i++
257                 }
258         }
259
260         e2tInstance.AssociatedRanList = e2tInstance.AssociatedRanList[:i]
261
262         err = m.rnibDataService.SaveE2TInstance(e2tInstance)
263
264         if err != nil {
265                 m.logger.Errorf("#E2TInstancesManager.RemoveRanFromInstance - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
266                 return e2managererrors.NewRnibDbError()
267         }
268
269         m.logger.Infof("#E2TInstancesManager.RemoveRanFromInstance - successfully dissociated RAN %s from E2T %s", ranName, e2tInstance.Address)
270         return nil
271 }
272
273 func (m *E2TInstancesManager) RemoveE2TInstance(e2tAddress string) error {
274         m.mux.Lock()
275         defer m.mux.Unlock()
276
277         err := m.rnibDataService.RemoveE2TInstance(e2tAddress)
278         if err != nil {
279                 m.logger.Errorf("#E2TInstancesManager.RemoveE2TInstance - E2T Instance address: %s - Failed removing E2TInstance. error: %s", e2tAddress, err)
280                 return e2managererrors.NewRnibDbError()
281         }
282
283         e2tAddresses, err := m.rnibDataService.GetE2TAddresses()
284
285         if err != nil {
286                 m.logger.Errorf("#E2TInstancesManager.RemoveE2TInstance - E2T Instance address: %s - Failed retrieving E2T addresses list. error: %s", e2tAddress, err)
287                 return e2managererrors.NewRnibDbError()
288         }
289
290         e2tAddresses = m.removeAddressFromList(e2tAddresses, e2tAddress)
291
292         err = m.rnibDataService.SaveE2TAddresses(e2tAddresses)
293         if err != nil {
294                 m.logger.Errorf("#E2TInstancesManager.RemoveE2TInstance - E2T Instance address: %s - Failed saving E2T addresses list. error: %s", e2tAddress, err)
295                 return e2managererrors.NewRnibDbError()
296         }
297
298         return nil
299 }
300
301 func (m *E2TInstancesManager) removeAddressFromList(e2tAddresses []string, addressToRemove string) []string {
302         newAddressList := []string{}
303
304         for _, address := range e2tAddresses {
305                 if address != addressToRemove {
306                         newAddressList = append(newAddressList, address)
307                 }
308         }
309
310         return newAddressList
311 }
312
313 func (m *E2TInstancesManager) SelectE2TInstance() (string, error) {
314
315         e2tInstances, err := m.GetE2TInstances()
316
317         if err != nil {
318                 return "", err
319         }
320
321         if len(e2tInstances) == 0 {
322                 m.logger.Errorf("#E2TInstancesManager.SelectE2TInstance - No E2T instance found")
323                 return "", e2managererrors.NewE2TInstanceAbsenceError()
324         }
325
326         min := findActiveE2TInstanceWithMinimumAssociatedRans(e2tInstances)
327
328         if min == nil {
329                 m.logger.Errorf("#E2TInstancesManager.SelectE2TInstance - No active E2T instance found")
330                 return "", e2managererrors.NewE2TInstanceAbsenceError()
331         }
332
333         m.logger.Infof("#E2TInstancesManager.SelectE2TInstance - successfully selected E2T instance. address: %s", min.Address)
334         return min.Address, nil
335 }
336
337 func (m *E2TInstancesManager) AddRansToInstance(e2tAddress string, ranNames []string) error {
338
339         m.mux.Lock()
340         defer m.mux.Unlock()
341
342         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
343
344         if err != nil {
345                 m.logger.Errorf("#E2TInstancesManager.AddRansToInstance - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
346                 return e2managererrors.NewRnibDbError()
347         }
348
349         e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, ranNames...)
350
351         err = m.rnibDataService.SaveE2TInstance(e2tInstance)
352
353         if err != nil {
354                 m.logger.Errorf("#E2TInstancesManager.AddRansToInstance - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
355                 return e2managererrors.NewRnibDbError()
356         }
357
358         m.logger.Infof("#E2TInstancesManager.AddRansToInstance - RAN %s were added successfully to E2T %s", ranNames, e2tInstance.Address)
359         return nil
360 }
361
362 func (m *E2TInstancesManager) ResetKeepAliveTimestamp(e2tAddress string) error {
363
364         m.mux.Lock()
365         defer m.mux.Unlock()
366
367         e2tInstance, err := m.rnibDataService.GetE2TInstanceNoLogs(e2tAddress)
368
369         if err != nil {
370                 m.logger.Errorf("#E2TInstancesManager.ResetKeepAliveTimestamp - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
371                 return err
372         }
373
374         if e2tInstance.State == entities.ToBeDeleted {
375                 m.logger.Warnf("#E2TInstancesManager.ResetKeepAliveTimestamp - Ignore. This Instance is about to be deleted")
376                 return nil
377
378         }
379
380         e2tInstance.KeepAliveTimestamp = time.Now().UnixNano()
381         err = m.rnibDataService.SaveE2TInstanceNoLogs(e2tInstance)
382
383         if err != nil {
384                 m.logger.Errorf("#E2TInstancesManager.ResetKeepAliveTimestamp - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
385                 return err
386         }
387
388         return nil
389 }
390
391 func (m *E2TInstancesManager) SetE2tInstanceState(e2tAddress string, currentState entities.E2TInstanceState, newState entities.E2TInstanceState) error {
392         m.mux.Lock()
393         defer m.mux.Unlock()
394
395         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
396
397         if err != nil {
398                 m.logger.Errorf("#E2TInstancesManager.SetE2tInstanceState - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
399                 return e2managererrors.NewRnibDbError()
400         }
401
402         if (currentState != e2tInstance.State) {
403                 m.logger.Warnf("#E2TInstancesManager.SetE2tInstanceState - E2T Instance address: %s - Current state is not: %s", e2tAddress, currentState)
404                 return e2managererrors.NewInternalError()
405         }
406
407         e2tInstance.State = newState
408         if (newState == entities.Active) {
409                 e2tInstance.KeepAliveTimestamp = time.Now().UnixNano()
410         }
411
412         err = m.rnibDataService.SaveE2TInstance(e2tInstance)
413         if err != nil {
414                 m.logger.Errorf("#E2TInstancesManager.SetE2tInstanceState - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tInstance.Address, err)
415                 return err
416         }
417
418         m.logger.Infof("#E2TInstancesManager.SetE2tInstanceState - E2T Instance address: %s - State change: %s --> %s", e2tAddress, currentState, newState)
419
420         return nil
421 }
422
423 func (m *E2TInstancesManager) ClearRansOfAllE2TInstances() error {
424         m.logger.Infof("#E2TInstancesManager.ClearRansOfAllE2TInstances - Going to clear associated RANs from E2T instances")
425         m.mux.Lock()
426         defer m.mux.Unlock()
427
428         e2tInstances, err := m.GetE2TInstances()
429
430         if err != nil {
431                 return err
432         }
433
434         if len(e2tInstances) == 0 {
435                 m.logger.Errorf("#E2TInstancesManager.ClearRansOfAllE2TInstances - No E2T instances to clear associated RANs from")
436                 return nil
437         }
438
439         for _, v := range e2tInstances {
440                 v.AssociatedRanList = []string{}
441                 err := m.rnibDataService.SaveE2TInstance(v)
442
443                 if err != nil {
444                         m.logger.Errorf("#E2TInstancesManager.ClearRansOfAllE2TInstances - e2t address: %s - failed saving e2t instance. error: %s", v.Address, err)
445                 }
446         }
447
448         return nil
449 }