a44f38822cf10cf53144f48314d2318894dae075
[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         "encoding/json"
24         "fmt"
25         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
26         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
27         "github.com/golang/protobuf/proto"
28 )
29
30 const E2TAddressesKey = "E2TAddresses"
31
32 type rNibWriterInstance struct {
33         sdl common.ISdlInstance
34 }
35
36 /*
37 RNibWriter interface allows saving data to the redis DB
38 */
39 type RNibWriter interface {
40         SaveNodeb(nbIdentity *entities.NbIdentity, nb *entities.NodebInfo) error
41         UpdateNodebInfo(nodebInfo *entities.NodebInfo) error
42         SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error
43         SaveE2TInstance(e2tInstance *entities.E2TInstance) error
44         SaveE2TAddresses(addresses []string) error
45         RemoveE2TInstance(e2tAddress string) error
46         UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error
47         RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error
48 }
49
50 /*
51 GetRNibWriter returns reference to RNibWriter
52 */
53
54 func GetRNibWriter(sdl common.ISdlInstance) RNibWriter {
55         return &rNibWriterInstance{sdl: sdl}
56 }
57
58
59 func (w *rNibWriterInstance) RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error {
60         cellKeysToRemove := buildCellKeysToRemove(inventoryName, servedNrCells)
61         err := w.sdl.Remove(cellKeysToRemove)
62
63         if err != nil {
64                 return common.NewInternalError(err)
65         }
66
67         return nil
68 }
69
70 /*
71 SaveNodeb saves nodeB entity data in the redis DB according to the specified data model
72 */
73 func (w *rNibWriterInstance) SaveNodeb(nbIdentity *entities.NbIdentity, entity *entities.NodebInfo) error {
74         isNotEmptyIdentity := isNotEmpty(nbIdentity)
75
76         if isNotEmptyIdentity && entity.GetNodeType() == entities.Node_UNKNOWN {
77                 return common.NewValidationError(fmt.Sprintf("#rNibWriter.saveNodeB - Unknown responding node type, entity: %v", entity))
78         }
79         data, err := proto.Marshal(entity)
80         if err != nil {
81                 return common.NewInternalError(err)
82         }
83         var pairs []interface{}
84         key, rNibErr := common.ValidateAndBuildNodeBNameKey(nbIdentity.InventoryName)
85         if rNibErr != nil {
86                 return rNibErr
87         }
88         pairs = append(pairs, key, data)
89
90         if isNotEmptyIdentity {
91                 key, rNibErr = common.ValidateAndBuildNodeBIdKey(entity.GetNodeType().String(), nbIdentity.GlobalNbId.GetPlmnId(), nbIdentity.GlobalNbId.GetNbId())
92                 if rNibErr != nil {
93                         return rNibErr
94                 }
95                 pairs = append(pairs, key, data)
96         }
97
98         if entity.GetEnb() != nil {
99                 pairs, rNibErr = appendEnbCells(nbIdentity.InventoryName, entity.GetEnb().GetServedCells(), pairs)
100                 if rNibErr != nil {
101                         return rNibErr
102                 }
103         }
104         if entity.GetGnb() != nil {
105                 pairs, rNibErr = appendGnbCells(nbIdentity.InventoryName, entity.GetGnb().GetServedNrCells(), pairs)
106                 if rNibErr != nil {
107                         return rNibErr
108                 }
109         }
110         err = w.sdl.Set(pairs)
111         if err != nil {
112                 return common.NewInternalError(err)
113         }
114
115         ranNameIdentity := &entities.NbIdentity{InventoryName: nbIdentity.InventoryName}
116
117         if isNotEmptyIdentity {
118                 nbIdData, err := proto.Marshal(ranNameIdentity)
119                 if err != nil {
120                         return common.NewInternalError(err)
121                 }
122                 err = w.sdl.RemoveMember(entities.Node_UNKNOWN.String(), nbIdData)
123                 if err != nil {
124                         return common.NewInternalError(err)
125                 }
126         } else {
127                 nbIdentity = ranNameIdentity
128         }
129
130         nbIdData, err := proto.Marshal(nbIdentity)
131         if err != nil {
132                 return common.NewInternalError(err)
133         }
134         err = w.sdl.AddMember(entity.GetNodeType().String(), nbIdData)
135         if err != nil {
136                 return common.NewInternalError(err)
137         }
138         return nil
139 }
140
141 func (w *rNibWriterInstance) UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error {
142
143         pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
144
145         if err != nil {
146                 return err
147         }
148
149         pairs, err = appendGnbCells(nodebInfo.RanName, servedNrCells, pairs)
150
151         if err != nil {
152                 return err
153         }
154
155         err = w.sdl.Set(pairs)
156
157         if err != nil {
158                 return common.NewInternalError(err)
159         }
160
161         return nil
162 }
163
164 func buildCellKeysToRemove(inventoryName string, servedNrCellsToRemove []*entities.ServedNRCell) []string {
165
166         cellKeysToRemove := []string{}
167
168         for _, cell := range servedNrCellsToRemove {
169
170                 key, _ := common.ValidateAndBuildNrCellIdKey(cell.GetServedNrCellInformation().GetCellId())
171
172                 if len(key) != 0 {
173                         cellKeysToRemove = append(cellKeysToRemove, key)
174                 }
175
176                 key, _ = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetServedNrCellInformation().GetNrPci())
177
178                 if len(key) != 0 {
179                         cellKeysToRemove = append(cellKeysToRemove, key)
180                 }
181         }
182
183         return cellKeysToRemove
184 }
185
186 func buildUpdateNodebInfoPairs(nodebInfo *entities.NodebInfo) ([]interface{}, error) {
187         nodebNameKey, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.GetRanName())
188
189         if rNibErr != nil {
190                 return []interface{}{}, rNibErr
191         }
192
193         nodebIdKey, buildNodebIdKeyError := common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId())
194
195         data, err := proto.Marshal(nodebInfo)
196
197         if err != nil {
198                 return []interface{}{}, common.NewInternalError(err)
199         }
200
201         pairs := []interface{}{nodebNameKey, data}
202
203         if buildNodebIdKeyError == nil {
204                 pairs = append(pairs, nodebIdKey, data)
205         }
206
207         return pairs, nil
208 }
209
210 /*
211 UpdateNodebInfo...
212 */
213 func (w *rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error {
214
215         pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
216
217         if err != nil {
218                 return err
219         }
220
221         err = w.sdl.Set(pairs)
222
223         if err != nil {
224                 return common.NewInternalError(err)
225         }
226
227         return nil
228 }
229
230 /*
231 SaveRanLoadInformation stores ran load information for the provided ran
232 */
233 func (w *rNibWriterInstance) SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error {
234
235         key, rnibErr := common.ValidateAndBuildRanLoadInformationKey(inventoryName)
236
237         if rnibErr != nil {
238                 return rnibErr
239         }
240
241         data, err := proto.Marshal(ranLoadInformation)
242
243         if err != nil {
244                 return common.NewInternalError(err)
245         }
246
247         var pairs []interface{}
248         pairs = append(pairs, key, data)
249
250         err = w.sdl.Set(pairs)
251
252         if err != nil {
253                 return common.NewInternalError(err)
254         }
255
256         return nil
257 }
258
259 func (w *rNibWriterInstance) SaveE2TInstance(e2tInstance *entities.E2TInstance) error {
260
261         key, rnibErr := common.ValidateAndBuildE2TInstanceKey(e2tInstance.Address)
262
263         if rnibErr != nil {
264                 return rnibErr
265         }
266
267         data, err := json.Marshal(e2tInstance)
268
269         if err != nil {
270                 return common.NewInternalError(err)
271         }
272
273         var pairs []interface{}
274         pairs = append(pairs, key, data)
275
276         err = w.sdl.Set(pairs)
277
278         if err != nil {
279                 return common.NewInternalError(err)
280         }
281
282         return nil
283 }
284
285 func (w *rNibWriterInstance) SaveE2TAddresses(addresses []string) error {
286
287         data, err := json.Marshal(addresses)
288
289         if err != nil {
290                 return common.NewInternalError(err)
291         }
292
293         var pairs []interface{}
294         pairs = append(pairs, E2TAddressesKey, data)
295
296         err = w.sdl.Set(pairs)
297
298         if err != nil {
299                 return common.NewInternalError(err)
300         }
301
302         return nil
303 }
304
305 func (w *rNibWriterInstance) RemoveE2TInstance(address string) error {
306         key, rNibErr := common.ValidateAndBuildE2TInstanceKey(address)
307         if rNibErr != nil {
308                 return rNibErr
309         }
310         err := w.sdl.Remove([]string{key})
311
312         if err != nil {
313                 return common.NewInternalError(err)
314         }
315         return nil
316 }
317
318 /*
319 Close the writer
320 */
321 func Close() {
322         //Nothing to do
323 }
324
325 func appendEnbCells(inventoryName string, cells []*entities.ServedCellInfo, pairs []interface{}) ([]interface{}, error) {
326         for _, cell := range cells {
327                 cellEntity := entities.Cell{Type: entities.Cell_LTE_CELL, Cell: &entities.Cell_ServedCellInfo{ServedCellInfo: cell}}
328                 cellData, err := proto.Marshal(&cellEntity)
329                 if err != nil {
330                         return pairs, common.NewInternalError(err)
331                 }
332                 key, rNibErr := common.ValidateAndBuildCellIdKey(cell.GetCellId())
333                 if rNibErr != nil {
334                         return pairs, rNibErr
335                 }
336                 pairs = append(pairs, key, cellData)
337                 key, rNibErr = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetPci())
338                 if rNibErr != nil {
339                         return pairs, rNibErr
340                 }
341                 pairs = append(pairs, key, cellData)
342         }
343         return pairs, nil
344 }
345
346 func appendGnbCells(inventoryName string, cells []*entities.ServedNRCell, pairs []interface{}) ([]interface{}, error) {
347         for _, cell := range cells {
348                 cellEntity := entities.Cell{Type: entities.Cell_NR_CELL, Cell: &entities.Cell_ServedNrCell{ServedNrCell: cell}}
349                 cellData, err := proto.Marshal(&cellEntity)
350                 if err != nil {
351                         return pairs, common.NewInternalError(err)
352                 }
353                 key, rNibErr := common.ValidateAndBuildNrCellIdKey(cell.GetServedNrCellInformation().GetCellId())
354                 if rNibErr != nil {
355                         return pairs, rNibErr
356                 }
357                 pairs = append(pairs, key, cellData)
358                 key, rNibErr = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetServedNrCellInformation().GetNrPci())
359                 if rNibErr != nil {
360                         return pairs, rNibErr
361                 }
362                 pairs = append(pairs, key, cellData)
363         }
364         return pairs, nil
365 }
366
367 func isNotEmpty(nbIdentity *entities.NbIdentity) bool {
368         return nbIdentity.GlobalNbId != nil && nbIdentity.GlobalNbId.PlmnId != "" && nbIdentity.GlobalNbId.NbId != ""
369 }