6f3327356649494ee9d4d242c30cd1f5e212ef5d
[ric-plt/nodeb-rnib.git] / reader / rNibReader.go
1 //
2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 2019 Nokia
4 // Copyright 2023 Capgemini
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 //
10 //      http://www.apache.org/licenses/LICENSE-2.0
11 //
12 // Unless required by applicable law or agreed to in writing, software
13 // distributed under the License is distributed on an "AS IS" BASIS,
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 // See the License for the specific language governing permissions and
16 // limitations under the License.
17
18 //  This source code is part of the near-RT RIC (RAN Intelligent Controller)
19 //  platform project (RICP).
20
21 package reader
22
23 import (
24         "encoding/json"
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         "reflect"
29 )
30
31 const E2TAddressesKey = "E2TAddresses"
32
33 type rNibReaderInstance struct {
34         sdl        common.ISdlInstance //Deprecated: Will be removed in a future release and replaced by sdlStorage
35         sdlStorage common.ISdlSyncStorage
36         ns         string
37 }
38
39 /*
40 RNibReader interface allows retrieving data from redis BD by various keys
41 */
42 type RNibReader interface {
43         // GetNodeb retrieves responding nodeb entity from redis DB by nodeb inventory name
44         GetNodeb(inventoryName string) (*entities.NodebInfo, error)
45         // GetNodebByGlobalNbId retrieves responding nodeb entity from redis DB by nodeb global Id
46         GetNodebByGlobalNbId(nodeType entities.Node_Type, globalNbId *entities.GlobalNbId, cuupId string,duid string) (*entities.NodebInfo, error)
47         // GetCellList retrieves the list of cell entities belonging to responding nodeb entity from redis DB by nodeb inventory name
48         GetCellList(inventoryName string) (*entities.Cells, error)
49         // GetListGnbIds retrieves the list of gNodeb identity entities
50         GetListGnbIds() ([]*entities.NbIdentity, error)
51         // GetListEnbIds retrieves the list of eNodeb identity entities
52         GetListEnbIds() ([]*entities.NbIdentity, error)
53         // Close closes reader's pool
54         GetCountGnbList() (int, error)
55         // GetCell retrieves the cell entity belonging to responding nodeb from redis DB by nodeb inventory name and cell pci
56         GetCell(inventoryName string, pci uint32) (*entities.Cell, error)
57         // GetCellById retrieves the cell entity from redis DB by cell type and cell Id
58         GetCellById(cellType entities.Cell_Type, cellId string) (*entities.Cell, error)
59         // GetListNodebIds returns the full list of Nodeb identity entities
60         GetListNodebIds() ([]*entities.NbIdentity, error)
61         // GetRanLoadInformation retrieves nodeb load information entity from redis DB by nodeb inventory name
62         GetRanLoadInformation(inventoryName string) (*entities.RanLoadInformation, error)
63
64         GetE2TInstance(address string) (*entities.E2TInstance, error)
65
66         GetE2TInstances(addresses []string) ([]*entities.E2TInstance, error)
67
68         GetE2TAddresses() ([]string, error)
69
70         GetGeneralConfiguration() (*entities.GeneralConfiguration, error)
71
72         GetRanFunctionDefinition(inventoryName string, Oid string) ([]string, error)
73 }
74
75 //GetNewRNibReader returns reference to RNibReader
76 func GetNewRNibReader(storage common.ISdlSyncStorage) RNibReader {
77         return &rNibReaderInstance{
78                 sdl: nil,
79                 sdlStorage: storage,
80                 ns:         common.GetRNibNamespace(),
81         }
82 }
83
84 //GetRanFunctionDefinition from the OID
85 func (w *rNibReaderInstance) GetRanFunctionDefinition(inventoryName string, oid string) ([]string, error){
86     nb, err := w.GetNodeb (inventoryName)
87     if (nb.GetGnb() != nil) {
88         ranFunction := nb.GetGnb().RanFunctions
89         functionDefinitionList := make([]string, 0)
90         for _, ranFunction := range ranFunction {
91             if (oid == ranFunction.RanFunctionOid) {
92                 functionDefinitionList = append(functionDefinitionList ,ranFunction.RanFunctionDefinition)
93                 }
94         }
95         return functionDefinitionList, err
96     }
97     return nil, common.NewResourceNotFoundErrorf("#rNibReader.GetCellList - served cells not found. Responding node RAN name: %    s.", inventoryName)
98 }
99
100 //GetRNibReader returns reference to RNibReader
101 //Deprecated: Will be removed in a future release, please use GetNewRNibReader instead.
102 func GetRNibReader(sdl common.ISdlInstance) RNibReader {
103         return &rNibReaderInstance{
104                 sdl:        sdl,
105                 sdlStorage: nil,
106                 ns:         "",
107         }
108 }
109
110 func (w *rNibReaderInstance) GetNodeb(inventoryName string) (*entities.NodebInfo, error) {
111         key, rNibErr := common.ValidateAndBuildNodeBNameKey(inventoryName)
112         if rNibErr != nil {
113                 return nil, rNibErr
114         }
115         nbInfo := &entities.NodebInfo{}
116         err := w.getByKeyAndUnmarshal(key, nbInfo)
117         if err != nil {
118                 return nil, err
119         }
120         return nbInfo, nil
121 }
122
123 func (w *rNibReaderInstance) GetNodebByGlobalNbId(nodeType entities.Node_Type, globalNbId *entities.GlobalNbId, cuupid string, duid string) (*entities.NodebInfo, error) {
124         key, rNibErr := common.ValidateAndBuildNodeBIdKey(nodeType.String(), globalNbId.GetPlmnId(), globalNbId.GetNbId(), cuupid, duid)
125         if rNibErr != nil {
126                 return nil, rNibErr
127         }
128         nbInfo := &entities.NodebInfo{}
129         err := w.getByKeyAndUnmarshal(key, nbInfo)
130         if err != nil {
131                 return nil, err
132         }
133         return nbInfo, nil
134 }
135
136 func (w *rNibReaderInstance) GetCellList(inventoryName string) (*entities.Cells, error) {
137         cells := &entities.Cells{}
138         nb, err := w.GetNodeb(inventoryName)
139         if err != nil {
140                 return nil, err
141         }
142         if nb.GetEnb() != nil && len(nb.GetEnb().GetServedCells()) > 0 {
143                 cells.Type = entities.Cell_LTE_CELL
144                 cells.List = &entities.Cells_ServedCellInfos{ServedCellInfos: &entities.ServedCellInfoList{ServedCells: nb.GetEnb().GetServedCells()}}
145                 return cells, nil
146         }
147         if nb.GetGnb() != nil && len(nb.GetGnb().GetServedNrCells()) > 0 {
148                 cells.Type = entities.Cell_NR_CELL
149                 cells.List = &entities.Cells_ServedNrCells{ServedNrCells: &entities.ServedNRCellList{ServedCells: nb.GetGnb().GetServedNrCells()}}
150                 return cells, nil
151         }
152         return nil, common.NewResourceNotFoundErrorf("#rNibReader.GetCellList - served cells not found. Responding node RAN name: %s.", inventoryName)
153 }
154
155 func (w *rNibReaderInstance) GetListGnbIds() ([]*entities.NbIdentity, error) {
156         return w.getListNodebIdsByType(entities.Node_GNB.String())
157 }
158
159 func (w *rNibReaderInstance) GetListEnbIds() ([]*entities.NbIdentity, error) {
160         return w.getListNodebIdsByType(entities.Node_ENB.String())
161 }
162
163 func (w *rNibReaderInstance) GetCountGnbList() (int, error) {
164         var size int64
165         var err error
166         if w.sdlStorage != nil {
167                 size, err = w.sdlStorage.GroupSize(w.ns, entities.Node_GNB.String())
168         } else {
169                 size, err = w.sdl.GroupSize(entities.Node_GNB.String())
170         }
171         if err != nil {
172                 return 0, common.NewInternalError(err)
173         }
174         return int(size), nil
175 }
176
177 func (w *rNibReaderInstance) GetCell(inventoryName string, pci uint32) (*entities.Cell, error) {
178         key, rNibErr := common.ValidateAndBuildCellNamePciKey(inventoryName, pci)
179         if rNibErr != nil {
180                 return nil, rNibErr
181         }
182         cell := &entities.Cell{}
183         err := w.getByKeyAndUnmarshal(key, cell)
184         if err != nil {
185                 return nil, err
186         }
187         return cell, err
188 }
189
190 func (w *rNibReaderInstance) GetCellById(cellType entities.Cell_Type, cellId string) (*entities.Cell, error) {
191         var key string
192         var rNibErr error
193         if cellType == entities.Cell_LTE_CELL {
194                 key, rNibErr = common.ValidateAndBuildCellIdKey(cellId)
195         } else if cellType == entities.Cell_NR_CELL {
196                 key, rNibErr = common.ValidateAndBuildNrCellIdKey(cellId)
197         } else {
198                 return nil, common.NewValidationErrorf("#rNibReader.GetCellById - invalid cell type: %v", cellType)
199         }
200         if rNibErr != nil {
201                 return nil, rNibErr
202         }
203         cell := &entities.Cell{}
204         err := w.getByKeyAndUnmarshal(key, cell)
205         if err != nil {
206                 return nil, err
207         }
208         return cell, err
209 }
210
211 func (w *rNibReaderInstance) GetListNodebIds() ([]*entities.NbIdentity, error) {
212         var dataEnb, dataGnb []string
213         var err error
214         if w.sdlStorage != nil {
215                 dataEnb, err = w.sdlStorage.GetMembers(w.ns, entities.Node_ENB.String())
216         } else {
217                 dataEnb, err = w.sdl.GetMembers(entities.Node_ENB.String())
218         }
219         if err != nil {
220                 return nil, common.NewInternalError(err)
221         }
222         if w.sdlStorage != nil {
223                 dataGnb, err = w.sdlStorage.GetMembers(w.ns, entities.Node_GNB.String())
224         } else {
225                 dataGnb, err = w.sdl.GetMembers(entities.Node_GNB.String())
226         }
227         if err != nil {
228                 return nil, common.NewInternalError(err)
229         }
230         allIds := append(dataEnb, dataGnb...)
231         data, rnibErr := w.unmarshalIdentityList(allIds)
232         return data, rnibErr
233 }
234
235 func (w *rNibReaderInstance) GetRanLoadInformation(inventoryName string) (*entities.RanLoadInformation, error) {
236         key, rNibErr := common.ValidateAndBuildRanLoadInformationKey(inventoryName)
237         if rNibErr != nil {
238                 return nil, rNibErr
239         }
240         loadInfo := &entities.RanLoadInformation{}
241         err := w.getByKeyAndUnmarshal(key, loadInfo)
242         if err != nil {
243                 return nil, err
244         }
245         return loadInfo, err
246 }
247
248 func (w *rNibReaderInstance) GetE2TInstance(address string) (*entities.E2TInstance, error) {
249         key, rNibErr := common.ValidateAndBuildE2TInstanceKey(address)
250         if rNibErr != nil {
251                 return nil, rNibErr
252         }
253         e2tInstance := &entities.E2TInstance{}
254         err := w.getByKeyAndUnmarshalJson(key, e2tInstance)
255         if err != nil {
256                 return nil, err
257         }
258         return e2tInstance, err
259 }
260
261 func (w *rNibReaderInstance) GetE2TInstances(addresses []string) ([]*entities.E2TInstance, error) {
262         var data map[string]interface{}
263         var err error
264
265         keys := common.MapE2TAddressesToKeys(addresses)
266
267         e2tInstances := []*entities.E2TInstance{}
268
269         if w.sdlStorage != nil {
270                 data, err = w.sdlStorage.Get(w.ns, keys)
271         } else {
272                 data, err = w.sdl.Get(keys)
273         }
274
275         if err != nil {
276                 return []*entities.E2TInstance{}, common.NewInternalError(err)
277         }
278
279         if len(data) == 0 {
280                 return []*entities.E2TInstance{}, common.NewResourceNotFoundErrorf("#rNibReader.GetE2TInstances - e2t instances not found")
281         }
282
283         for _, v := range keys {
284
285                 if data[v] != nil {
286                         var e2tInstance entities.E2TInstance
287                         err = json.Unmarshal([]byte(data[v].(string)), &e2tInstance)
288                         if err != nil {
289                                 continue
290                         }
291
292                         e2tInstances = append(e2tInstances, &e2tInstance)
293                 }
294         }
295
296         return e2tInstances, nil
297 }
298
299 func (w *rNibReaderInstance) GetE2TAddresses() ([]string, error) {
300         var e2tAddresses []string
301         err := w.getByKeyAndUnmarshalJson(E2TAddressesKey, &e2tAddresses)
302         if err != nil {
303                 return nil, err
304         }
305         return e2tAddresses, err
306 }
307
308 func (w *rNibReaderInstance) GetGeneralConfiguration() (*entities.GeneralConfiguration, error) {
309         config := &entities.GeneralConfiguration{}
310         key := common.BuildGeneralConfigurationKey()
311
312         err := w.getByKeyAndUnmarshalJson(key, config)
313
314         return config, err
315 }
316
317 func (w *rNibReaderInstance) getByKeyAndUnmarshalJson(key string, entity interface{}) error {
318         var data map[string]interface{}
319         var err error
320         if w.sdlStorage != nil {
321                 data, err = w.sdlStorage.Get(w.ns, []string{key})
322         } else {
323                 data, err = w.sdl.Get([]string{key})
324         }
325
326         if err != nil {
327                 return common.NewInternalError(err)
328         }
329
330         if data != nil && data[key] != nil {
331                 err = json.Unmarshal([]byte(data[key].(string)), entity)
332                 if err != nil {
333                         return common.NewInternalError(err)
334                 }
335                 return nil
336         }
337         return common.NewResourceNotFoundErrorf("#rNibReader.getByKeyAndUnmarshalJson - entity of type %s not found. Key: %s", reflect.TypeOf(entity).String(), key)
338 }
339
340 func (w *rNibReaderInstance) getByKeyAndUnmarshal(key string, entity proto.Message) error {
341         var data map[string]interface{}
342         var err error
343         if w.sdlStorage != nil {
344                 data, err = w.sdlStorage.Get(w.ns, []string{key})
345         } else {
346                 data, err = w.sdl.Get([]string{key})
347         }
348
349         if err != nil {
350                 return common.NewInternalError(err)
351         }
352         if data != nil && data[key] != nil {
353                 err = proto.Unmarshal([]byte(data[key].(string)), entity)
354                 if err != nil {
355                         return common.NewInternalError(err)
356                 }
357                 return nil
358         }
359         return common.NewResourceNotFoundErrorf("#rNibReader.getByKeyAndUnmarshal - entity of type %s not found. Key: %s", reflect.TypeOf(entity).String(), key)
360 }
361
362 func (w *rNibReaderInstance) getListNodebIdsByType(nbType string) ([]*entities.NbIdentity, error) {
363         var data []string
364         var err error
365         if w.sdlStorage != nil {
366                 data, err = w.sdlStorage.GetMembers(w.ns, nbType)
367         } else {
368                 data, err = w.sdl.GetMembers(nbType)
369         }
370         if err != nil {
371                 return nil, common.NewInternalError(err)
372         }
373         return w.unmarshalIdentityList(data)
374 }
375
376 func (w *rNibReaderInstance) unmarshalIdentityList(data []string) ([]*entities.NbIdentity, error) {
377         var members []*entities.NbIdentity
378         for _, d := range data {
379                 member := entities.NbIdentity{}
380                 err := proto.Unmarshal([]byte(d), &member)
381                 if err != nil {
382                         return nil, common.NewInternalError(err)
383                 }
384                 members = append(members, &member)
385         }
386         return members, nil
387 }
388
389 //Close the reader
390 func Close() {
391         // Nothing to do
392 }