From aa8f22b7a9ebee53581f145ef75fd79714417955 Mon Sep 17 00:00:00 2001 From: subhash kumar singh Date: Mon, 9 May 2022 18:27:07 +0000 Subject: [PATCH] Handle received addition List NodeConfig Implemented handling of e2nodebconfig for receieved IEs in addtion list. Each IEs is converted to respective entities to store inside NodebInfo. Signed-off-by: subhash kumar singh Change-Id: I550743f1761440c74d618880de106c8b7e569c56 --- .../e2_node_config_update_notification_handler.go | 134 +++++++++++++++++++++ ...node_config_update_notification_handler_test.go | 120 ++++++++++++++++++ 2 files changed, 254 insertions(+) create mode 100644 E2Manager/handlers/rmrmsghandlers/e2_node_config_update_notification_handler.go create mode 100644 E2Manager/handlers/rmrmsghandlers/e2_node_config_update_notification_handler_test.go diff --git a/E2Manager/handlers/rmrmsghandlers/e2_node_config_update_notification_handler.go b/E2Manager/handlers/rmrmsghandlers/e2_node_config_update_notification_handler.go new file mode 100644 index 0000000..21428b0 --- /dev/null +++ b/E2Manager/handlers/rmrmsghandlers/e2_node_config_update_notification_handler.go @@ -0,0 +1,134 @@ +// +// Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This source code is part of the near-RT RIC (RAN Intelligent Controller) +// platform project (RICP). + +package rmrmsghandlers + +import ( + "e2mgr/logger" + "e2mgr/models" + "e2mgr/services" + "e2mgr/services/rmrsender" + "e2mgr/utils" + "encoding/xml" + + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" +) + +var ( + toReplaceTags = []string{"reject", "ignore", "procedureCode", "id", "RANfunctionID-Item", "RANfunctionsID-List", "success", "s1", "ng", "e1", "f1", "w1", "x1", "xn"} +) + +type E2nodeConfigUpdateNotificationHandler struct { + logger *logger.Logger + rNibDataService services.RNibDataService + rmrSender *rmrsender.RmrSender +} + +func NewE2nodeConfigUpdateNotificationHandler(logger *logger.Logger, rNibDataService services.RNibDataService, rmrSender *rmrsender.RmrSender) *E2nodeConfigUpdateNotificationHandler { + return &E2nodeConfigUpdateNotificationHandler{ + logger: logger, + rNibDataService: rNibDataService, + rmrSender: rmrSender, + } +} + +func (e *E2nodeConfigUpdateNotificationHandler) Handle(request *models.NotificationRequest) { + e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - RAN name: %s - received E2_Config_Update. Payload: %x", request.RanName, request.Payload) + e2NodeConfig, err := e.parseE2NodeConfigurationUpdate(request.Payload) + if err != nil { + e.logger.Errorf(err.Error()) + return + } + e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - RIC_E2_Node_Config_Update parsed successfully") + + nodebInfo, err := e.rNibDataService.GetNodeb(request.RanName) + + if err != nil { + switch v := err.(type) { + case *common.ResourceNotFoundError: + e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - failed to get nodeB, E2nodeConfigUpdate will not be processed further.") + default: + e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - nobeB entity of RanName:%s absent in RNIB. Error: %s", request.RanName, v) + } + return + } + e.updateE2nodeConfig(e2NodeConfig, nodebInfo) +} + +func (e *E2nodeConfigUpdateNotificationHandler) updateE2nodeConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) { + e.handleAddConfig(e2nodeConfig, nodebInfo) + e.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo) +} + +func (e *E2nodeConfigUpdateNotificationHandler) compareConfigIDs(n1, n2 entities.E2NodeComponentConfig) bool { + if n1.E2NodeComponentInterfaceType != n2.E2NodeComponentInterfaceType { + return false + } + + switch n1.E2NodeComponentInterfaceType { + case entities.E2NodeComponentInterfaceType_ng: + return n1.GetE2NodeComponentInterfaceTypeNG().GetAmfName() == n2.GetE2NodeComponentInterfaceTypeNG().GetAmfName() + case entities.E2NodeComponentInterfaceType_xn: + // TODO -- Not supported yet + e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type Xn is not supported") + case entities.E2NodeComponentInterfaceType_e1: + return n1.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId() == n2.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId() + case entities.E2NodeComponentInterfaceType_f1: + return n1.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId() == n2.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId() + case entities.E2NodeComponentInterfaceType_w1: + return n1.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId() == n2.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId() + case entities.E2NodeComponentInterfaceType_s1: + return n1.GetE2NodeComponentInterfaceTypeS1().GetMmeName() == n2.GetE2NodeComponentInterfaceTypeS1().GetMmeName() + + case entities.E2NodeComponentInterfaceType_x2: + // TODO -- Not supported yet + e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type X2 is not supported") + default: + e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type not supported") + } + return false +} + +func (e *E2nodeConfigUpdateNotificationHandler) handleAddConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) { + var result []*entities.E2NodeComponentConfig + + additionList := e2nodeConfig.ExtractConfigAdditionList() + for i, _ := range additionList { + result = append(result, &additionList[i]) + } + + if nodebInfo.NodeType == entities.Node_ENB { + nodebInfo.GetEnb().NodeConfigs = append(result, nodebInfo.GetEnb().NodeConfigs...) + + } else { + nodebInfo.GetGnb().NodeConfigs = append(result, nodebInfo.GetGnb().NodeConfigs...) + } +} + +func (e *E2nodeConfigUpdateNotificationHandler) parseE2NodeConfigurationUpdate(payload []byte) (*models.E2nodeConfigurationUpdateMessage, error) { + e2nodeConfig := models.E2nodeConfigurationUpdateMessage{} + err := xml.Unmarshal(utils.NormalizeXml(payload), &(e2nodeConfig.E2APPDU)) + + if err != nil { + e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - error in parsing request message: %+v", err) + return nil, err + } + e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - Unmarshalling is successful %v", e2nodeConfig.E2APPDU.InitiatingMessage.ProcedureCode) + return &e2nodeConfig, nil +} diff --git a/E2Manager/handlers/rmrmsghandlers/e2_node_config_update_notification_handler_test.go b/E2Manager/handlers/rmrmsghandlers/e2_node_config_update_notification_handler_test.go new file mode 100644 index 0000000..870bec5 --- /dev/null +++ b/E2Manager/handlers/rmrmsghandlers/e2_node_config_update_notification_handler_test.go @@ -0,0 +1,120 @@ +// +// Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This source code is part of the near-RT RIC (RAN Intelligent Controller) +// platform project (RICP). + +package rmrmsghandlers + +import ( + "e2mgr/configuration" + "e2mgr/mocks" + "e2mgr/models" + "e2mgr/rmrCgo" + "e2mgr/services" + "e2mgr/tests" + "e2mgr/utils" + "testing" + + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +const ( + E2nodeConfigUpdateXmlPath = "../../tests/resources/configurationUpdate/e2NodeConfigurationUpdate.xml" + E2nodeConfigUpdateOnlyAdditionXmlPath = "../../tests/resources/configurationUpdate/e2NodeConfigurationUpdateOnlyAddition.xml" +) + +func initE2nodeConfigMocks(t *testing.T) (*E2nodeConfigUpdateNotificationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock) { + logger := tests.InitLog(t) + config := &configuration.Configuration{ + RnibRetryIntervalMs: 10, + MaxRnibConnectionAttempts: 3, + RnibWriter: configuration.RnibWriterConfig{ + StateChangeMessageChannel: StateChangeMessageChannel, + }, + GlobalRicId: struct { + RicId string + Mcc string + Mnc string + }{Mcc: "327", Mnc: "94", RicId: "AACCE"}} + readerMock := &mocks.RnibReaderMock{} + writerMock := &mocks.RnibWriterMock{} + rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock) + rmrMessengerMock := &mocks.RmrMessengerMock{} + rmrSender := tests.InitRmrSender(rmrMessengerMock, logger) + handler := NewE2nodeConfigUpdateNotificationHandler(logger, rnibDataService, rmrSender) + return handler, readerMock, writerMock, rmrMessengerMock +} + +func TestE2nodeConfigUpdatetNotificationHandler(t *testing.T) { + e2NodeConfigUpdateXml := utils.ReadXmlFile(t, E2nodeConfigUpdateOnlyAdditionXmlPath) + handler, readerMock, writerMock, _ := initE2nodeConfigMocks(t) + var nodebInfo = &entities.NodebInfo{ + RanName: gnbNodebRanName, + AssociatedE2TInstanceAddress: e2tInstanceFullAddress, + ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, + NodeType: entities.Node_GNB, + Configuration: &entities.NodebInfo_Gnb{ + Gnb: &entities.Gnb{}, + }, + } + readerMock.On("GetNodeb", gnbNodebRanName).Return(nodebInfo, nil) + writerMock.On("UpdateNodebInfoAndPublish", mock.Anything).Return(nil) + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(""), e2NodeConfigUpdateXml...)} + handler.Handle(notificationRequest) + readerMock.AssertExpectations(t) + writerMock.AssertExpectations(t) +} + +func TestE2nodeConfigUpdatetParseFail(t *testing.T) { + handler, _, _, _ := initE2nodeConfigMocks(t) + badxml := []byte("abc") + e2nodeConfig, err := handler.parseE2NodeConfigurationUpdate(badxml) + + var expected *models.E2nodeConfigurationUpdateMessage + assert.Equal(t, expected, e2nodeConfig) + assert.NotNil(t, err) +} + +func TestHandleAddConfig(t *testing.T) { + e2NodeConfigUpdateXml := utils.ReadXmlFile(t, E2nodeConfigUpdateXmlPath) + + handler, readerMock, writerMock, rmrMessengerMock := initE2nodeConfigMocks(t) + var nodebInfo = &entities.NodebInfo{ + RanName: gnbNodebRanName, + AssociatedE2TInstanceAddress: e2tInstanceFullAddress, + ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, + NodeType: entities.Node_GNB, + Configuration: &entities.NodebInfo_Gnb{ + Gnb: &entities.Gnb{}, + }, + } + readerMock.On("GetNodeb", gnbNodebRanName).Return(nodebInfo, nil) + writerMock.On("UpdateNodebInfoAndPublish", mock.Anything).Return(nil) + var errEmpty error + rmrMessengerMock.On("SendMsg", mock.Anything, mock.Anything).Return(&rmrCgo.MBuf{}, errEmpty) + + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(""), e2NodeConfigUpdateXml...)} + + handler.Handle(notificationRequest) + + t.Logf("len of addtionList : %d", len(nodebInfo.GetGnb().NodeConfigs)) + + assert.Equal(t, 5, len(nodebInfo.GetGnb().NodeConfigs)) + writerMock.AssertExpectations(t) + readerMock.AssertExpectations(t) +} -- 2.16.6