Merge "[RIC-384] Update ran_function.proto"
[ric-plt/nodeb-rnib.git] / reader / rNibReader.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 reader
21
22 import (
23         "encoding/json"
24         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
25         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
26         "github.com/golang/protobuf/proto"
27         "reflect"
28 )
29
30 const E2TAddressesKey = "E2TAddresses"
31
32 type rNibReaderInstance struct {
33         sdl common.ISdlInstance
34 }
35
36 /*
37 RNibReader interface allows retrieving data from redis BD by various keys
38 */
39 type RNibReader interface {
40         // GetNodeb retrieves responding nodeb entity from redis DB by nodeb inventory name
41         GetNodeb(inventoryName string) (*entities.NodebInfo, error)
42         // GetNodebByGlobalNbId retrieves responding nodeb entity from redis DB by nodeb global Id
43         GetNodebByGlobalNbId(nodeType entities.Node_Type, globalNbId *entities.GlobalNbId) (*entities.NodebInfo, error)
44         // GetCellList retrieves the list of cell entities belonging to responding nodeb entity from redis DB by nodeb inventory name
45         GetCellList(inventoryName string) (*entities.Cells, error)
46         // GetListGnbIds retrieves the list of gNodeb identity entities
47         GetListGnbIds() ([]*entities.NbIdentity, error)
48         // GetListEnbIds retrieves the list of eNodeb identity entities
49         GetListEnbIds() ([]*entities.NbIdentity, error)
50         // Close closes reader's pool
51         GetCountGnbList() (int, error)
52         // GetCell retrieves the cell entity belonging to responding nodeb from redis DB by nodeb inventory name and cell pci
53         GetCell(inventoryName string, pci uint32) (*entities.Cell, error)
54         // GetCellById retrieves the cell entity from redis DB by cell type and cell Id
55         GetCellById(cellType entities.Cell_Type, cellId string) (*entities.Cell, error)
56         // GetListNodebIds returns the full list of Nodeb identity entities
57         GetListNodebIds() ([]*entities.NbIdentity, error)
58         // GetRanLoadInformation retrieves nodeb load information entity from redis DB by nodeb inventory name
59         GetRanLoadInformation(inventoryName string) (*entities.RanLoadInformation, error)
60
61         GetE2TInstance(address string) (*entities.E2TInstance, error)
62
63         GetE2TInstances(addresses []string) ([]*entities.E2TInstance, error)
64
65         GetE2TAddresses() ([]string, error)
66 }
67
68 /*
69 GetRNibReader returns reference to RNibReader
70 */
71 func GetRNibReader(sdl common.ISdlInstance) RNibReader {
72         return &rNibReaderInstance{sdl: sdl}
73 }
74
75 func (w *rNibReaderInstance) GetNodeb(inventoryName string) (*entities.NodebInfo, error) {
76         key, rNibErr := common.ValidateAndBuildNodeBNameKey(inventoryName)
77         if rNibErr != nil {
78                 return nil, rNibErr
79         }
80         nbInfo := &entities.NodebInfo{}
81         err := w.getByKeyAndUnmarshal(key, nbInfo)
82         if err != nil {
83                 return nil, err
84         }
85         return nbInfo, nil
86 }
87
88 func (w *rNibReaderInstance) GetNodebByGlobalNbId(nodeType entities.Node_Type, globalNbId *entities.GlobalNbId) (*entities.NodebInfo, error) {
89         key, rNibErr := common.ValidateAndBuildNodeBIdKey(nodeType.String(), globalNbId.GetPlmnId(), globalNbId.GetNbId())
90         if rNibErr != nil {
91                 return nil, rNibErr
92         }
93         nbInfo := &entities.NodebInfo{}
94         err := w.getByKeyAndUnmarshal(key, nbInfo)
95         if err != nil {
96                 return nil, err
97         }
98         return nbInfo, nil
99 }
100
101 func (w *rNibReaderInstance) GetCellList(inventoryName string) (*entities.Cells, error) {
102         cells := &entities.Cells{}
103         nb, err := w.GetNodeb(inventoryName)
104         if err != nil {
105                 return nil, err
106         }
107         if nb.GetEnb() != nil && len(nb.GetEnb().GetServedCells()) > 0 {
108                 cells.Type = entities.Cell_LTE_CELL
109                 cells.List = &entities.Cells_ServedCellInfos{ServedCellInfos: &entities.ServedCellInfoList{ServedCells: nb.GetEnb().GetServedCells()}}
110                 return cells, nil
111         }
112         if nb.GetGnb() != nil && len(nb.GetGnb().GetServedNrCells()) > 0 {
113                 cells.Type = entities.Cell_NR_CELL
114                 cells.List = &entities.Cells_ServedNrCells{ServedNrCells: &entities.ServedNRCellList{ServedCells: nb.GetGnb().GetServedNrCells()}}
115                 return cells, nil
116         }
117         return nil, common.NewResourceNotFoundErrorf("#rNibReader.GetCellList - served cells not found. Responding node RAN name: %s.", inventoryName)
118 }
119
120 func (w *rNibReaderInstance) GetListGnbIds() ([]*entities.NbIdentity, error) {
121         return w.getListNodebIdsByType(entities.Node_GNB.String())
122 }
123
124 func (w *rNibReaderInstance) GetListEnbIds() ([]*entities.NbIdentity, error) {
125         return w.getListNodebIdsByType(entities.Node_ENB.String())
126 }
127
128 func (w *rNibReaderInstance) GetCountGnbList() (int, error) {
129         size, err := w.sdl.GroupSize(entities.Node_GNB.String())
130         if err != nil {
131                 return 0, common.NewInternalError(err)
132         }
133         return int(size), nil
134 }
135
136 func (w *rNibReaderInstance) GetCell(inventoryName string, pci uint32) (*entities.Cell, error) {
137         key, rNibErr := common.ValidateAndBuildCellNamePciKey(inventoryName, pci)
138         if rNibErr != nil {
139                 return nil, rNibErr
140         }
141         cell := &entities.Cell{}
142         err := w.getByKeyAndUnmarshal(key, cell)
143         if err != nil {
144                 return nil, err
145         }
146         return cell, err
147 }
148
149 func (w *rNibReaderInstance) GetCellById(cellType entities.Cell_Type, cellId string) (*entities.Cell, error) {
150         var key string
151         var rNibErr error
152         if cellType == entities.Cell_LTE_CELL {
153                 key, rNibErr = common.ValidateAndBuildCellIdKey(cellId)
154         } else if cellType == entities.Cell_NR_CELL {
155                 key, rNibErr = common.ValidateAndBuildNrCellIdKey(cellId)
156         } else {
157                 return nil, common.NewValidationErrorf("#rNibReader.GetCellById - invalid cell type: %v", cellType)
158         }
159         if rNibErr != nil {
160                 return nil, rNibErr
161         }
162         cell := &entities.Cell{}
163         err := w.getByKeyAndUnmarshal(key, cell)
164         if err != nil {
165                 return nil, err
166         }
167         return cell, err
168 }
169
170 func (w *rNibReaderInstance) GetListNodebIds() ([]*entities.NbIdentity, error) {
171         dataEnb, err := w.sdl.GetMembers(entities.Node_ENB.String())
172         if err != nil {
173                 return nil, common.NewInternalError(err)
174         }
175         dataGnb, err := w.sdl.GetMembers(entities.Node_GNB.String())
176         if err != nil {
177                 return nil, common.NewInternalError(err)
178         }
179         dataUnknown, err := w.sdl.GetMembers(entities.Node_UNKNOWN.String())
180         if err != nil {
181                 return nil, common.NewInternalError(err)
182         }
183         allIds := append(dataEnb, dataGnb...)
184         allIds = append(allIds, dataUnknown...)
185         data, rnibErr := w.unmarshalIdentityList(allIds)
186         return data, rnibErr
187 }
188
189 func (w *rNibReaderInstance) GetRanLoadInformation(inventoryName string) (*entities.RanLoadInformation, error) {
190         key, rNibErr := common.ValidateAndBuildRanLoadInformationKey(inventoryName)
191         if rNibErr != nil {
192                 return nil, rNibErr
193         }
194         loadInfo := &entities.RanLoadInformation{}
195         err := w.getByKeyAndUnmarshal(key, loadInfo)
196         if err != nil {
197                 return nil, err
198         }
199         return loadInfo, err
200 }
201
202 func (w *rNibReaderInstance) GetE2TInstance(address string) (*entities.E2TInstance, error) {
203         key, rNibErr := common.ValidateAndBuildE2TInstanceKey(address)
204         if rNibErr != nil {
205                 return nil, rNibErr
206         }
207         e2tInstance := &entities.E2TInstance{}
208         err := w.getByKeyAndUnmarshalJson(key, e2tInstance)
209         if err != nil {
210                 return nil, err
211         }
212         return e2tInstance, err
213 }
214
215 func (w *rNibReaderInstance) GetE2TInstances(addresses []string) ([]*entities.E2TInstance, error) {
216         keys := common.MapE2TAddressesToKeys(addresses)
217
218         e2tInstances := []*entities.E2TInstance{}
219
220         data, err := w.sdl.Get(keys)
221
222         if err != nil {
223                 return []*entities.E2TInstance{}, common.NewInternalError(err)
224         }
225
226         if len(data) == 0 {
227                 return []*entities.E2TInstance{}, common.NewResourceNotFoundErrorf("#rNibReader.GetE2TInstances - e2t instances not found")
228         }
229
230         for _, v := range keys {
231
232                 if data[v] != nil {
233                         var e2tInstance entities.E2TInstance
234                         err = json.Unmarshal([]byte(data[v].(string)), &e2tInstance)
235                         if err != nil {
236                                 continue
237                         }
238
239                         e2tInstances = append(e2tInstances, &e2tInstance)
240                 }
241         }
242
243         return e2tInstances, nil
244 }
245
246 func (w *rNibReaderInstance) GetE2TAddresses() ([]string, error) {
247         var e2tAddresses []string
248         err := w.getByKeyAndUnmarshalJson(E2TAddressesKey, &e2tAddresses)
249         if err != nil {
250                 return nil, err
251         }
252         return e2tAddresses, err
253 }
254
255 func (w *rNibReaderInstance) getByKeyAndUnmarshalJson(key string, entity interface{}) error {
256         data, err := w.sdl.Get([]string{key})
257
258         if err != nil {
259                 return common.NewInternalError(err)
260         }
261
262         if data != nil && data[key] != nil {
263                 err = json.Unmarshal([]byte(data[key].(string)), entity)
264                 if err != nil {
265                         return common.NewInternalError(err)
266                 }
267                 return nil
268         }
269         return common.NewResourceNotFoundErrorf("#rNibReader.getByKeyAndUnmarshalJson - entity of type %s not found. Key: %s", reflect.TypeOf(entity).String(), key)
270 }
271
272 func (w *rNibReaderInstance) getByKeyAndUnmarshal(key string, entity proto.Message) error {
273         data, err := w.sdl.Get([]string{key})
274         if err != nil {
275                 return common.NewInternalError(err)
276         }
277         if data != nil && data[key] != nil {
278                 err = proto.Unmarshal([]byte(data[key].(string)), entity)
279                 if err != nil {
280                         return common.NewInternalError(err)
281                 }
282                 return nil
283         }
284         return common.NewResourceNotFoundErrorf("#rNibReader.getByKeyAndUnmarshal - entity of type %s not found. Key: %s", reflect.TypeOf(entity).String(), key)
285 }
286
287 func (w *rNibReaderInstance) getListNodebIdsByType(nbType string) ([]*entities.NbIdentity, error) {
288         data, err := w.sdl.GetMembers(nbType)
289         if err != nil {
290                 return nil, common.NewInternalError(err)
291         }
292         return w.unmarshalIdentityList(data)
293 }
294
295 func (w *rNibReaderInstance) unmarshalIdentityList(data []string) ([]*entities.NbIdentity, error) {
296         var members []*entities.NbIdentity
297         for _, d := range data {
298                 member := entities.NbIdentity{}
299                 err := proto.Unmarshal([]byte(d), &member)
300                 if err != nil {
301                         return nil, common.NewInternalError(err)
302                 }
303                 members = append(members, &member)
304         }
305         return members, nil
306 }
307
308 //Close the reader
309 func Close() {
310         // Nothing to do
311 }