[RIC-430] - Update Connection Status on RAN List - release tag 5.4.5
[ric-plt/e2mgr.git] / E2Manager / rNibWriter / rNibWriter.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 rNibWriter
21
22 import (
23         "e2mgr/configuration"
24         "encoding/json"
25         "fmt"
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         "github.com/golang/protobuf/proto"
29 )
30
31 const (
32         E2TAddressesKey = "E2TAddresses"
33         RanAddedEvent   = "ADDED"
34         RanUpdatedEvent = "UPDATED"
35         RanDeletedEvent = "DELETED"
36 )
37
38 type rNibWriterInstance struct {
39         sdl              common.ISdlInstance
40         rnibWriterConfig configuration.RnibWriterConfig
41 }
42
43 /*
44 RNibWriter interface allows saving data to the redis DB
45 */
46 type RNibWriter interface {
47         SaveNodeb(nodebInfo *entities.NodebInfo) error
48         UpdateNodebInfo(nodebInfo *entities.NodebInfo) error
49         UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error
50         SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error
51         SaveE2TInstance(e2tInstance *entities.E2TInstance) error
52         SaveE2TAddresses(addresses []string) error
53         RemoveE2TInstance(e2tAddress string) error
54         UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error
55         RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error
56         UpdateNodebInfoOnConnectionStatusInversion(nodebInfo *entities.NodebInfo, ent string) error
57         SaveGeneralConfiguration(config *entities.GeneralConfiguration) error
58         RemoveEnb(nodebInfo *entities.NodebInfo) error
59         RemoveServedCells(inventoryName string, servedCells []*entities.ServedCellInfo) error
60         UpdateEnb(nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) error
61         AddNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error
62         RemoveNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error
63         AddEnb(nodebInfo *entities.NodebInfo) error
64         UpdateNbIdentities(nodeType entities.Node_Type, oldNbIdentities []*entities.NbIdentity, newNbIdentities []*entities.NbIdentity) error
65 }
66 /*
67 GetRNibWriter returns reference to RNibWriter
68 */
69
70 func GetRNibWriter(sdl common.ISdlInstance, rnibWriterConfig configuration.RnibWriterConfig) RNibWriter {
71         return &rNibWriterInstance{sdl: sdl, rnibWriterConfig: rnibWriterConfig}
72 }
73
74 func getChannelsAndEventsPair(channel string, ranName string, event string) []string {
75         return []string{channel, fmt.Sprintf("%s_%s", ranName, event)}
76 }
77
78 func (w *rNibWriterInstance) AddNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error {
79         nbIdData, err := proto.Marshal(nbIdentity)
80
81         if err != nil {
82                 return common.NewInternalError(err)
83         }
84
85         err = w.sdl.AddMember(nodeType.String(), nbIdData)
86
87         if err != nil {
88                 return common.NewInternalError(err)
89         }
90         return nil
91 }
92
93 func (w *rNibWriterInstance) RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error {
94         cellKeysToRemove := buildServedNRCellKeysToRemove(inventoryName, servedNrCells)
95
96         err := w.sdl.Remove(cellKeysToRemove)
97
98         if err != nil {
99                 return common.NewInternalError(err)
100         }
101
102         return nil
103 }
104
105 func (w *rNibWriterInstance) RemoveServedCells(inventoryName string, servedCells []*entities.ServedCellInfo) error {
106         cellKeysToRemove := buildServedCellInfoKeysToRemove(inventoryName, servedCells)
107
108         err := w.sdl.Remove(cellKeysToRemove)
109
110         if err != nil {
111                 return common.NewInternalError(err)
112         }
113
114         return nil
115 }
116
117 func (w *rNibWriterInstance) SaveGeneralConfiguration(config *entities.GeneralConfiguration) error {
118
119         err := w.SaveWithKeyAndMarshal(common.BuildGeneralConfigurationKey(), config)
120
121         if err != nil {
122                 return common.NewInternalError(err)
123         }
124
125         return nil
126 }
127
128 /*
129 SaveNodeb saves nodeB entity data in the redis DB according to the specified data model
130 */
131 func (w *rNibWriterInstance) SaveNodeb(nodebInfo *entities.NodebInfo) error {
132
133         data, err := proto.Marshal(nodebInfo)
134
135         if err != nil {
136                 return common.NewInternalError(err)
137         }
138
139         var pairs []interface{}
140         key, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.RanName)
141
142         if rNibErr != nil {
143                 return rNibErr
144         }
145
146         pairs = append(pairs, key, data)
147
148         if nodebInfo.GlobalNbId != nil {
149
150                 key, rNibErr = common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId())
151                 if rNibErr != nil {
152                         return rNibErr
153                 }
154                 pairs = append(pairs, key, data)
155         }
156
157         if nodebInfo.GetEnb() != nil {
158                 pairs, rNibErr = appendEnbCells(nodebInfo.RanName, nodebInfo.GetEnb().GetServedCells(), pairs)
159                 if rNibErr != nil {
160                         return rNibErr
161                 }
162         }
163
164         if nodebInfo.GetGnb() != nil {
165                 pairs, rNibErr = appendGnbCells(nodebInfo.RanName, nodebInfo.GetGnb().GetServedNrCells(), pairs)
166                 if rNibErr != nil {
167                         return rNibErr
168                 }
169         }
170
171         err = w.sdl.Set(pairs)
172
173         if err != nil {
174                 return common.NewInternalError(err)
175         }
176
177         return nil
178 }
179
180 func (w *rNibWriterInstance) AddEnb(nodebInfo *entities.NodebInfo) error {
181
182         data, err := proto.Marshal(nodebInfo)
183
184         if err != nil {
185                 return common.NewInternalError(err)
186         }
187
188         var pairs []interface{}
189         key, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.RanName)
190
191         if rNibErr != nil {
192                 return rNibErr
193         }
194
195         pairs = append(pairs, key, data)
196
197         if nodebInfo.GlobalNbId != nil {
198
199                 key, rNibErr = common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId())
200                 if rNibErr != nil {
201                         return rNibErr
202                 }
203                 pairs = append(pairs, key, data)
204         }
205
206         pairs, rNibErr = appendEnbCells(nodebInfo.RanName, nodebInfo.GetEnb().GetServedCells(), pairs)
207         if rNibErr != nil {
208                 return rNibErr
209         }
210
211         channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanAddedEvent)
212         err = w.sdl.SetAndPublish(channelsAndEvents, pairs)
213         if err != nil {
214                 return common.NewInternalError(err)
215         }
216
217         return nil
218 }
219
220 func (w *rNibWriterInstance) UpdateNbIdentities(nodeType entities.Node_Type, oldNbIdentities []*entities.NbIdentity, newNbIdentities []*entities.NbIdentity) error {
221
222         nbIdIdentitiesToRemove, err := w.buildNbIdentitiesMembers(oldNbIdentities)
223         if err != nil {
224                 return err
225         }
226
227         err = w.sdl.RemoveMember(nodeType.String(), nbIdIdentitiesToRemove[:]...)
228         if err != nil {
229                 return err
230         }
231
232         nbIdIdentitiesToAdd, err := w.buildNbIdentitiesMembers(newNbIdentities)
233         if err != nil {
234                 return err
235         }
236
237         err = w.sdl.AddMember(nodeType.String(), nbIdIdentitiesToAdd[:]...)
238         if err != nil {
239                 return err
240         }
241
242         return nil
243 }
244
245 func (w *rNibWriterInstance) UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error {
246
247         pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
248
249         if err != nil {
250                 return err
251         }
252
253         pairs, err = appendGnbCells(nodebInfo.RanName, servedNrCells, pairs)
254
255         if err != nil {
256                 return err
257         }
258
259         channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanUpdatedEvent)
260         err = w.sdl.SetAndPublish(channelsAndEvents, pairs)
261
262         if err != nil {
263                 return common.NewInternalError(err)
264         }
265
266         return nil
267 }
268
269 func buildServedNRCellKeysToRemove(inventoryName string, servedNrCellsToRemove []*entities.ServedNRCell) []string {
270
271         var cellKeysToRemove []string
272
273         for _, cell := range servedNrCellsToRemove {
274
275                 key, _ := common.ValidateAndBuildNrCellIdKey(cell.GetServedNrCellInformation().GetCellId())
276
277                 if len(key) != 0 {
278                         cellKeysToRemove = append(cellKeysToRemove, key)
279                 }
280
281                 key, _ = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetServedNrCellInformation().GetNrPci())
282
283                 if len(key) != 0 {
284                         cellKeysToRemove = append(cellKeysToRemove, key)
285                 }
286         }
287
288         return cellKeysToRemove
289 }
290
291 func buildServedCellInfoKeysToRemove(inventoryName string, servedCellsToRemove []*entities.ServedCellInfo) []string {
292
293         var cellKeysToRemove []string
294
295         for _, cell := range servedCellsToRemove {
296
297                 key, _ := common.ValidateAndBuildCellIdKey(cell.GetCellId())
298
299                 if len(key) != 0 {
300                         cellKeysToRemove = append(cellKeysToRemove, key)
301                 }
302
303                 key, _ = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetPci())
304
305                 if len(key) != 0 {
306                         cellKeysToRemove = append(cellKeysToRemove, key)
307                 }
308         }
309
310         return cellKeysToRemove
311 }
312
313 func buildUpdateNodebInfoPairs(nodebInfo *entities.NodebInfo) ([]interface{}, error) {
314         nodebNameKey, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.GetRanName())
315
316         if rNibErr != nil {
317                 return []interface{}{}, rNibErr
318         }
319
320         nodebIdKey, buildNodebIdKeyError := common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId())
321
322         data, err := proto.Marshal(nodebInfo)
323
324         if err != nil {
325                 return []interface{}{}, common.NewInternalError(err)
326         }
327
328         pairs := []interface{}{nodebNameKey, data}
329
330         if buildNodebIdKeyError == nil {
331                 pairs = append(pairs, nodebIdKey, data)
332         }
333
334         return pairs, nil
335 }
336
337 func (w *rNibWriterInstance) buildRemoveEnbKeys(nodebInfo *entities.NodebInfo) ([]string, error) {
338         keys := buildServedCellInfoKeysToRemove(nodebInfo.GetRanName(), nodebInfo.GetEnb().GetServedCells())
339
340         nodebNameKey, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.GetRanName())
341
342         if rNibErr != nil {
343                 return []string{}, rNibErr
344         }
345
346         keys = append(keys, nodebNameKey)
347
348         nodebIdKey, buildNodebIdKeyError := common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId())
349
350         if buildNodebIdKeyError == nil {
351                 keys = append(keys, nodebIdKey)
352         }
353
354         return keys, nil
355 }
356
357 func (w *rNibWriterInstance) RemoveNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error {
358         nbIdData, err := proto.Marshal(nbIdentity)
359         if err != nil {
360                 return common.NewInternalError(err)
361         }
362         err = w.sdl.RemoveMember(nodeType.String(), nbIdData)
363         if err != nil {
364                 return common.NewInternalError(err)
365         }
366         return nil
367 }
368
369 func (w *rNibWriterInstance) updateNodebInfo(nodebInfo *entities.NodebInfo, publish bool) error {
370
371         pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
372
373         if err != nil {
374                 return err
375         }
376
377         if publish {
378                 channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanUpdatedEvent)
379                 err = w.sdl.SetAndPublish(channelsAndEvents, pairs)
380         } else {
381                 err = w.sdl.Set(pairs)
382         }
383
384         if err != nil {
385                 return common.NewInternalError(err)
386         }
387
388         return nil
389 }
390
391 /*
392 UpdateNodebInfo...
393 */
394 func (w *rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error {
395         return w.updateNodebInfo(nodebInfo, false)
396 }
397
398 /*
399 UpdateNodebInfoAndPublish...
400 */
401 func (w *rNibWriterInstance) UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error {
402         return w.updateNodebInfo(nodebInfo, true)
403 }
404
405
406 /*
407 SaveRanLoadInformation stores ran load information for the provided ran
408 */
409 func (w *rNibWriterInstance) SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error {
410
411         key, rnibErr := common.ValidateAndBuildRanLoadInformationKey(inventoryName)
412
413         if rnibErr != nil {
414                 return rnibErr
415         }
416
417         data, err := proto.Marshal(ranLoadInformation)
418
419         if err != nil {
420                 return common.NewInternalError(err)
421         }
422
423         var pairs []interface{}
424         pairs = append(pairs, key, data)
425
426         err = w.sdl.Set(pairs)
427
428         if err != nil {
429                 return common.NewInternalError(err)
430         }
431
432         return nil
433 }
434
435 func (w *rNibWriterInstance) SaveE2TInstance(e2tInstance *entities.E2TInstance) error {
436
437         key, rnibErr := common.ValidateAndBuildE2TInstanceKey(e2tInstance.Address)
438
439         if rnibErr != nil {
440                 return rnibErr
441         }
442
443         data, err := json.Marshal(e2tInstance)
444
445         if err != nil {
446                 return common.NewInternalError(err)
447         }
448
449         var pairs []interface{}
450         pairs = append(pairs, key, data)
451
452         err = w.sdl.Set(pairs)
453
454         if err != nil {
455                 return common.NewInternalError(err)
456         }
457
458         return nil
459 }
460
461 func (w *rNibWriterInstance) SaveE2TAddresses(addresses []string) error {
462
463         data, err := json.Marshal(addresses)
464
465         if err != nil {
466                 return common.NewInternalError(err)
467         }
468
469         var pairs []interface{}
470         pairs = append(pairs, E2TAddressesKey, data)
471
472         err = w.sdl.Set(pairs)
473
474         if err != nil {
475                 return common.NewInternalError(err)
476         }
477
478         return nil
479 }
480
481 func (w *rNibWriterInstance) RemoveE2TInstance(address string) error {
482         key, rNibErr := common.ValidateAndBuildE2TInstanceKey(address)
483         if rNibErr != nil {
484                 return rNibErr
485         }
486         err := w.sdl.Remove([]string{key})
487
488         if err != nil {
489                 return common.NewInternalError(err)
490         }
491         return nil
492 }
493
494 func (w *rNibWriterInstance) SaveWithKeyAndMarshal(key string, entity interface{}) error {
495
496         data, err := json.Marshal(entity)
497
498         if err != nil {
499                 return common.NewInternalError(err)
500         }
501
502         var pairs []interface{}
503         pairs = append(pairs, key, data)
504
505         err = w.sdl.Set(pairs)
506
507         if err != nil {
508                 return common.NewInternalError(err)
509         }
510
511         return nil
512 }
513
514 /*
515 UpdateNodebInfoOnConnectionStatusInversion...
516 */
517 func (w *rNibWriterInstance) UpdateNodebInfoOnConnectionStatusInversion(nodebInfo *entities.NodebInfo, event string) error {
518
519         pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
520
521         if err != nil {
522                 return err
523         }
524
525         err = w.sdl.SetAndPublish([]string{w.rnibWriterConfig.StateChangeMessageChannel, event}, pairs)
526
527         if err != nil {
528                 return common.NewInternalError(err)
529         }
530
531         return nil
532 }
533
534 func (w *rNibWriterInstance) RemoveEnb(nodebInfo *entities.NodebInfo) error {
535         keysToRemove, err := w.buildRemoveEnbKeys(nodebInfo)
536         if err != nil {
537                 return err
538         }
539
540         channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanDeletedEvent)
541         err = w.sdl.RemoveAndPublish(channelsAndEvents, keysToRemove)
542
543         if err != nil {
544                 return common.NewInternalError(err)
545         }
546
547         return nil
548 }
549
550 func (w *rNibWriterInstance) UpdateEnb(nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) error {
551
552         pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
553
554         if err != nil {
555                 return err
556         }
557
558         pairs, err = appendEnbCells(nodebInfo.RanName, servedCells, pairs)
559
560         if err != nil {
561                 return err
562         }
563
564         channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanUpdatedEvent)
565         err = w.sdl.SetAndPublish(channelsAndEvents, pairs)
566
567         if err != nil {
568                 return common.NewInternalError(err)
569         }
570
571         return nil
572 }
573
574 func (w *rNibWriterInstance) buildNbIdentitiesMembers(nbIdentities []*entities.NbIdentity) ([]interface{}, error) {
575
576         var nbIdIdentitiesMembers []interface{}
577         for _, nbIdentity := range nbIdentities {
578
579                 nbIdData, err := proto.Marshal(nbIdentity)
580                 if err != nil {
581                         return nil, common.NewInternalError(err)
582                 }
583                 nbIdIdentitiesMembers = append(nbIdIdentitiesMembers, nbIdData)
584         }
585
586         return nbIdIdentitiesMembers, nil
587 }
588 /*
589 Close the writer
590 */
591 func Close() {
592         //Nothing to do
593 }
594
595 func appendEnbCells(inventoryName string, cells []*entities.ServedCellInfo, pairs []interface{}) ([]interface{}, error) {
596         for _, cell := range cells {
597                 cellEntity := entities.Cell{Type: entities.Cell_LTE_CELL, Cell: &entities.Cell_ServedCellInfo{ServedCellInfo: cell}}
598                 cellData, err := proto.Marshal(&cellEntity)
599                 if err != nil {
600                         return pairs, common.NewInternalError(err)
601                 }
602                 key, rNibErr := common.ValidateAndBuildCellIdKey(cell.GetCellId())
603                 if rNibErr != nil {
604                         return pairs, rNibErr
605                 }
606                 pairs = append(pairs, key, cellData)
607                 key, rNibErr = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetPci())
608                 if rNibErr != nil {
609                         return pairs, rNibErr
610                 }
611                 pairs = append(pairs, key, cellData)
612         }
613         return pairs, nil
614 }
615
616 func appendGnbCells(inventoryName string, cells []*entities.ServedNRCell, pairs []interface{}) ([]interface{}, error) {
617         for _, cell := range cells {
618                 cellEntity := entities.Cell{Type: entities.Cell_NR_CELL, Cell: &entities.Cell_ServedNrCell{ServedNrCell: cell}}
619                 cellData, err := proto.Marshal(&cellEntity)
620                 if err != nil {
621                         return pairs, common.NewInternalError(err)
622                 }
623                 key, rNibErr := common.ValidateAndBuildNrCellIdKey(cell.GetServedNrCellInformation().GetCellId())
624                 if rNibErr != nil {
625                         return pairs, rNibErr
626                 }
627                 pairs = append(pairs, key, cellData)
628                 key, rNibErr = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetServedNrCellInformation().GetNrPci())
629                 if rNibErr != nil {
630                         return pairs, rNibErr
631                 }
632                 pairs = append(pairs, key, cellData)
633         }
634         return pairs, nil
635 }