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