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