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