blob: 74f6a5188345eef4657762594783d3955853ae84 [file] [log] [blame]
ss412gefcb4522019-12-02 16:59:19 +02001//
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
18package managers
19
20import (
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
31type E2TInstancesManager struct {
32 rnibDataService services.RNibDataService
33 logger *logger.Logger
34 mux sync.Mutex
35}
36
37type 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
50func NewE2TInstancesManager(rnibDataService services.RNibDataService, logger *logger.Logger) *E2TInstancesManager {
51 return &E2TInstancesManager{
52 rnibDataService: rnibDataService,
53 logger: logger,
54 }
55}
56
57func (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
74func (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
106func (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
142func (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
174func 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
188func (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
226func (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
260func (m *E2TInstancesManager) RemoveE2TInstance(e2tInstance *entities.E2TInstance) error {
261 return nil
262}
263func (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
287func (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
312func (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
332func (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}