fda411f7325bcf455e5cbef5fbb4f60db098521e
[ric-plt/e2mgr.git] / E2Manager / handlers / rmrmsghandlers / ric_service_update_handler.go
1 //
2 // Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 //  This source code is part of the near-RT RIC (RAN Intelligent Controller)
17 //  platform project (RICP).
18
19 package rmrmsghandlers
20
21 import (
22         "bytes"
23         "e2mgr/logger"
24         "e2mgr/managers"
25         "e2mgr/models"
26         "e2mgr/rmrCgo"
27         "e2mgr/services"
28         "e2mgr/services/rmrsender"
29         "e2mgr/utils"
30         "encoding/xml"
31         "fmt"
32
33         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
34         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
35 )
36
37 //type FunctionChange int
38
39 const (
40         RAN_FUNCTIONS_ADDED int = 10 + iota
41         RAN_FUNCTIONS_DELETED
42         RAN_FUNCTIONS_MODIFIED
43 )
44
45 type functionDetails struct {
46         functionChange     int
47         functionId         uint32
48         functionDefinition string
49         functionRevision   uint32
50         functionOID        string
51 }
52
53 type RicServiceUpdateHandler struct {
54         logger                  *logger.Logger
55         rmrSender               *rmrsender.RmrSender
56         rNibDataService         services.RNibDataService
57         ranListManager          managers.RanListManager
58         RicServiceUpdateManager managers.IRicServiceUpdateManager
59 }
60
61 func NewRicServiceUpdateHandler(logger *logger.Logger, rmrSender *rmrsender.RmrSender, rNibDataService services.RNibDataService, ranListManager managers.RanListManager, RicServiceUpdateManager managers.IRicServiceUpdateManager) *RicServiceUpdateHandler {
62         return &RicServiceUpdateHandler{
63                 logger:                  logger,
64                 rmrSender:               rmrSender,
65                 rNibDataService:         rNibDataService,
66                 ranListManager:          ranListManager,
67                 RicServiceUpdateManager: RicServiceUpdateManager,
68         }
69 }
70
71 func (h *RicServiceUpdateHandler) Handle(request *models.NotificationRequest) {
72         ranName := request.RanName
73         h.logger.Infof("#RicServiceUpdateHandler.Handle - RAN name: %s - received RIC_SERVICE_UPDATE. Payload: %s", ranName, request.Payload)
74
75         nodebInfo, err := h.rNibDataService.GetNodeb(ranName)
76         if err != nil {
77                 _, ok := err.(*common.ResourceNotFoundError)
78                 if !ok {
79                         h.logger.Errorf("#RicServiceUpdateHandler.Handle - failed to get nodeB entity for ran name: %v due to RNIB Error: %s", ranName, err)
80                 } else {
81                         h.logger.Errorf("#RicServiceUpdateHandler.Handle - nobeB entity of RanName:%s absent in RNIB. Error: %s", ranName, err)
82                 }
83                 return
84         }
85
86         ricServiceUpdate, err := h.parseSetupRequest(request.Payload)
87         if err != nil {
88                 h.logger.Errorf(err.Error())
89                 return
90         }
91         h.logger.Infof("#RicServiceUpdateHandler.Handle - RIC_SERVICE_UPDATE has been parsed successfully %+v", ricServiceUpdate)
92         h.RicServiceUpdateManager.StoreExistingRanFunctions(ranName)
93         h.logger.Infof("#RicServiceUpdate.Handle - Getting the ranFunctions before we do the RIC ServiceUpdate handling")
94
95         if len(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs) == 0 {
96                 h.logger.Errorf("#RicServiceUpdateHandler.Handle - RAN name: %s - RICServiceUpdateIEs empty", ranName)
97                 return
98         }
99
100         ackFunctionIds := h.updateFunctions(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs, nodebInfo)
101         if len(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs) > 1 {
102                 err = h.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
103                 if err != nil {
104                         h.logger.Errorf("#RicServiceUpdateHandler.Handle - RAN name: %s - Failed at UpdateNodebInfoAndPublish. error: %s", nodebInfo.RanName, err)
105                         return
106                 }
107         }
108
109         oldNbIdentity, newNbIdentity := h.ranListManager.UpdateHealthcheckTimeStampReceived(nodebInfo.RanName)
110         err = h.ranListManager.UpdateNbIdentities(nodebInfo.NodeType, []*entities.NbIdentity{oldNbIdentity}, []*entities.NbIdentity{newNbIdentity})
111         if err != nil {
112                 h.logger.Errorf("#RicServiceUpdate.Handle - failed to Update NbIdentities: %s", err)
113                 return
114         }
115
116         updateAck := models.NewServiceUpdateAck(ackFunctionIds, ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs[0].Value.TransactionID)
117         err = h.sendUpdateAck(updateAck, nodebInfo, request)
118         if err != nil {
119                 h.logger.Errorf("#RicServiceUpdate.Handle - failed to send RIC_SERVICE_UPDATE_ACK message to RMR: %s", err)
120                 return
121         }
122
123         h.logger.Infof("#RicServiceUpdate.Handle - Completed successfully")
124         models.UpdateProcedureType(ranName, models.RicServiceUpdateCompleted)
125         h.logger.Debugf("#RicServiceUpdateHandler.Handle  - updating the enum value to RicServiceUpdateCompleted completed")
126 }
127
128 func (h *RicServiceUpdateHandler) sendUpdateAck(updateAck models.RicServiceUpdateAckE2APPDU, nodebInfo *entities.NodebInfo, request *models.NotificationRequest) error {
129         payLoad, err := xml.Marshal(updateAck)
130         if err != nil {
131                 h.logger.Errorf("#RicServiceUpdate.sendUpdateAck - RAN name: %s - Error marshalling RIC_SERVICE_UPDATE_ACK. Payload: %s", nodebInfo.RanName, payLoad)
132         }
133
134         toReplaceTags := []string{"reject", "ignore", "procedureCode", "id", "RANfunctionID-Item", "RANfunctionsID-List"}
135         payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, toReplaceTags)
136
137         h.logger.Infof("#RicServiceUpdate.sendUpdateAck - Sending RIC_SERVICE_UPDATE_ACK to RAN name: %s with payload %s", nodebInfo.RanName, payLoad)
138         msg := models.NewRmrMessage(rmrCgo.RIC_SERVICE_UPDATE_ACK, nodebInfo.RanName, payLoad, request.TransactionId, request.GetMsgSrc())
139         err = h.rmrSender.Send(msg)
140         return err
141 }
142
143 func (h *RicServiceUpdateHandler) updateFunctions(RICServiceUpdateIEs []models.RICServiceUpdateIEs, nodebInfo *entities.NodebInfo) []models.RicServiceAckRANFunctionIDItem {
144         ranFunctions := nodebInfo.GetGnb().RanFunctions
145         RanFIdtoIdxMap := make(map[uint32]int)
146         var acceptedFunctionIds []models.RicServiceAckRANFunctionIDItem
147         functionsToBeDeleted := make(map[int]bool)
148
149         for index, ranFunction := range ranFunctions {
150                 RanFIdtoIdxMap[ranFunction.RanFunctionId] = index
151         }
152
153         for _, ricServiceUpdateIE := range RICServiceUpdateIEs {
154                 functionDetails, err := h.getFunctionDetails(ricServiceUpdateIE)
155                 if err != nil {
156                         h.logger.Errorf("#RicServiceUpdate.updateFunctions- GetFunctionDetails returned err: %s", err)
157                 }
158
159                 for _, functionDetail := range functionDetails {
160                         functionChange, functionId, functionDefinition, functionRevision, functionOID := functionDetail.functionChange,
161                                 functionDetail.functionId, functionDetail.functionDefinition, functionDetail.functionRevision, functionDetail.functionOID
162                         ranFIndex, ok := RanFIdtoIdxMap[functionId]
163                         if !ok {
164                                 switch functionChange {
165                                 case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
166                                         ranFunctions = append(ranFunctions, &entities.RanFunction{RanFunctionId: functionId,
167                                                 RanFunctionDefinition: functionDefinition, RanFunctionRevision: functionRevision, RanFunctionOid: functionOID})
168                                 case RAN_FUNCTIONS_DELETED:
169                                         //Do nothing
170                                 }
171                         } else {
172                                 switch functionChange {
173                                 case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
174                                         ranFunctions[ranFIndex].RanFunctionDefinition = functionDefinition
175                                         ranFunctions[ranFIndex].RanFunctionRevision = functionRevision
176                                 case RAN_FUNCTIONS_DELETED:
177                                         functionsToBeDeleted[ranFIndex] = true
178                                 }
179                         }
180                         serviceupdateAckFunctionId := models.RicServiceAckRANFunctionIDItem{RanFunctionID: functionId, RanFunctionRevision: functionRevision}
181                         acceptedFunctionIds = append(acceptedFunctionIds, serviceupdateAckFunctionId)
182                 }
183         }
184         finalranFunctions := h.remove(ranFunctions, functionsToBeDeleted)
185         nodebInfo.GetGnb().RanFunctions = finalranFunctions
186         return acceptedFunctionIds
187 }
188
189 func (h *RicServiceUpdateHandler) remove(ranFunctions []*entities.RanFunction, functionsToBeDeleted map[int]bool) []*entities.RanFunction {
190         if len(functionsToBeDeleted) == 0 {
191                 return ranFunctions
192         }
193         var finalranFunctions []*entities.RanFunction
194         for i := 0; i < len(ranFunctions); i++ {
195                 _, ok := functionsToBeDeleted[i]
196                 if !ok {
197                         finalranFunctions = append(finalranFunctions, ranFunctions[i])
198                 }
199         }
200         return finalranFunctions
201 }
202
203 func (h *RicServiceUpdateHandler) getFunctionDetails(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails, error) {
204         functionChange := ricServiceUpdateIE.ID
205         switch functionChange {
206         case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
207                 return h.getFunctionsAddedModifiedHandler(ricServiceUpdateIE)
208         case RAN_FUNCTIONS_DELETED:
209                 return h.getFunctionsDeleteHandler(ricServiceUpdateIE)
210         default:
211                 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - Unknown change type %v", functionChange))
212         }
213         return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - Internal Error"))
214 }
215
216 func (h *RicServiceUpdateHandler) getFunctionsAddedModifiedHandler(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails, error) {
217         functionChange := ricServiceUpdateIE.ID
218         ranFunctionsIEList := ricServiceUpdateIE.Value.RANfunctionsList.RANfunctionsItemProtocolIESingleContainer
219         if len(ranFunctionsIEList) == 0 {
220                 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - function change type is %v but Functions list is empty", functionChange))
221         }
222
223         functionDetailsList := make([]functionDetails, len(ranFunctionsIEList))
224         for index, ranFunctionIE := range ranFunctionsIEList {
225                 ranFunction := ranFunctionIE.Value.RANfunctionItem
226                 functionDetailsList[index] = functionDetails{functionChange: functionChange, functionId: ranFunction.RanFunctionID,
227                         functionDefinition: ranFunction.RanFunctionDefinition, functionRevision: ranFunction.RanFunctionRevision, functionOID: ranFunction.RanFunctionOID}
228         }
229         return functionDetailsList, nil
230 }
231
232 func (h *RicServiceUpdateHandler) getFunctionsDeleteHandler(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails, error) {
233         functionChange := ricServiceUpdateIE.ID
234         ranFunctionIdIEsList := ricServiceUpdateIE.Value.RANfunctionsIDList.RANfunctionsItemIDProtocolIESingleContainer
235         if len(ranFunctionIdIEsList) == 0 {
236                 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - function change type is %v but FunctionIds list is empty", functionChange))
237         }
238
239         functionDetailsList := make([]functionDetails, len(ranFunctionIdIEsList))
240         for index, ranFunctionIdIE := range ranFunctionIdIEsList {
241                 ranFunctionId := ranFunctionIdIE.Value.RANfunctionIDItem
242                 functionDetailsList[index] = functionDetails{functionChange: functionChange, functionId: ranFunctionId.RanFunctionID,
243                         functionDefinition: "", functionRevision: ranFunctionId.RanFunctionRevision}
244         }
245         return functionDetailsList, nil
246 }
247
248 func (h *RicServiceUpdateHandler) parseSetupRequest(payload []byte) (*models.RICServiceUpdateMessage, error) {
249         pipInd := bytes.IndexByte(payload, '|')
250         if pipInd < 0 {
251                 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdateHandler.parseSetupRequest - Error parsing RIC SERVICE UPDATE failed extract Payload: no | separator found"))
252         }
253
254         ricServiceUpdate := &models.RICServiceUpdateMessage{}
255         err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &ricServiceUpdate.E2APPDU)
256         if err != nil {
257                 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdateHandler.parseSetupRequest - Error unmarshalling RIC SERVICE UPDATE payload: %x", payload))
258         }
259         return ricServiceUpdate, nil
260 }