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