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