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