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