[RIC-287] New Handler: Handle Ran List Object - to solve Race Condition
[ric-plt/e2mgr.git] / E2Manager / services / rnib_data_service.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 services
21
22 import (
23         "e2mgr/configuration"
24         "e2mgr/logger"
25         "e2mgr/rNibWriter"
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         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
29         "net"
30         "time"
31 )
32
33 type RNibDataService interface {
34         SaveNodeb(nodebInfo *entities.NodebInfo) error
35         UpdateNodebInfo(nodebInfo *entities.NodebInfo) error
36         UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error
37         SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error
38         GetNodeb(ranName string) (*entities.NodebInfo, error)
39         GetListNodebIds() ([]*entities.NbIdentity, error)
40         PingRnib() bool
41         GetE2TInstance(address string) (*entities.E2TInstance, error)
42         GetE2TInstances(addresses []string) ([]*entities.E2TInstance, error)
43         GetE2TAddresses() ([]string, error)
44         SaveE2TInstance(e2tInstance *entities.E2TInstance) error
45         SaveE2TAddresses(addresses []string) error
46         GetE2TInstanceNoLogs(address string) (*entities.E2TInstance, error)
47         GetE2TInstancesNoLogs(addresses []string) ([]*entities.E2TInstance, error)
48         SaveE2TInstanceNoLogs(e2tInstance *entities.E2TInstance) error
49         GetE2TAddressesNoLogs() ([]string, error)
50         RemoveE2TInstance(e2tAddress string) error
51         UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error
52         RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error
53         GetGeneralConfiguration() (*entities.GeneralConfiguration, error)
54         UpdateNodebInfoOnConnectionStatusInversion(nodebInfo *entities.NodebInfo, event string) error
55         SaveGeneralConfiguration(config *entities.GeneralConfiguration) error
56         RemoveEnb(nodebInfo *entities.NodebInfo) error
57         RemoveServedCells(inventoryName string, servedCells []*entities.ServedCellInfo) error
58         UpdateEnb(nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) error
59         AddNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error
60         RemoveNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error
61         AddEnb(nodebInfo *entities.NodebInfo) error
62         UpdateNbIdentity(nodeType entities.Node_Type, oldNbIdentities *entities.NbIdentity, newNbIdentities *entities.NbIdentity) error
63         UpdateNbIdentities(nodeType entities.Node_Type, oldNbIdentities []*entities.NbIdentity, newNbIdentities []*entities.NbIdentity) error
64 }
65
66 type rNibDataService struct {
67         logger        *logger.Logger
68         rnibReader    reader.RNibReader
69         rnibWriter    rNibWriter.RNibWriter
70         maxAttempts   int
71         retryInterval time.Duration
72 }
73
74 func NewRnibDataService(logger *logger.Logger, config *configuration.Configuration, rnibReader reader.RNibReader, rnibWriter rNibWriter.RNibWriter) *rNibDataService {
75         return &rNibDataService{
76                 logger:        logger,
77                 rnibReader:    rnibReader,
78                 rnibWriter:    rnibWriter,
79                 maxAttempts:   config.MaxRnibConnectionAttempts,
80                 retryInterval: time.Duration(config.RnibRetryIntervalMs) * time.Millisecond,
81         }
82 }
83
84 func (w *rNibDataService) AddNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error {
85         w.logger.Infof("#RnibDataService.AddNbIdentity - nbIdentity: %s", nbIdentity)
86
87         err := w.retry("AddNbIdentity", func() (err error) {
88                 err = w.rnibWriter.AddNbIdentity(nodeType, nbIdentity)
89                 return
90         })
91
92         return err
93 }
94
95 func (w *rNibDataService) RemoveNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error{
96         w.logger.Infof("#RnibDataService.RemoveNbIdentity - nbIdentity: %s", nbIdentity)
97
98         err := w.retry("RemoveNbIdentity", func() (err error) {
99                 err = w.rnibWriter.RemoveNbIdentity(nodeType, nbIdentity)
100                 return
101         })
102
103         return err
104 }
105
106 func (w *rNibDataService) RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error {
107         err := w.retry("RemoveServedNrCells", func() (err error) {
108                 err = w.rnibWriter.RemoveServedNrCells(inventoryName, servedNrCells)
109                 return
110         })
111
112         return err
113 }
114
115 func (w *rNibDataService) RemoveEnb(nodebInfo *entities.NodebInfo) error {
116         w.logger.Infof("#RnibDataService.RemoveEnb - nodebInfo: %s", nodebInfo)
117
118         err := w.retry("RemoveEnb", func() (err error) {
119                 err = w.rnibWriter.RemoveEnb(nodebInfo)
120                 return
121         })
122
123         return err
124 }
125
126 func (w *rNibDataService) UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error {
127         w.logger.Infof("#RnibDataService.UpdateGnbCells - nodebInfo: %s, servedNrCells: %s", nodebInfo, servedNrCells)
128
129         err := w.retry("UpdateGnbCells", func() (err error) {
130                 err = w.rnibWriter.UpdateGnbCells(nodebInfo, servedNrCells)
131                 return
132         })
133
134         return err
135 }
136
137 func (w *rNibDataService) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error {
138         w.logger.Infof("#RnibDataService.UpdateNodebInfo - nodebInfo: %s", nodebInfo)
139
140         err := w.retry("UpdateNodebInfo", func() (err error) {
141                 err = w.rnibWriter.UpdateNodebInfo(nodebInfo)
142                 return
143         })
144
145         return err
146 }
147
148 func (w *rNibDataService) UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error {
149         w.logger.Infof("#RnibDataService.UpdateNodebInfoAndPublish - nodebInfo: %s", nodebInfo)
150
151         err := w.retry("UpdateNodebInfoAndPublish", func() (err error) {
152                 err = w.rnibWriter.UpdateNodebInfoAndPublish(nodebInfo)
153                 return
154         })
155
156         return err
157 }
158
159 func (w *rNibDataService) SaveNodeb(nodebInfo *entities.NodebInfo) error {
160         w.logger.Infof("#RnibDataService.SaveNodeb - nodebInfo: %s", nodebInfo)
161
162         err := w.retry("SaveNodeb", func() (err error) {
163                 err = w.rnibWriter.SaveNodeb(nodebInfo)
164                 return
165         })
166
167         return err
168 }
169
170 func (w *rNibDataService) SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error {
171         w.logger.Infof("#RnibDataService.SaveRanLoadInformation - inventoryName: %s, ranLoadInformation: %s", inventoryName, ranLoadInformation)
172
173         err := w.retry("SaveRanLoadInformation", func() (err error) {
174                 err = w.rnibWriter.SaveRanLoadInformation(inventoryName, ranLoadInformation)
175                 return
176         })
177
178         return err
179 }
180
181 func (w *rNibDataService) GetNodeb(ranName string) (*entities.NodebInfo, error) {
182
183         var nodeb *entities.NodebInfo = nil
184
185         err := w.retry("GetNodeb", func() (err error) {
186                 nodeb, err = w.rnibReader.GetNodeb(ranName)
187                 return
188         })
189
190         if err == nil {
191                 w.logger.Infof("#RnibDataService.GetNodeb - RAN name: %s, connection status: %s, associated E2T: %s, setup from network: %t", nodeb.RanName, nodeb.ConnectionStatus, nodeb.AssociatedE2TInstanceAddress, nodeb.SetupFromNetwork)
192         }
193
194         return nodeb, err
195 }
196
197 func (w *rNibDataService) GetListNodebIds() ([]*entities.NbIdentity, error) {
198         var nodeIds []*entities.NbIdentity = nil
199
200         err := w.retry("GetListNodebIds", func() (err error) {
201                 nodeIds, err = w.rnibReader.GetListNodebIds()
202                 return
203         })
204
205         if err == nil {
206                 w.logger.Infof("#RnibDataService.GetListNodebIds - RANs count: %d", len(nodeIds))
207         }
208
209         return nodeIds, err
210 }
211
212 func (w *rNibDataService) GetE2TInstance(address string) (*entities.E2TInstance, error) {
213         var e2tInstance *entities.E2TInstance = nil
214
215         err := w.retry("GetE2TInstance", func() (err error) {
216                 e2tInstance, err = w.rnibReader.GetE2TInstance(address)
217                 return
218         })
219
220         if err == nil {
221                 w.logger.Infof("#RnibDataService.GetE2TInstance - E2T instance address: %s, state: %s, associated RANs count: %d, keep Alive ts: %d", e2tInstance.Address, e2tInstance.State, len(e2tInstance.AssociatedRanList), e2tInstance.KeepAliveTimestamp)
222         }
223
224         return e2tInstance, err
225 }
226
227 func (w *rNibDataService) GetE2TInstanceNoLogs(address string) (*entities.E2TInstance, error) {
228         var e2tInstance *entities.E2TInstance = nil
229
230         err := w.retry("GetE2TInstance", func() (err error) {
231                 e2tInstance, err = w.rnibReader.GetE2TInstance(address)
232                 return
233         })
234
235         return e2tInstance, err
236 }
237
238 func (w *rNibDataService) GetE2TInstances(addresses []string) ([]*entities.E2TInstance, error) {
239         w.logger.Infof("#RnibDataService.GetE2TInstances - addresses: %s", addresses)
240         var e2tInstances []*entities.E2TInstance = nil
241
242         err := w.retry("GetE2TInstance", func() (err error) {
243                 e2tInstances, err = w.rnibReader.GetE2TInstances(addresses)
244                 return
245         })
246
247         return e2tInstances, err
248 }
249
250 func (w *rNibDataService) GetE2TInstancesNoLogs(addresses []string) ([]*entities.E2TInstance, error) {
251
252         var e2tInstances []*entities.E2TInstance = nil
253
254         err := w.retry("GetE2TInstance", func() (err error) {
255                 e2tInstances, err = w.rnibReader.GetE2TInstances(addresses)
256                 return
257         })
258
259         return e2tInstances, err
260 }
261
262 func (w *rNibDataService) GetE2TAddresses() ([]string, error) {
263
264         var e2tAddresses []string = nil
265
266         err := w.retry("GetE2TAddresses", func() (err error) {
267                 e2tAddresses, err = w.rnibReader.GetE2TAddresses()
268                 return
269         })
270
271         if err == nil {
272                 w.logger.Infof("#RnibDataService.GetE2TAddresses - addresses: %s", e2tAddresses)
273         }
274
275         return e2tAddresses, err
276 }
277
278 func (w *rNibDataService) GetE2TAddressesNoLogs() ([]string, error) {
279
280         var e2tAddresses []string = nil
281
282         err := w.retry("GetE2TAddresses", func() (err error) {
283                 e2tAddresses, err = w.rnibReader.GetE2TAddresses()
284                 return
285         })
286
287         return e2tAddresses, err
288 }
289
290 func (w *rNibDataService) SaveE2TInstance(e2tInstance *entities.E2TInstance) error {
291         w.logger.Infof("#RnibDataService.SaveE2TInstance - E2T instance address: %s, podName: %s, state: %s, associated RANs count: %d, keep Alive ts: %d", e2tInstance.Address, e2tInstance.PodName, e2tInstance.State, len(e2tInstance.AssociatedRanList), e2tInstance.KeepAliveTimestamp)
292
293         return w.SaveE2TInstanceNoLogs(e2tInstance)
294 }
295
296 func (w *rNibDataService) SaveE2TInstanceNoLogs(e2tInstance *entities.E2TInstance) error {
297
298         err := w.retry("SaveE2TInstance", func() (err error) {
299                 err = w.rnibWriter.SaveE2TInstance(e2tInstance)
300                 return
301         })
302
303         return err
304 }
305
306 func (w *rNibDataService) SaveE2TAddresses(addresses []string) error {
307         w.logger.Infof("#RnibDataService.SaveE2TAddresses - addresses: %s", addresses)
308
309         err := w.retry("SaveE2TAddresses", func() (err error) {
310                 err = w.rnibWriter.SaveE2TAddresses(addresses)
311                 return
312         })
313
314         return err
315 }
316
317 func (w *rNibDataService) RemoveE2TInstance(e2tAddress string) error {
318         w.logger.Infof("#RnibDataService.RemoveE2TInstance - e2tAddress: %s", e2tAddress)
319
320         err := w.retry("RemoveE2TInstance", func() (err error) {
321                 err = w.rnibWriter.RemoveE2TInstance(e2tAddress)
322                 return
323         })
324
325         return err
326 }
327
328 func (w *rNibDataService) GetGeneralConfiguration() (*entities.GeneralConfiguration, error) {
329         var generalConfiguration *entities.GeneralConfiguration = nil
330
331         err := w.retry("GetGeneralConfiguration", func() (err error) {
332                 generalConfiguration, err = w.rnibReader.GetGeneralConfiguration()
333                 return
334         })
335
336         return generalConfiguration, err
337 }
338
339 func (w *rNibDataService) SaveGeneralConfiguration(config *entities.GeneralConfiguration) error {
340         err := w.retry("SaveGeneralConfiguration", func() (err error) {
341                 err = w.rnibWriter.SaveGeneralConfiguration(config)
342                 return
343         })
344
345         return err
346 }
347
348 func (w *rNibDataService) RemoveServedCells(inventoryName string, servedCells []*entities.ServedCellInfo) error {
349         err := w.retry("RemoveServedCells", func() (err error) {
350                 err = w.rnibWriter.RemoveServedCells(inventoryName, servedCells)
351                 return
352         })
353
354         return err
355 }
356
357 func (w *rNibDataService) UpdateEnb(nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) error {
358         err := w.retry("UpdateEnb", func() (err error) {
359                 err = w.rnibWriter.UpdateEnb(nodebInfo, servedCells)
360                 return
361         })
362
363         return err
364 }
365
366 func (w *rNibDataService) PingRnib() bool {
367         err := w.retry("GetListNodebIds", func() (err error) {
368                 _, err = w.rnibReader.GetListNodebIds()
369                 return
370         })
371
372         return !isRnibConnectionError(err)
373 }
374
375 func (w *rNibDataService) UpdateNodebInfoOnConnectionStatusInversion(nodebInfo *entities.NodebInfo, event string) error {
376         w.logger.Infof("#RnibDataService.UpdateNodebInfoOnConnectionStatusInversion - event: %s, nodebInfo: %s", event, nodebInfo)
377
378         err := w.retry("UpdateNodebInfoOnConnectionStatusInversion", func() (err error) {
379                 err = w.rnibWriter.UpdateNodebInfoOnConnectionStatusInversion(nodebInfo, event)
380                 return
381         })
382
383         return err
384 }
385
386 func (w *rNibDataService) AddEnb(nodebInfo *entities.NodebInfo) error {
387         w.logger.Infof("#RnibDataService.AddEnb - nodebInfo: %s", nodebInfo)
388
389         err := w.retry("AddEnb", func() (err error) {
390                 err = w.rnibWriter.AddEnb(nodebInfo)
391                 return
392         })
393
394         return err
395 }
396
397 func (w *rNibDataService) UpdateNbIdentity(nodeType entities.Node_Type, oldNbIdentity *entities.NbIdentity, newNbIdentity *entities.NbIdentity) error {
398         err := w.retry("UpdateNbIdentities", func() (err error) {
399                 err = w.rnibWriter.UpdateNbIdentities(nodeType, []*entities.NbIdentity{oldNbIdentity}, []*entities.NbIdentity{newNbIdentity})
400                 return
401         })
402
403         return err
404 }
405
406 func (w *rNibDataService) UpdateNbIdentities(nodeType entities.Node_Type, oldNbIdentities []*entities.NbIdentity, newNbIdentities []*entities.NbIdentity) error {
407         err := w.retry("UpdateNbIdentities", func() (err error) {
408                 err = w.rnibWriter.UpdateNbIdentities(nodeType, oldNbIdentities, newNbIdentities)
409                 return
410         })
411
412         return err
413 }
414
415 func (w *rNibDataService) retry(rnibFunc string, f func() error) (err error) {
416         attempts := w.maxAttempts
417
418         for i := 1; ; i++ {
419                 err = f()
420                 if err == nil {
421                         return
422                 }
423                 if !isRnibConnectionError(err) {
424                         return err
425                 }
426                 if i >= attempts {
427                         w.logger.Errorf("#RnibDataService.retry - after %d attempts of %s, last error: %s", attempts, rnibFunc, err)
428                         return err
429                 }
430                 time.Sleep(w.retryInterval)
431
432                 w.logger.Infof("#RnibDataService.retry - retrying %d %s after error: %s", i, rnibFunc, err)
433         }
434 }
435
436 func isRnibConnectionError(err error) bool {
437         internalErr, ok := err.(*common.InternalError)
438         if !ok {
439                 return false
440         }
441         _, ok = internalErr.Err.(*net.OpError)
442
443         return ok
444 }