RIC-997: ErrorIndication handling in e2mgr
[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         ackFunctionIds := h.updateFunctions(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs, nodebInfo)
96         if len(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs) > 1 {
97                 err = h.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
98                 if err != nil {
99                         h.logger.Errorf("#RicServiceUpdateHandler.Handle - RAN name: %s - Failed at UpdateNodebInfoAndPublish. error: %s", nodebInfo.RanName, err)
100                         return
101                 }
102         }
103
104         oldNbIdentity, newNbIdentity := h.ranListManager.UpdateHealthcheckTimeStampReceived(nodebInfo.RanName)
105         err = h.ranListManager.UpdateNbIdentities(nodebInfo.NodeType, []*entities.NbIdentity{oldNbIdentity}, []*entities.NbIdentity{newNbIdentity})
106         if err != nil {
107                 h.logger.Errorf("#RicServiceUpdate.Handle - failed to Update NbIdentities: %s", err)
108                 return
109         }
110
111         updateAck := models.NewServiceUpdateAck(ackFunctionIds, ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs[0].Value.TransactionID)
112         err = h.sendUpdateAck(updateAck, nodebInfo, request)
113         if err != nil {
114                 h.logger.Errorf("#RicServiceUpdate.Handle - failed to send RIC_SERVICE_UPDATE_ACK message to RMR: %s", err)
115                 return
116         }
117
118         h.logger.Infof("#RicServiceUpdate.Handle - Completed successfully")
119         models.UpdateProcedureType(ranName, models.RicServiceUpdateCompleted)
120         h.logger.Debugf("#RicServiceUpdateHandler.Handle  - updating the enum value to RicServiceUpdateCompleted completed")
121 }
122
123 func (h *RicServiceUpdateHandler) sendUpdateAck(updateAck models.RicServiceUpdateAckE2APPDU, nodebInfo *entities.NodebInfo, request *models.NotificationRequest) error {
124         payLoad, err := xml.Marshal(updateAck)
125         if err != nil {
126                 h.logger.Errorf("#RicServiceUpdate.sendUpdateAck - RAN name: %s - Error marshalling RIC_SERVICE_UPDATE_ACK. Payload: %s", nodebInfo.RanName, payLoad)
127         }
128
129         toReplaceTags := []string{"reject", "ignore", "procedureCode", "id", "RANfunctionID-Item", "RANfunctionsID-List"}
130         payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, toReplaceTags)
131
132         h.logger.Infof("#RicServiceUpdate.sendUpdateAck - Sending RIC_SERVICE_UPDATE_ACK to RAN name: %s with payload %s", nodebInfo.RanName, payLoad)
133         msg := models.NewRmrMessage(rmrCgo.RIC_SERVICE_UPDATE_ACK, nodebInfo.RanName, payLoad, request.TransactionId, request.GetMsgSrc())
134         err = h.rmrSender.Send(msg)
135         return err
136 }
137
138 func (h *RicServiceUpdateHandler) updateFunctions(RICServiceUpdateIEs []models.RICServiceUpdateIEs, nodebInfo *entities.NodebInfo) []models.RicServiceAckRANFunctionIDItem {
139         ranFunctions := nodebInfo.GetGnb().RanFunctions
140         RanFIdtoIdxMap := make(map[uint32]int)
141         var acceptedFunctionIds []models.RicServiceAckRANFunctionIDItem
142         functionsToBeDeleted := make(map[int]bool)
143
144         for index, ranFunction := range ranFunctions {
145                 RanFIdtoIdxMap[ranFunction.RanFunctionId] = index
146         }
147
148         for _, ricServiceUpdateIE := range RICServiceUpdateIEs {
149                 functionDetails, err := h.getFunctionDetails(ricServiceUpdateIE)
150                 if err != nil {
151                         h.logger.Errorf("#RicServiceUpdate.updateFunctions- GetFunctionDetails returned err: %s", err)
152                 }
153
154                 for _, functionDetail := range functionDetails {
155                         functionChange, functionId, functionDefinition, functionRevision, functionOID := functionDetail.functionChange,
156                                 functionDetail.functionId, functionDetail.functionDefinition, functionDetail.functionRevision, functionDetail.functionOID
157                         ranFIndex, ok := RanFIdtoIdxMap[functionId]
158                         if !ok {
159                                 switch functionChange {
160                                 case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
161                                         ranFunctions = append(ranFunctions, &entities.RanFunction{RanFunctionId: functionId,
162                                                 RanFunctionDefinition: functionDefinition, RanFunctionRevision: functionRevision, RanFunctionOid: functionOID})
163                                 case RAN_FUNCTIONS_DELETED:
164                                         //Do nothing
165                                 }
166                         } else {
167                                 switch functionChange {
168                                 case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
169                                         ranFunctions[ranFIndex].RanFunctionDefinition = functionDefinition
170                                         ranFunctions[ranFIndex].RanFunctionRevision = functionRevision
171                                 case RAN_FUNCTIONS_DELETED:
172                                         functionsToBeDeleted[ranFIndex] = true
173                                 }
174                         }
175                         serviceupdateAckFunctionId := models.RicServiceAckRANFunctionIDItem{RanFunctionID: functionId, RanFunctionRevision: functionRevision}
176                         acceptedFunctionIds = append(acceptedFunctionIds, serviceupdateAckFunctionId)
177                 }
178         }
179         finalranFunctions := h.remove(ranFunctions, functionsToBeDeleted)
180         nodebInfo.GetGnb().RanFunctions = finalranFunctions
181         return acceptedFunctionIds
182 }
183
184 func (h *RicServiceUpdateHandler) remove(ranFunctions []*entities.RanFunction, functionsToBeDeleted map[int]bool) []*entities.RanFunction {
185         if len(functionsToBeDeleted) == 0 {
186                 return ranFunctions
187         }
188         var finalranFunctions []*entities.RanFunction
189         for i := 0; i < len(ranFunctions); i++ {
190                 _, ok := functionsToBeDeleted[i]
191                 if !ok {
192                         finalranFunctions = append(finalranFunctions, ranFunctions[i])
193                 }
194         }
195         return finalranFunctions
196 }
197
198 func (h *RicServiceUpdateHandler) getFunctionDetails(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails, error) {
199         functionChange := ricServiceUpdateIE.ID
200         switch functionChange {
201         case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
202                 return h.getFunctionsAddedModifiedHandler(ricServiceUpdateIE)
203         case RAN_FUNCTIONS_DELETED:
204                 return h.getFunctionsDeleteHandler(ricServiceUpdateIE)
205         default:
206                 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - Unknown change type %v", functionChange))
207         }
208         return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - Internal Error"))
209 }
210
211 func (h *RicServiceUpdateHandler) getFunctionsAddedModifiedHandler(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails, error) {
212         functionChange := ricServiceUpdateIE.ID
213         ranFunctionsIEList := ricServiceUpdateIE.Value.RANfunctionsList.RANfunctionsItemProtocolIESingleContainer
214         if len(ranFunctionsIEList) == 0 {
215                 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - function change type is %v but Functions list is empty", functionChange))
216         }
217
218         functionDetailsList := make([]functionDetails, len(ranFunctionsIEList))
219         for index, ranFunctionIE := range ranFunctionsIEList {
220                 ranFunction := ranFunctionIE.Value.RANfunctionItem
221                 functionDetailsList[index] = functionDetails{functionChange: functionChange, functionId: ranFunction.RanFunctionID,
222                         functionDefinition: ranFunction.RanFunctionDefinition, functionRevision: ranFunction.RanFunctionRevision, functionOID: ranFunction.RanFunctionOID}
223         }
224         return functionDetailsList, nil
225 }
226
227 func (h *RicServiceUpdateHandler) getFunctionsDeleteHandler(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails, error) {
228         functionChange := ricServiceUpdateIE.ID
229         ranFunctionIdIEsList := ricServiceUpdateIE.Value.RANfunctionsIDList.RANfunctionsItemIDProtocolIESingleContainer
230         if len(ranFunctionIdIEsList) == 0 {
231                 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - function change type is %v but FunctionIds list is empty", functionChange))
232         }
233
234         functionDetailsList := make([]functionDetails, len(ranFunctionIdIEsList))
235         for index, ranFunctionIdIE := range ranFunctionIdIEsList {
236                 ranFunctionId := ranFunctionIdIE.Value.RANfunctionIDItem
237                 functionDetailsList[index] = functionDetails{functionChange: functionChange, functionId: ranFunctionId.RanFunctionID,
238                         functionDefinition: "", functionRevision: ranFunctionId.RanFunctionRevision}
239         }
240         return functionDetailsList, nil
241 }
242
243 func (h *RicServiceUpdateHandler) parseSetupRequest(payload []byte) (*models.RICServiceUpdateMessage, error) {
244         pipInd := bytes.IndexByte(payload, '|')
245         if pipInd < 0 {
246                 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdateHandler.parseSetupRequest - Error parsing RIC SERVICE UPDATE failed extract Payload: no | separator found"))
247         }
248
249         ricServiceUpdate := &models.RICServiceUpdateMessage{}
250         err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &ricServiceUpdate.E2APPDU)
251         if err != nil {
252                 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdateHandler.parseSetupRequest - Error unmarshalling RIC SERVICE UPDATE payload: %x", payload))
253         }
254         return ricServiceUpdate, nil
255 }