[RIC-587] Update E2 Setup existing nodeb behavior
[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 }
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) UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error {
221
222         pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
223
224         if err != nil {
225                 return err
226         }
227
228         pairs, err = appendGnbCells(nodebInfo.RanName, servedNrCells, pairs)
229
230         if err != nil {
231                 return err
232         }
233
234         channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanUpdatedEvent)
235         err = w.sdl.SetAndPublish(channelsAndEvents, pairs)
236
237         if err != nil {
238                 return common.NewInternalError(err)
239         }
240
241         return nil
242 }
243
244 func buildServedNRCellKeysToRemove(inventoryName string, servedNrCellsToRemove []*entities.ServedNRCell) []string {
245
246         var cellKeysToRemove []string
247
248         for _, cell := range servedNrCellsToRemove {
249
250                 key, _ := common.ValidateAndBuildNrCellIdKey(cell.GetServedNrCellInformation().GetCellId())
251
252                 if len(key) != 0 {
253                         cellKeysToRemove = append(cellKeysToRemove, key)
254                 }
255
256                 key, _ = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetServedNrCellInformation().GetNrPci())
257
258                 if len(key) != 0 {
259                         cellKeysToRemove = append(cellKeysToRemove, key)
260                 }
261         }
262
263         return cellKeysToRemove
264 }
265
266 func buildServedCellInfoKeysToRemove(inventoryName string, servedCellsToRemove []*entities.ServedCellInfo) []string {
267
268         var cellKeysToRemove []string
269
270         for _, cell := range servedCellsToRemove {
271
272                 key, _ := common.ValidateAndBuildCellIdKey(cell.GetCellId())
273
274                 if len(key) != 0 {
275                         cellKeysToRemove = append(cellKeysToRemove, key)
276                 }
277
278                 key, _ = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetPci())
279
280                 if len(key) != 0 {
281                         cellKeysToRemove = append(cellKeysToRemove, key)
282                 }
283         }
284
285         return cellKeysToRemove
286 }
287
288 func buildUpdateNodebInfoPairs(nodebInfo *entities.NodebInfo) ([]interface{}, error) {
289         nodebNameKey, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.GetRanName())
290
291         if rNibErr != nil {
292                 return []interface{}{}, rNibErr
293         }
294
295         nodebIdKey, buildNodebIdKeyError := common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId())
296
297         data, err := proto.Marshal(nodebInfo)
298
299         if err != nil {
300                 return []interface{}{}, common.NewInternalError(err)
301         }
302
303         pairs := []interface{}{nodebNameKey, data}
304
305         if buildNodebIdKeyError == nil {
306                 pairs = append(pairs, nodebIdKey, data)
307         }
308
309         return pairs, nil
310 }
311
312 func (w *rNibWriterInstance) buildRemoveEnbKeys(nodebInfo *entities.NodebInfo) ([]string, error) {
313         keys := buildServedCellInfoKeysToRemove(nodebInfo.GetRanName(), nodebInfo.GetEnb().GetServedCells())
314
315         nodebNameKey, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.GetRanName())
316
317         if rNibErr != nil {
318                 return []string{}, rNibErr
319         }
320
321         keys = append(keys, nodebNameKey)
322
323         nodebIdKey, buildNodebIdKeyError := common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId())
324
325         if buildNodebIdKeyError == nil {
326                 keys = append(keys, nodebIdKey)
327         }
328
329         return keys, nil
330 }
331
332 func (w *rNibWriterInstance) RemoveNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error {
333         nbIdData, err := proto.Marshal(nbIdentity)
334         if err != nil {
335                 return common.NewInternalError(err)
336         }
337         err = w.sdl.RemoveMember(nodeType.String(), nbIdData)
338         if err != nil {
339                 return common.NewInternalError(err)
340         }
341         return nil
342 }
343
344 func (w *rNibWriterInstance) updateNodebInfo(nodebInfo *entities.NodebInfo, publish bool) error {
345
346         pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
347
348         if err != nil {
349                 return err
350         }
351
352         if publish {
353                 channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanUpdatedEvent)
354                 err = w.sdl.SetAndPublish(channelsAndEvents, pairs)
355         } else {
356                 err = w.sdl.Set(pairs)
357         }
358
359         if err != nil {
360                 return common.NewInternalError(err)
361         }
362
363         return nil
364 }
365
366 /*
367 UpdateNodebInfo...
368 */
369 func (w *rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error {
370         return w.updateNodebInfo(nodebInfo, false)
371 }
372
373 /*
374 UpdateNodebInfoAndPublish...
375 */
376 func (w *rNibWriterInstance) UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error {
377         return w.updateNodebInfo(nodebInfo, true)
378 }
379
380
381 /*
382 SaveRanLoadInformation stores ran load information for the provided ran
383 */
384 func (w *rNibWriterInstance) SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error {
385
386         key, rnibErr := common.ValidateAndBuildRanLoadInformationKey(inventoryName)
387
388         if rnibErr != nil {
389                 return rnibErr
390         }
391
392         data, err := proto.Marshal(ranLoadInformation)
393
394         if err != nil {
395                 return common.NewInternalError(err)
396         }
397
398         var pairs []interface{}
399         pairs = append(pairs, key, data)
400
401         err = w.sdl.Set(pairs)
402
403         if err != nil {
404                 return common.NewInternalError(err)
405         }
406
407         return nil
408 }
409
410 func (w *rNibWriterInstance) SaveE2TInstance(e2tInstance *entities.E2TInstance) error {
411
412         key, rnibErr := common.ValidateAndBuildE2TInstanceKey(e2tInstance.Address)
413
414         if rnibErr != nil {
415                 return rnibErr
416         }
417
418         data, err := json.Marshal(e2tInstance)
419
420         if err != nil {
421                 return common.NewInternalError(err)
422         }
423
424         var pairs []interface{}
425         pairs = append(pairs, key, data)
426
427         err = w.sdl.Set(pairs)
428
429         if err != nil {
430                 return common.NewInternalError(err)
431         }
432
433         return nil
434 }
435
436 func (w *rNibWriterInstance) SaveE2TAddresses(addresses []string) error {
437
438         data, err := json.Marshal(addresses)
439
440         if err != nil {
441                 return common.NewInternalError(err)
442         }
443
444         var pairs []interface{}
445         pairs = append(pairs, E2TAddressesKey, data)
446
447         err = w.sdl.Set(pairs)
448
449         if err != nil {
450                 return common.NewInternalError(err)
451         }
452
453         return nil
454 }
455
456 func (w *rNibWriterInstance) RemoveE2TInstance(address string) error {
457         key, rNibErr := common.ValidateAndBuildE2TInstanceKey(address)
458         if rNibErr != nil {
459                 return rNibErr
460         }
461         err := w.sdl.Remove([]string{key})
462
463         if err != nil {
464                 return common.NewInternalError(err)
465         }
466         return nil
467 }
468
469 func (w *rNibWriterInstance) SaveWithKeyAndMarshal(key string, entity interface{}) error {
470
471         data, err := json.Marshal(entity)
472
473         if err != nil {
474                 return common.NewInternalError(err)
475         }
476
477         var pairs []interface{}
478         pairs = append(pairs, key, data)
479
480         err = w.sdl.Set(pairs)
481
482         if err != nil {
483                 return common.NewInternalError(err)
484         }
485
486         return nil
487 }
488
489 /*
490 UpdateNodebInfoOnConnectionStatusInversion...
491 */
492 func (w *rNibWriterInstance) UpdateNodebInfoOnConnectionStatusInversion(nodebInfo *entities.NodebInfo, event string) error {
493
494         pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
495
496         if err != nil {
497                 return err
498         }
499
500         err = w.sdl.SetAndPublish([]string{w.rnibWriterConfig.StateChangeMessageChannel, event}, pairs)
501
502         if err != nil {
503                 return common.NewInternalError(err)
504         }
505
506         return nil
507 }
508
509 func (w *rNibWriterInstance) RemoveEnb(nodebInfo *entities.NodebInfo) error {
510         keysToRemove, err := w.buildRemoveEnbKeys(nodebInfo)
511         if err != nil {
512                 return err
513         }
514
515         channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanDeletedEvent)
516         err = w.sdl.RemoveAndPublish(channelsAndEvents, keysToRemove)
517
518         if err != nil {
519                 return common.NewInternalError(err)
520         }
521
522         return nil
523 }
524
525 func (w *rNibWriterInstance) UpdateEnb(nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) error {
526
527         pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
528
529         if err != nil {
530                 return err
531         }
532
533         pairs, err = appendEnbCells(nodebInfo.RanName, servedCells, pairs)
534
535         if err != nil {
536                 return err
537         }
538
539         channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanUpdatedEvent)
540         err = w.sdl.SetAndPublish(channelsAndEvents, pairs)
541
542         if err != nil {
543                 return common.NewInternalError(err)
544         }
545
546         return nil
547 }
548
549 /*
550 Close the writer
551 */
552 func Close() {
553         //Nothing to do
554 }
555
556 func appendEnbCells(inventoryName string, cells []*entities.ServedCellInfo, pairs []interface{}) ([]interface{}, error) {
557         for _, cell := range cells {
558                 cellEntity := entities.Cell{Type: entities.Cell_LTE_CELL, Cell: &entities.Cell_ServedCellInfo{ServedCellInfo: cell}}
559                 cellData, err := proto.Marshal(&cellEntity)
560                 if err != nil {
561                         return pairs, common.NewInternalError(err)
562                 }
563                 key, rNibErr := common.ValidateAndBuildCellIdKey(cell.GetCellId())
564                 if rNibErr != nil {
565                         return pairs, rNibErr
566                 }
567                 pairs = append(pairs, key, cellData)
568                 key, rNibErr = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetPci())
569                 if rNibErr != nil {
570                         return pairs, rNibErr
571                 }
572                 pairs = append(pairs, key, cellData)
573         }
574         return pairs, nil
575 }
576
577 func appendGnbCells(inventoryName string, cells []*entities.ServedNRCell, pairs []interface{}) ([]interface{}, error) {
578         for _, cell := range cells {
579                 cellEntity := entities.Cell{Type: entities.Cell_NR_CELL, Cell: &entities.Cell_ServedNrCell{ServedNrCell: cell}}
580                 cellData, err := proto.Marshal(&cellEntity)
581                 if err != nil {
582                         return pairs, common.NewInternalError(err)
583                 }
584                 key, rNibErr := common.ValidateAndBuildNrCellIdKey(cell.GetServedNrCellInformation().GetCellId())
585                 if rNibErr != nil {
586                         return pairs, rNibErr
587                 }
588                 pairs = append(pairs, key, cellData)
589                 key, rNibErr = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetServedNrCellInformation().GetNrPci())
590                 if rNibErr != nil {
591                         return pairs, rNibErr
592                 }
593                 pairs = append(pairs, key, cellData)
594         }
595         return pairs, nil
596 }