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