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