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