2 // Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
16 // This source code is part of the near-RT RIC (RAN Intelligent Controller)
17 // platform project (RICP).
19 package rmrmsghandlers
26 "e2mgr/services/rmrsender"
30 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
31 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
35 toReplaceTags = []string{"reject", "ignore", "procedureCode", "id", "RANfunctionID-Item", "RANfunctionsID-List", "success", "s1", "ng", "e1", "f1", "w1", "x1", "xn"}
38 type E2nodeConfigUpdateNotificationHandler struct {
40 rNibDataService services.RNibDataService
41 rmrSender *rmrsender.RmrSender
44 func NewE2nodeConfigUpdateNotificationHandler(logger *logger.Logger, rNibDataService services.RNibDataService, rmrSender *rmrsender.RmrSender) *E2nodeConfigUpdateNotificationHandler {
45 return &E2nodeConfigUpdateNotificationHandler{
47 rNibDataService: rNibDataService,
52 func (e *E2nodeConfigUpdateNotificationHandler) Handle(request *models.NotificationRequest) {
53 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - RAN name: %s - received E2_Config_Update. Payload: %x", request.RanName, request.Payload)
54 e2NodeConfig, err := e.parseE2NodeConfigurationUpdate(request.Payload)
56 e.logger.Errorf(err.Error())
59 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - RIC_E2_Node_Config_Update parsed successfully")
61 nodebInfo, err := e.rNibDataService.GetNodeb(request.RanName)
64 switch v := err.(type) {
65 case *common.ResourceNotFoundError:
66 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - failed to get nodeB, E2nodeConfigUpdate will not be processed further.")
68 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - nobeB entity of RanName:%s absent in RNIB. Error: %s", request.RanName, v)
72 e.updateE2nodeConfig(e2NodeConfig, nodebInfo)
73 e.handleSuccessfulResponse(e2NodeConfig, request, nodebInfo)
76 func (e *E2nodeConfigUpdateNotificationHandler) updateE2nodeConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
77 e.handleAddConfig(e2nodeConfig, nodebInfo)
78 e.handleUpdateConfig(e2nodeConfig, nodebInfo)
79 e.handleDeleteConfig(e2nodeConfig, nodebInfo)
80 e.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
83 func (e *E2nodeConfigUpdateNotificationHandler) compareConfigIDs(n1, n2 entities.E2NodeComponentConfig) bool {
84 if n1.E2NodeComponentInterfaceType != n2.E2NodeComponentInterfaceType {
88 switch n1.E2NodeComponentInterfaceType {
89 case entities.E2NodeComponentInterfaceType_ng:
90 return n1.GetE2NodeComponentInterfaceTypeNG().GetAmfName() == n2.GetE2NodeComponentInterfaceTypeNG().GetAmfName()
91 case entities.E2NodeComponentInterfaceType_xn:
92 // TODO -- Not supported yet
93 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type Xn is not supported")
94 case entities.E2NodeComponentInterfaceType_e1:
95 return n1.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId() == n2.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId()
96 case entities.E2NodeComponentInterfaceType_f1:
97 return n1.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId() == n2.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId()
98 case entities.E2NodeComponentInterfaceType_w1:
99 return n1.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId() == n2.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId()
100 case entities.E2NodeComponentInterfaceType_s1:
101 return n1.GetE2NodeComponentInterfaceTypeS1().GetMmeName() == n2.GetE2NodeComponentInterfaceTypeS1().GetMmeName()
103 case entities.E2NodeComponentInterfaceType_x2:
104 // TODO -- Not supported yet
105 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type X2 is not supported")
107 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type not supported")
112 func (e *E2nodeConfigUpdateNotificationHandler) handleAddConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
113 var result []*entities.E2NodeComponentConfig
115 additionList := e2nodeConfig.ExtractConfigAdditionList()
116 for i, _ := range additionList {
117 result = append(result, &additionList[i])
120 if nodebInfo.NodeType == entities.Node_ENB {
121 nodebInfo.GetEnb().NodeConfigs = append(result, nodebInfo.GetEnb().NodeConfigs...)
124 nodebInfo.GetGnb().NodeConfigs = append(result, nodebInfo.GetGnb().NodeConfigs...)
128 func (e *E2nodeConfigUpdateNotificationHandler) handleUpdateConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
129 updateList := e2nodeConfig.ExtractConfigUpdateList()
130 if nodebInfo.GetNodeType() == entities.Node_GNB {
131 for i := 0; i < len(updateList); i++ {
133 if nodebInfo.GetNodeType() == entities.Node_GNB {
134 for j := 0; j < len(nodebInfo.GetGnb().NodeConfigs); j++ {
135 if e.compareConfigIDs(u, *nodebInfo.GetGnb().NodeConfigs[j]) {
136 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i)
137 nodebInfo.GetGnb().NodeConfigs[i] = &u
140 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - dint match")
146 for i := 0; i < len(updateList); i++ {
148 if nodebInfo.GetNodeType() == entities.Node_ENB {
149 for j := 0; j < len(nodebInfo.GetEnb().NodeConfigs); j++ {
150 v := nodebInfo.GetEnb().NodeConfigs[j]
151 if e.compareConfigIDs(u, *v) {
152 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i)
153 nodebInfo.GetEnb().NodeConfigs[i] = &u
163 func (e *E2nodeConfigUpdateNotificationHandler) handleDeleteConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
164 deleteList := e2nodeConfig.ExtractConfigDeletionList()
166 for _, u := range deleteList {
167 if nodebInfo.GetNodeType() == entities.Node_ENB {
168 for i, v := range nodebInfo.GetEnb().NodeConfigs {
169 if e.compareConfigIDs(u, *v) {
170 nodebInfo.GetEnb().NodeConfigs = removeIndex(nodebInfo.GetEnb().GetNodeConfigs(), i)
176 if nodebInfo.GetNodeType() == entities.Node_GNB {
177 for i, v := range nodebInfo.GetGnb().NodeConfigs {
178 if e.compareConfigIDs(u, *v) {
179 nodebInfo.GetGnb().NodeConfigs = removeIndex(nodebInfo.GetGnb().GetNodeConfigs(), i)
187 func removeIndex(s []*entities.E2NodeComponentConfig, index int) []*entities.E2NodeComponentConfig {
189 return append(s[:index], s[index+1:]...)
194 func (e *E2nodeConfigUpdateNotificationHandler) parseE2NodeConfigurationUpdate(payload []byte) (*models.E2nodeConfigurationUpdateMessage, error) {
195 e2nodeConfig := models.E2nodeConfigurationUpdateMessage{}
196 err := xml.Unmarshal(utils.NormalizeXml(payload), &(e2nodeConfig.E2APPDU))
199 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - error in parsing request message: %+v", err)
202 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - Unmarshalling is successful %v", e2nodeConfig.E2APPDU.InitiatingMessage.ProcedureCode)
203 return &e2nodeConfig, nil
206 func (e *E2nodeConfigUpdateNotificationHandler) handleSuccessfulResponse(e2NodeConfigUpdate *models.E2nodeConfigurationUpdateMessage, request *models.NotificationRequest, nodebInfo *entities.NodebInfo) error {
207 e2nodeConfigUpdateResp := models.NewE2nodeConfigurationUpdateSuccessResponseMessage(e2NodeConfigUpdate)
208 payLoad, err := xml.Marshal(e2nodeConfigUpdateResp)
210 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Error marshalling RIC_SERVICE_UPDATE_ACK. Payload: %s", payLoad)
213 payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, toReplaceTags)
214 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Sending RIC_SERVICE_UPDATE_ACK to RAN name: %s with payload %s", nodebInfo.RanName, payLoad)
215 msg := models.NewRmrMessage(rmrCgo.RIC_SERVICE_UPDATE_ACK, nodebInfo.RanName, payLoad, request.TransactionId, request.GetMsgSrc())
216 err = e.rmrSender.Send(msg)