[RICPLT-2590] US completion........
[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(e2tInstance *entities.E2TInstance) error
47         SelectE2TInstance() (string, error)
48         AddRanToInstance(ranName string, e2tAddress string) error
49         RemoveRanFromInstance(ranName string, e2tAddress string) error
50         ActivateE2TInstance(e2tInstance *entities.E2TInstance) error
51         ResetKeepAliveTimestamp(e2tAddress string) error
52         ClearRansOfAllE2TInstances() 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(e2tInstance *entities.E2TInstance) error {
274         return nil
275 }
276 func (m *E2TInstancesManager) SelectE2TInstance() (string, error) {
277
278         e2tInstances, err := m.GetE2TInstances()
279
280         if err != nil {
281                 return "", err
282         }
283
284         if len(e2tInstances) == 0 {
285                 m.logger.Errorf("#E2TInstancesManager.SelectE2TInstance - No E2T instance found")
286                 return "", e2managererrors.NewE2TInstanceAbsenceError()
287         }
288
289         min := findActiveE2TInstanceWithMinimumAssociatedRans(e2tInstances)
290
291         if min == nil {
292                 m.logger.Errorf("#E2TInstancesManager.SelectE2TInstance - No active E2T instance found")
293                 return "", e2managererrors.NewE2TInstanceAbsenceError()
294         }
295
296         m.logger.Infof("#E2TInstancesManager.SelectE2TInstance - successfully selected E2T instance. address: %s", min.Address)
297         return min.Address, nil
298 }
299
300 func (m *E2TInstancesManager) AddRanToInstance(ranName string, e2tAddress string) error {
301
302         m.mux.Lock()
303         defer m.mux.Unlock()
304
305         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
306
307         if err != nil {
308                 m.logger.Errorf("#E2TInstancesManager.AddRanToInstance - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
309                 return e2managererrors.NewRnibDbError()
310         }
311
312         e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, ranName)
313
314         err = m.rnibDataService.SaveE2TInstance(e2tInstance)
315
316         if err != nil {
317                 m.logger.Errorf("#E2TInstancesManager.AddRanToInstance - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
318                 return e2managererrors.NewRnibDbError()
319         }
320
321         m.logger.Infof("#E2TInstancesManager.AddRanToInstance - RAN %s was added successfully to E2T %s", ranName, e2tInstance.Address)
322         return nil
323 }
324
325 func (m E2TInstancesManager) ActivateE2TInstance(e2tInstance *entities.E2TInstance) error {
326
327         if e2tInstance == nil {
328                 m.logger.Errorf("#E2TInstancesManager.ActivateE2TInstance - e2tInstance empty")
329                 return e2managererrors.NewInternalError()
330         }
331
332         m.logger.Infof("#E2TInstancesManager.ActivateE2TInstance - E2T Address: %s - activate E2T instance", e2tInstance.Address)
333
334         e2tInstance.State = entities.Active
335         e2tInstance.KeepAliveTimestamp = time.Now().UnixNano()
336
337         err := m.rnibDataService.SaveE2TInstance(e2tInstance)
338         if err != nil {
339                 m.logger.Errorf("#E2TInstancesManager.ActivateE2TInstance - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tInstance.Address, err)
340                 return err
341         }
342         return nil
343 }
344
345 func (m *E2TInstancesManager) ResetKeepAliveTimestamp(e2tAddress string) error {
346
347         m.mux.Lock()
348         defer m.mux.Unlock()
349
350         e2tInstance, err := m.rnibDataService.GetE2TInstanceNoLogs(e2tAddress)
351
352         if err != nil {
353                 m.logger.Errorf("#E2TInstancesManager.ResetKeepAliveTimestamp - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
354                 return err
355         }
356
357         if e2tInstance.State == entities.ToBeDeleted || e2tInstance.State == entities.RoutingManagerFailure {
358                 m.logger.Warnf("#E2TInstancesManager.ResetKeepAliveTimestamp - Ignore. This Instance is about to deleted")
359                 return nil
360
361         }
362
363         e2tInstance.KeepAliveTimestamp = time.Now().UnixNano()
364         err = m.rnibDataService.SaveE2TInstanceNoLogs(e2tInstance)
365
366         if err != nil {
367                 m.logger.Errorf("#E2TInstancesManager.ResetKeepAliveTimestamp - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
368                 return err
369         }
370
371         return nil
372 }
373
374 func (m *E2TInstancesManager) ClearRansOfAllE2TInstances() error {
375         m.logger.Infof("#E2TInstancesManager.ClearRansOfAllE2TInstances - Going to clear associated RANs from E2T instances")
376         m.mux.Lock()
377         defer m.mux.Unlock()
378
379         e2tInstances, err := m.GetE2TInstances()
380
381         if err != nil {
382                 return err
383         }
384
385         if len(e2tInstances) == 0 {
386                 m.logger.Errorf("#E2TInstancesManager.ClearRansOfAllE2TInstances - No E2T instances to clear associated RANs from")
387                 return nil
388         }
389
390         for _, v := range e2tInstances {
391                 v.AssociatedRanList = []string{}
392                 err := m.rnibDataService.SaveE2TInstance(v)
393
394                 if err != nil {
395                         m.logger.Errorf("#E2TInstancesManager.ClearRansOfAllE2TInstances - e2t address: %s - failed saving e2t instance. error: %s", v.Address, err)
396                 }
397         }
398
399         return nil
400 }