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