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