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