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