66a299e038649a15001889ca54ba12a882052d35
[ric-plt/e2mgr.git] / E2Manager / rNibWriter / rNibWriter.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
18 package rNibWriter
19
20 import (
21         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
22         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
23         "errors"
24         "fmt"
25         "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
26         "github.com/golang/protobuf/proto"
27 )
28
29
30
31 var writerPool *common.Pool
32
33 type rNibWriterInstance struct {
34         sdl       *common.ISdlInstance
35         namespace string
36 }
37 /*
38 RNibWriter interface allows saving data to the redis DB
39  */
40 type RNibWriter interface {
41         SaveNodeb(nbIdentity *entities.NbIdentity, nb *entities.NodebInfo) common.IRNibError
42         SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) common.IRNibError
43 }
44 /*
45 Init initializes the infrastructure required for the RNibWriter instance
46  */
47 func Init(namespace string, poolSize int) {
48         initPool(poolSize,
49                 func() interface{} {
50                         var sdlI common.ISdlInstance = sdlgo.NewSdlInstance(namespace, sdlgo.NewDatabase())
51                         return &rNibWriterInstance{sdl: &sdlI, namespace: namespace}
52                 },
53                 func(obj interface{}) {
54                         (*obj.(*rNibWriterInstance).sdl).Close()
55                 })
56 }
57 /*
58 InitPool initializes the writer's instances pool
59  */
60 func initPool(poolSize int, newObj func() interface{}, destroyObj func(interface{})) {
61         writerPool = common.NewPool(poolSize, newObj, destroyObj)
62 }
63 /*
64 GetRNibWriter returns RNibWriter instance from the pool
65  */
66 func GetRNibWriter() RNibWriter {
67         return writerPool.Get().(RNibWriter)
68 }
69 /*
70 SaveNodeb saves nodeB entity data in the redis DB according to the specified data model
71  */
72 func (w *rNibWriterInstance) SaveNodeb(nbIdentity *entities.NbIdentity, entity *entities.NodebInfo) common.IRNibError {
73
74         isNotEmptyIdentity := isNotEmpty(nbIdentity)
75
76         if isNotEmptyIdentity && entity.GetNodeType() == entities.Node_UNKNOWN{
77                 return common.NewValidationError(errors.New( fmt.Sprintf("#rNibWriter.saveNodeB - Unknown responding node type, entity: %v", entity)))
78         }
79         defer writerPool.Put(w)
80         data, err := proto.Marshal(entity)
81         if err != nil {
82                 return common.NewInternalError(err)
83         }
84         var pairs []interface{}
85         key, rNibErr := common.ValidateAndBuildNodeBNameKey(nbIdentity.InventoryName)
86         if rNibErr != nil{
87                 return rNibErr
88         }
89         pairs = append(pairs, key, data)
90
91         if isNotEmptyIdentity {
92                 key, rNibErr = common.ValidateAndBuildNodeBIdKey(entity.GetNodeType().String(), nbIdentity.GlobalNbId.GetPlmnId(), nbIdentity.GlobalNbId.GetNbId())
93                 if rNibErr != nil{
94                         return rNibErr
95                 }
96                 pairs = append(pairs, key, data)
97         }
98
99         if entity.GetEnb() != nil {
100                 pairs, rNibErr = appendEnbCells(nbIdentity, entity.GetEnb().GetServedCells(), pairs)
101                 if rNibErr != nil{
102                         return rNibErr
103                 }
104         }
105         if entity.GetGnb() != nil {
106                 pairs, rNibErr = appendGnbCells(nbIdentity, entity.GetGnb().GetServedNrCells(), pairs)
107                 if rNibErr != nil{
108                         return rNibErr
109                 }
110         }
111         err = (*w.sdl).Set(pairs)
112         if err != nil {
113                 return common.NewInternalError(err)
114         }
115
116         ranNameIdentity := &entities.NbIdentity{InventoryName: nbIdentity.InventoryName}
117
118         if isNotEmptyIdentity{
119                 nbIdData, err := proto.Marshal(ranNameIdentity)
120                 if err != nil {
121                         return common.NewInternalError(err)
122                 }
123                 err = (*w.sdl).RemoveMember(entities.Node_UNKNOWN.String(), nbIdData)
124                 if err != nil {
125                         return common.NewInternalError(err)
126                 }
127         } else {
128                 nbIdentity = ranNameIdentity
129         }
130
131         nbIdData, err := proto.Marshal(nbIdentity)
132         if err != nil {
133                 return common.NewInternalError(err)
134         }
135         err = (*w.sdl).AddMember(entity.GetNodeType().String(), nbIdData)
136         if err != nil {
137                 return common.NewInternalError(err)
138         }
139         return nil
140 }
141
142 /*
143 SaveRanLoadInformation stores ran load information for the provided ran
144 */
145 func (w *rNibWriterInstance) SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) common.IRNibError {
146
147         defer writerPool.Put(w)
148
149         key, rnibErr:= common.ValidateAndBuildRanLoadInformationKey(inventoryName)
150
151         if rnibErr != nil {
152                 return rnibErr
153         }
154
155         data, err := proto.Marshal(ranLoadInformation)
156
157         if err != nil {
158                 return common.NewInternalError(err)
159         }
160
161         var pairs []interface{}
162         pairs = append(pairs, key, data)
163
164         err = (*w.sdl).Set(pairs)
165
166         if err != nil {
167                 return common.NewInternalError(err)
168         }
169
170         return nil
171 }
172
173 /*
174 Close closes writer's pool
175  */
176 func Close(){
177         writerPool.Close()
178 }
179
180 func appendEnbCells(nbIdentity *entities.NbIdentity, cells []*entities.ServedCellInfo, pairs []interface{}) ([]interface{}, common.IRNibError) {
181         for _, cell := range cells {
182                 cellEntity := entities.Cell{Type:entities.Cell_LTE_CELL, Cell:&entities.Cell_ServedCellInfo{ServedCellInfo:cell}}
183                 cellData, err := proto.Marshal(&cellEntity)
184                 if err != nil {
185                         return pairs, common.NewInternalError(err)
186                 }
187                 key, rNibErr := common.ValidateAndBuildCellIdKey(cell.GetCellId())
188                 if rNibErr != nil{
189                         return pairs, rNibErr
190                 }
191                 pairs = append(pairs, key, cellData)
192                 key, rNibErr = common.ValidateAndBuildCellNamePciKey(nbIdentity.InventoryName, cell.GetPci())
193                 if rNibErr != nil{
194                         return pairs, rNibErr
195                 }
196                 pairs = append(pairs, key, cellData)
197         }
198         return pairs, nil
199 }
200
201 func appendGnbCells(nbIdentity *entities.NbIdentity, cells  []*entities.ServedNRCell, pairs []interface{}) ([]interface{}, common.IRNibError) {
202         for _, cell := range cells {
203                 cellEntity := entities.Cell{Type:entities.Cell_NR_CELL, Cell:&entities.Cell_ServedNrCell{ServedNrCell:cell}}
204                 cellData, err := proto.Marshal(&cellEntity)
205                 if err != nil {
206                         return pairs, common.NewInternalError(err)
207                 }
208                 key, rNibErr := common.ValidateAndBuildNrCellIdKey(cell.GetServedNrCellInformation().GetCellId())
209                 if rNibErr != nil{
210                         return pairs, rNibErr
211                 }
212                 pairs = append(pairs, key, cellData)
213                 key, rNibErr = common.ValidateAndBuildCellNamePciKey(nbIdentity.InventoryName, cell.GetServedNrCellInformation().GetNrPci())
214                 if rNibErr != nil{
215                         return pairs, rNibErr
216                 }
217                 pairs = append(pairs, key, cellData)
218         }
219         return pairs, nil
220 }
221
222 func isNotEmpty(nbIdentity *entities.NbIdentity) bool {
223         return nbIdentity.GlobalNbId != nil && nbIdentity.GlobalNbId.PlmnId != "" && nbIdentity.GlobalNbId.NbId != ""
224 }