[RICPLT-2787] Add new e2t controller and GetE2TInstances API
[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 package managers
19
20 import (
21         "e2mgr/e2managererrors"
22         "e2mgr/logger"
23         "e2mgr/services"
24         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
25         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
26         "math"
27         "sync"
28         "time"
29 )
30
31 type E2TInstancesManager struct {
32         rnibDataService services.RNibDataService
33         logger          *logger.Logger
34         mux             sync.Mutex
35 }
36
37 type IE2TInstancesManager interface {
38         GetE2TInstance(e2tAddress string) (*entities.E2TInstance, error)
39         GetE2TInstances() ([]*entities.E2TInstance, error)
40         GetE2TInstancesNoLogs() ([]*entities.E2TInstance, error)
41         AddE2TInstance(e2tAddress string) error
42         RemoveE2TInstance(e2tInstance *entities.E2TInstance) error
43         SelectE2TInstance() (string, error)
44         AssociateRan(ranName string, e2tAddress string) error
45         DissociateRan(ranName string, e2tAddress string) error
46         ActivateE2TInstance(e2tInstance *entities.E2TInstance) error
47         ResetKeepAliveTimestamp(e2tAddress string) error
48 }
49
50 func NewE2TInstancesManager(rnibDataService services.RNibDataService, logger *logger.Logger) *E2TInstancesManager {
51         return &E2TInstancesManager{
52                 rnibDataService: rnibDataService,
53                 logger:          logger,
54         }
55 }
56
57 func (m *E2TInstancesManager) GetE2TInstance(e2tAddress string) (*entities.E2TInstance, error) {
58         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
59
60         if err != nil {
61
62                 _, ok := err.(*common.ResourceNotFoundError)
63
64                 if !ok {
65                         m.logger.Errorf("#E2TInstancesManager.GetE2TInstance - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
66                 } else {
67                         m.logger.Infof("#E2TInstancesManager.GetE2TInstance - E2T Instance address: %s not found on DB", e2tAddress)
68                 }
69         }
70
71         return e2tInstance, err
72 }
73
74 func (m *E2TInstancesManager) GetE2TInstancesNoLogs() ([]*entities.E2TInstance, error) {
75         e2tAddresses, err := m.rnibDataService.GetE2TAddressesNoLogs()
76
77         if err != nil {
78                 _, ok := err.(*common.ResourceNotFoundError)
79
80                 if !ok {
81                         m.logger.Errorf("#E2TInstancesManager.GetE2TInstancesNoLogs - Failed retrieving E2T addresses. error: %s", err)
82                         return nil, e2managererrors.NewRnibDbError()
83                 }
84
85                 return []*entities.E2TInstance{}, nil
86         }
87
88         if len(e2tAddresses) == 0 {
89                 return []*entities.E2TInstance{}, nil
90         }
91
92         e2tInstances, err := m.rnibDataService.GetE2TInstancesNoLogs(e2tAddresses)
93
94         if err != nil {
95                 _, ok := err.(*common.ResourceNotFoundError)
96
97                 if !ok {
98                         m.logger.Errorf("#E2TInstancesManager.GetE2TInstancesNoLogs - Failed retrieving E2T instances list. error: %s", err)
99                 }
100                 return e2tInstances, err
101         }
102
103         return e2tInstances, nil
104 }
105
106 func (m *E2TInstancesManager) GetE2TInstances() ([]*entities.E2TInstance, error) {
107         e2tAddresses, err := m.rnibDataService.GetE2TAddresses()
108
109         if err != nil {
110
111                 _, ok := err.(*common.ResourceNotFoundError)
112
113                 if !ok {
114                         m.logger.Errorf("#E2TInstancesManager.GetE2TInstances - Failed retrieving E2T addresses. error: %s", err)
115                         return nil, e2managererrors.NewRnibDbError()
116                 }
117
118                 m.logger.Infof("#E2TInstancesManager.GetE2TInstances - Empty E2T addresses list")
119                 return []*entities.E2TInstance{}, nil
120         }
121
122         if len(e2tAddresses) == 0 {
123                 m.logger.Infof("#E2TInstancesManager.GetE2TInstances - Empty E2T addresses list")
124                 return []*entities.E2TInstance{}, nil
125         }
126
127         e2tInstances, err := m.rnibDataService.GetE2TInstances(e2tAddresses)
128
129         if err != nil {
130                 m.logger.Errorf("#E2TInstancesManager.GetE2TInstances - Failed retrieving E2T instances list. error: %s", err)
131                 return e2tInstances, e2managererrors.NewRnibDbError()
132         }
133
134         if len(e2tInstances) == 0 {
135                 m.logger.Warnf("#E2TInstancesManager.GetE2TInstances - Empty E2T instances list")
136                 return e2tInstances, nil
137         }
138
139         return e2tInstances, nil
140 }
141
142 func (m *E2TInstancesManager) ResetKeepAliveTimestampsForAllE2TInstances() {
143
144         e2tInstances, err := m.GetE2TInstances()
145
146         if err != nil {
147                 m.logger.Errorf("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - Couldn't reset timestamps due to a DB error")
148                 return
149         }
150
151         if len(e2tInstances) == 0 {
152                 m.logger.Infof("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - No instances, ignoring reset")
153                 return
154         }
155
156         for _, v := range e2tInstances {
157
158                 if v.State != entities.Active {
159                         continue
160                 }
161
162                 v.KeepAliveTimestamp = time.Now().UnixNano()
163
164                 err := m.rnibDataService.SaveE2TInstance(v)
165
166                 if err != nil {
167                         m.logger.Errorf("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - E2T address: %s - failed resetting e2t instance keep alive timestamp. error: %s", v.Address, err)
168                 }
169         }
170
171         m.logger.Infof("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - Done with reset")
172 }
173
174 func findActiveE2TInstanceWithMinimumAssociatedRans(e2tInstances []*entities.E2TInstance) *entities.E2TInstance {
175         var minInstance *entities.E2TInstance
176         minAssociatedRanCount := math.MaxInt32
177
178         for _, v := range e2tInstances {
179                 if v.State == entities.Active && len(v.AssociatedRanList) < minAssociatedRanCount {
180                         minAssociatedRanCount = len(v.AssociatedRanList)
181                         minInstance = v
182                 }
183         }
184
185         return minInstance
186 }
187
188 func (m *E2TInstancesManager) AddE2TInstance(e2tAddress string) error {
189
190         m.mux.Lock()
191         defer m.mux.Unlock()
192
193         e2tInstance := entities.NewE2TInstance(e2tAddress)
194         err := m.rnibDataService.SaveE2TInstance(e2tInstance)
195
196         if err != nil {
197                 m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed saving E2T instance. error: %s", e2tInstance.Address, err)
198                 return err
199         }
200
201         e2tAddresses, err := m.rnibDataService.GetE2TAddresses()
202
203         if err != nil {
204
205                 _, ok := err.(*common.ResourceNotFoundError)
206
207                 if !ok {
208                         m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed retrieving E2T addresses list. error: %s", e2tInstance.Address, err)
209                         return err
210                 }
211         }
212
213         e2tAddresses = append(e2tAddresses, e2tInstance.Address)
214
215         err = m.rnibDataService.SaveE2TAddresses(e2tAddresses)
216
217         if err != nil {
218                 m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed saving E2T addresses list. error: %s", e2tInstance.Address, err)
219                 return err
220         }
221
222         m.logger.Infof("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - successfully added E2T instance", e2tInstance.Address)
223         return nil
224 }
225
226 func (m *E2TInstancesManager) DissociateRan(ranName string, e2tAddress string) error {
227
228         m.mux.Lock()
229         defer m.mux.Unlock()
230
231         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
232
233         if err != nil {
234                 m.logger.Errorf("#E2TInstancesManager.DissociateRan - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
235                 return err
236         }
237
238         i := 0 // output index
239         for _, v := range e2tInstance.AssociatedRanList {
240                 if v != ranName {
241                         // copy and increment index
242                         e2tInstance.AssociatedRanList[i] = v
243                         i++
244                 }
245         }
246
247         e2tInstance.AssociatedRanList = e2tInstance.AssociatedRanList[:i]
248
249         err = m.rnibDataService.SaveE2TInstance(e2tInstance)
250
251         if err != nil {
252                 m.logger.Errorf("#E2TInstancesManager.DissociateRan - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
253                 return err
254         }
255
256         m.logger.Infof("#E2TInstancesManager.DissociateRan - successfully dissociated RAN %s from E2T %s", ranName, e2tInstance.Address)
257         return nil
258 }
259
260 func (m *E2TInstancesManager) RemoveE2TInstance(e2tInstance *entities.E2TInstance) error {
261         return nil
262 }
263 func (m *E2TInstancesManager) SelectE2TInstance() (string, error) {
264
265         e2tInstances, err := m.GetE2TInstances()
266
267         if err != nil {
268                 return "", err
269         }
270
271         if len(e2tInstances) == 0 {
272                 m.logger.Errorf("#E2TInstancesManager.SelectE2TInstance - No E2T instance found")
273                 return "", e2managererrors.NewE2TInstanceAbsenceError()
274         }
275
276         min := findActiveE2TInstanceWithMinimumAssociatedRans(e2tInstances)
277
278         if min == nil {
279                 m.logger.Errorf("#E2TInstancesManager.SelectE2TInstance - No active E2T instance found")
280                 return "", e2managererrors.NewE2TInstanceAbsenceError()
281         }
282
283         m.logger.Infof("#E2TInstancesManager.SelectE2TInstance - successfully selected E2T instance. address: %s", min.Address)
284         return min.Address, nil
285 }
286
287 func (m *E2TInstancesManager) AssociateRan(ranName string, e2tAddress string) error {
288
289         m.mux.Lock()
290         defer m.mux.Unlock()
291
292         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
293
294         if err != nil {
295                 m.logger.Errorf("#E2TInstancesManager.AssociateRan - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
296                 return e2managererrors.NewRnibDbError()
297         }
298
299         e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, ranName)
300
301         err = m.rnibDataService.SaveE2TInstance(e2tInstance)
302
303         if err != nil {
304                 m.logger.Errorf("#E2TInstancesManager.AssociateRan - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
305                 return e2managererrors.NewRnibDbError()
306         }
307
308         m.logger.Infof("#E2TInstancesManager.AssociateRan - successfully associated RAN %s with E2T %s", ranName, e2tInstance.Address)
309         return nil
310 }
311
312 func (h E2TInstancesManager) ActivateE2TInstance(e2tInstance *entities.E2TInstance) error{
313
314         if e2tInstance == nil {
315                 h.logger.Errorf("#E2TInstancesManager.ActivateE2TInstance - e2tInstance empty")
316                 return e2managererrors.NewInternalError()
317         }
318
319         h.logger.Infof("#E2TInstancesManager.ActivateE2TInstance - E2T Address: %s - activate E2T instance", e2tInstance.Address)
320
321         e2tInstance.State = entities.Active
322         e2tInstance.KeepAliveTimestamp = time.Now().UnixNano()
323
324         err := h.rnibDataService.SaveE2TInstance(e2tInstance)
325         if err != nil {
326                 h.logger.Errorf("#E2TInstancesManager.ActivateE2TInstance - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tInstance.Address, err)
327                 return err
328         }
329         return nil
330 }
331
332 func (m *E2TInstancesManager) ResetKeepAliveTimestamp(e2tAddress string) error {
333
334         m.mux.Lock()
335         defer m.mux.Unlock()
336
337         e2tInstance, err := m.rnibDataService.GetE2TInstanceNoLogs(e2tAddress)
338
339         if err != nil {
340                 m.logger.Errorf("#E2TInstancesManager.ResetKeepAliveTimestamp - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
341                 return err
342         }
343
344         if e2tInstance.State == entities.ToBeDeleted || e2tInstance.State == entities.RoutingManagerFailure {
345                 m.logger.Warnf("#E2TInstancesManager.ResetKeepAliveTimestamp - Ignore. This Instance is about to deleted")
346                 return nil
347
348         }
349
350         e2tInstance.KeepAliveTimestamp = time.Now().UnixNano()
351         err = m.rnibDataService.SaveE2TInstanceNoLogs(e2tInstance)
352
353         if err != nil {
354                 m.logger.Errorf("#E2TInstancesManager.ResetKeepAliveTimestamp - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
355                 return err
356         }
357
358         return nil
359 }