From 0f06f71ca88aeedf1239fdc0f3f4cb7fa0ab9823 Mon Sep 17 00:00:00 2001 From: czichy Date: Mon, 16 May 2022 19:48:51 +0300 Subject: [PATCH] Squash-merging e2ap-v2.0 branch commit e2c582dc988edd96d1ec243cf35f93150e08a1f9 Author: subhash kumar singh Date: Wed May 11 18:42:38 2022 +0000 Enable rmrMsgHandler for RICE2nodeConfigUpdate msg This patch contains: * Change in lib-rmr dependency to 4.8.3 . * Messange handler enabled to handle RICE2nodeConfigUpdate. Signed-off-by: subhash kumar singh Change-Id: Ib462390829d8ebac7cdbfc99515e4179b3bd4023 commit 54d50ce00d98d92faf5bf2383bdefee15d48336e Author: subhash kumar singh Date: Wed May 11 10:51:49 2022 +0000 Fix UT and constant values This patch contains two fix : * Fixed values of constant to match with specification. * Removed invalid UT, as service update ack has mandatory `RICserviceUpdateAcknowledgeRANfunctionsList` with minimum one ProtocolIESingleContainer. Signed-off-by: subhash kumar singh Change-Id: I18aa46e82d667fb1a2075194a70b0f7d9801dec4 commit d5a5e94c9b55b64a81429c529ce4dcb39b44b04e Author: subhash kumar singh Date: Mon May 9 20:48:25 2022 +0000 Enable E2nodeConfigUpdateAck message Prepared E2nodeConfigUpdateAck message on successful processing of E2nodeConfigUpdate message. Finally we will respond to nodeb by sending Ack message over RMR. Signed-off-by: subhash kumar singh Change-Id: I7968ad7fc937aaf8035165175898b36dfde3d490 commit 26bf2fa76093cfe8f1145d91dd6124caf09f1818 Author: subhash kumar singh Date: Mon May 9 20:37:12 2022 +0000 Handle received removal List NodeConfig Implemented handling of e2nodebconfig for receieved IEs in removal list. Each IEs is converted to respective entities updated to store inside NodebInfo. Signed-off-by: subhash kumar singh Change-Id: I99fdbba24352bc5e68732aff9ae05c6b020db556 commit 5d031febe2ee3f3c6023732ea9e6d1c1efda195e Author: subhash kumar singh Date: Mon May 9 19:18:49 2022 +0000 Handle received update List NodeConfig Implemented handling of e2nodebconfig for receieved IEs in update list. Each IEs is converted to respective entities updated to store inside NodebInfo. Signed-off-by: subhash kumar singh Change-Id: Ia186648117d1494bfb67181258d85f03e47a4f05 commit 76847bc791ea3c063756e8dc7f048d8c516dd3cd Author: subhash kumar singh Date: Mon May 9 18:27:07 2022 +0000 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 commit b947b3065b70f3c812ae00452c4783ef1b47efe0 Author: subhash kumar singh Date: Sun May 8 20:05:37 2022 +0000 Implement creation of E2nodeConfigUpdateAck msg Implemented creation of E2nodeConfigUpdateAck message. It can be used to create an entity to create Ack message. Signed-off-by: subhash kumar singh Change-Id: I86b4932e7cb25e1e3550e8810b46cd1e7783968a commit 942385ac32edd7934179f2c8a9f47c0aa412cd43 Author: subhash kumar singh Date: Thu May 5 11:07:53 2022 +0000 Add transaction ID support in E2nodeConfigUpdate Added trasaction ID support in E2nodeConfigUpdate message. Signed-off-by: subhash kumar singh Change-Id: Iba5a016420bea2aa87b34a2e6ffec85b704f915b commit 3b6dd618f0ed509072c5118d5c26653de139fa45 Author: subhash kumar singh Date: Wed May 4 17:21:53 2022 +0000 Model for E2nodeConfigurationUpdateAck Written model to prepare E2nodeConfigUpdateAck message. Signed-off-by: subhash kumar singh Change-Id: Ie32b7ef3f9cb8ff399f767d98e344cd25800b640 commit bbefdac3bb1eacd5352c59ddd0e96180bcb9808b Author: subhash kumar singh Date: Wed May 4 12:15:16 2022 +0000 Add method to extract removal list Added method to extract configuration removal item. Note: Xn and X2 interface is not supported. Signed-off-by: subhash kumar singh Change-Id: I28aee1d228d422132eef9a091f2d57270fc15246 commit f98300ff5fab94ce8ad87226408be95ac47d9be4 Author: subhash kumar singh Date: Wed May 4 08:56:37 2022 +0000 Add method to extract update list Added method to extract configuration update item. Note: Xn and X2 interface is not supported. Signed-off-by: subhash kumar singh Change-Id: Ieaf5f7e78f4e3fe1289631d9567ec9e485d41ccd commit 02a6b66cf765385e31f9201a7488fd8b9f7a4c49 Author: subhash kumar singh Date: Wed May 4 07:28:17 2022 +0000 Add method to extract addtion list Added method got extract configuration addition item. Note: Xn and X2 interface is not supported. Signed-off-by: subhash kumar singh Change-Id: I1dbfa62b8439743ad4dabd4d3d1995e82e4db5bd commit 63cbf9095e87e2039e5d38f580791728c84d9948 Author: subhash kumar singh Date: Thu May 5 17:25:33 2022 +0000 Add transaction ID support in RICServiceQuery Added transaction ID support in RICServiceQuery message. Signed-off-by: subhash kumar singh Change-Id: I52a1849e421a7c0c372f8dea9ca62c12b7114c6e commit 34b0f41590e58c383001f87cf3749df3a6aa86da Author: subhash kumar singh Date: Fri May 6 20:32:50 2022 +0000 Support Transaction ID in ServiceUpdateAck Support transaction ID in ServiceUpdateAck message. Signed-off-by: subhash kumar singh Change-Id: I2a5b445bf3c032eee9882d14036e2662b46711f3 commit c0645c8db108e2b9ab0dfe3f8ab8e0b07c2b9eb4 Author: subhash kumar singh Date: Fri May 6 07:32:01 2022 +0000 Add txID in RICServiceUpdate message Added transaction ID support in RICServiceUpdate message. Signed-off-by: subhash kumar singh Change-Id: Iac59040d2b2bcd90f63ac7cc3e90941902c9a14d commit 1326ada5a7da9b078f4b175d4bf697d89462705b Author: subhash kumar singh Date: Mon May 2 11:47:16 2022 +0000 Model for E2nodeConfigurationUpdate message Model for E2nodeConfigurationUpdate message has been implemented to parse the xml message received from e2-node. Note: Currently we treated compnent ID for Xn and X2 interface as string which need to be further expanded. Signed-off-by: subhash kumar singh Change-Id: Ife81dbb2ede49d0a63ce38725287cad7f342ef54 commit fa72093ee4c4842c28f1b58eeeac9d524208086d Author: subhash kumar singh Date: Mon Apr 18 09:52:24 2022 +0000 E2Setup Message as per E2AP spec v2.0 Implement E2Setup Message as per the E2AP spec v2.0 to mainly support E2nodeConfig IE. Issue-ID: RIC-722 Change-Id: I3174451912d5d08cd472b3ae7ba81b176daebf7c Signed-off-by: subhash kumar singh Change-Id: I0428ab045258d9b2d4640b7494ea05c9aa8a1da8 Signed-off-by: czichy --- E2Manager/build-e2mgr-ubuntu.sh | 4 +- E2Manager/go.mod | 2 +- E2Manager/go.sum | 2 + .../e2_node_config_update_notification_handler.go | 218 +++++++++ ...node_config_update_notification_handler_test.go | 157 +++++++ .../e2_setup_request_notification_handler.go | 65 ++- .../e2_setup_request_notification_handler_test.go | 40 +- .../rmrmsghandlers/ric_service_update_handler.go | 4 +- .../ric_service_update_handler_test.go | 108 ++--- E2Manager/models/constants.go | 39 ++ E2Manager/models/e2_node_configuration_update.go | 512 +++++++++++++++++++++ .../models/e2_node_configuration_update_ack.go | 338 ++++++++++++++ .../e2_node_configuration_update_ack_test.go | 68 +++ .../models/e2_node_configuration_update_test.go | 119 +++++ E2Manager/models/e2_setup_request_message.go | 287 +++++++++++- E2Manager/models/e2_setup_request_message_test.go | 14 +- E2Manager/models/e2_setup_response_message.go | 220 ++++++++- E2Manager/models/e2_setup_response_message_test.go | 27 +- E2Manager/models/ric_service_query_message.go | 102 ++-- E2Manager/models/ric_service_query_message_test.go | 17 +- E2Manager/models/ric_service_update_ack_message.go | 134 ++++-- .../models/ric_service_update_ack_message_test.go | 29 +- E2Manager/models/ric_service_update_message.go | 5 +- .../models/ric_service_update_message_test.go | 5 + .../notification_handler_provider.go | 2 + .../notification_handler_provider_test.go | 1 + E2Manager/rmrCgo/rmrCgoTypes.go | 20 +- .../e2NodeConfigurationUpdate.xml | 410 +++++++++++++++++ ...odeConfigurationUpdateAdditionAndUpdateOnly.xml | 303 ++++++++++++ .../e2NodeConfigurationUpdateOnlyAddition.xml | 45 ++ .../RicServiceUpdate_AddedFunction.xml | 7 + .../RicServiceUpdate_AddedFunction_With_OID.xml | 7 + .../RicServiceUpdate_DeleteFunction.xml | 7 + .../serviceUpdate/RicServiceUpdate_Empty.xml | 7 + .../RicServiceUpdate_ModifiedFunction.xml | 7 + .../RicServiceUpdate_SetupRequest.xml | 7 + .../RicServiceUpdateAck_AddedFunction.xml | 7 + .../RicServiceUpdateAck_DeleteFunction.xml | 7 + .../serviceUpdateAck/RicServiceUpdateAck_Empty.xml | 7 + .../RicServiceUpdateAck_ModifiedFunction.xml | 7 + .../resources/setupRequest/setupRequest_en-gNB.xml | 37 ++ .../resources/setupRequest/setupRequest_enb.xml | 35 ++ .../resources/setupRequest/setupRequest_gnb.xml | 38 ++ .../setupRequest_gnb_with_zero_functions.xml | 35 ++ .../setupRequest_gnb_without_functions.xml | 35 ++ .../resources/setupRequest/setupRequest_ng-eNB.xml | 37 ++ .../setupRequest/setupRequest_with_oid_gnb.xml | 53 +++ 47 files changed, 3394 insertions(+), 243 deletions(-) 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 create mode 100644 E2Manager/models/constants.go create mode 100644 E2Manager/models/e2_node_configuration_update.go create mode 100644 E2Manager/models/e2_node_configuration_update_ack.go create mode 100644 E2Manager/models/e2_node_configuration_update_ack_test.go create mode 100644 E2Manager/models/e2_node_configuration_update_test.go create mode 100644 E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdate.xml create mode 100644 E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdateAdditionAndUpdateOnly.xml create mode 100644 E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdateOnlyAddition.xml diff --git a/E2Manager/build-e2mgr-ubuntu.sh b/E2Manager/build-e2mgr-ubuntu.sh index e584005..13059d9 100755 --- a/E2Manager/build-e2mgr-ubuntu.sh +++ b/E2Manager/build-e2mgr-ubuntu.sh @@ -31,11 +31,11 @@ set -eux echo "--> e2mgr-build-ubuntu.sh" # Install RMR from deb packages at packagecloud.io -rmr=rmr_4.8.0_amd64.deb +rmr=rmr_4.8.3_amd64.deb wget --content-disposition https://packagecloud.io/o-ran-sc/release/packages/debian/stretch/$rmr/download.deb sudo dpkg -i $rmr rm $rmr -rmrdev=rmr-dev_4.8.0_amd64.deb +rmrdev=rmr-dev_4.8.3_amd64.deb wget --content-disposition https://packagecloud.io/o-ran-sc/release/packages/debian/stretch/$rmrdev/download.deb sudo dpkg -i $rmrdev rm $rmrdev diff --git a/E2Manager/go.mod b/E2Manager/go.mod index 7a9abf3..c464026 100644 --- a/E2Manager/go.mod +++ b/E2Manager/go.mod @@ -2,7 +2,7 @@ module e2mgr require ( gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.2.1 - gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.3 + gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.4-0.20220331130243-8ea5c5358ce9 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.2.1 gerrit.o-ran-sc.org/r/ric-plt/sdlgo v0.8.0 github.com/golang/protobuf v1.4.2 diff --git a/E2Manager/go.sum b/E2Manager/go.sum index 4a9b36e..398c388 100644 --- a/E2Manager/go.sum +++ b/E2Manager/go.sum @@ -5,6 +5,8 @@ gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.1 h1:8Z60JRsPgcS1Ona4 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.1/go.mod h1:YaQ+XEI4PcAoISxp9wUpUr2TP0J7JihpQTD0G1Lpd4A= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.3 h1:fF5SA51FeEB9of/Q9a17ADUbCa3cU6oNkXY7GlFSvhs= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.3/go.mod h1:YaQ+XEI4PcAoISxp9wUpUr2TP0J7JihpQTD0G1Lpd4A= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.4-0.20220331130243-8ea5c5358ce9 h1:Z6NfwityKkVM0t6n/hAPwRvCsQwW3InMqQR62VlkvZI= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.4-0.20220331130243-8ea5c5358ce9/go.mod h1:YaQ+XEI4PcAoISxp9wUpUr2TP0J7JihpQTD0G1Lpd4A= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.2.1 h1:BG3kste8PLVTG0m8CRB/VP2tAV5JImKueBGuOsUNcR8= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.2.1/go.mod h1:zX8rW6YEsagHrRGVW5YO50Ku/Csrpzsuvblhr4DbYi4= gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.8.0 h1:H7GtCRC+pGn6oOxYalUZr7LinQX5jQCVa+ConX7PB5Q= 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..fa8efc5 --- /dev/null +++ b/E2Manager/handlers/rmrmsghandlers/e2_node_config_update_notification_handler.go @@ -0,0 +1,218 @@ +// +// 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/rmrCgo" + "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) + e.handleSuccessfulResponse(e2NodeConfig, request, nodebInfo) +} + +func (e *E2nodeConfigUpdateNotificationHandler) updateE2nodeConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) { + e.handleAddConfig(e2nodeConfig, nodebInfo) + e.handleUpdateConfig(e2nodeConfig, nodebInfo) + e.handleDeleteConfig(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) handleUpdateConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) { + updateList := e2nodeConfig.ExtractConfigUpdateList() + if nodebInfo.GetNodeType() == entities.Node_GNB { + for i := 0; i < len(updateList); i++ { + u := updateList[i] + if nodebInfo.GetNodeType() == entities.Node_GNB { + for j := 0; j < len(nodebInfo.GetGnb().NodeConfigs); j++ { + if e.compareConfigIDs(u, *nodebInfo.GetGnb().NodeConfigs[j]) { + e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i) + nodebInfo.GetGnb().NodeConfigs[i] = &u + break + } else { + e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - dint match") + } + } + } + } + } else { + for i := 0; i < len(updateList); i++ { + u := updateList[i] + if nodebInfo.GetNodeType() == entities.Node_ENB { + for j := 0; j < len(nodebInfo.GetEnb().NodeConfigs); j++ { + v := nodebInfo.GetEnb().NodeConfigs[j] + if e.compareConfigIDs(u, *v) { + e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i) + nodebInfo.GetEnb().NodeConfigs[i] = &u + break + } + } + } + + } + } +} + +func (e *E2nodeConfigUpdateNotificationHandler) handleDeleteConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) { + deleteList := e2nodeConfig.ExtractConfigDeletionList() + + for _, u := range deleteList { + if nodebInfo.GetNodeType() == entities.Node_ENB { + for i, v := range nodebInfo.GetEnb().NodeConfigs { + if e.compareConfigIDs(u, *v) { + nodebInfo.GetEnb().NodeConfigs = removeIndex(nodebInfo.GetEnb().GetNodeConfigs(), i) + break + } + } + } + + if nodebInfo.GetNodeType() == entities.Node_GNB { + for i, v := range nodebInfo.GetGnb().NodeConfigs { + if e.compareConfigIDs(u, *v) { + nodebInfo.GetGnb().NodeConfigs = removeIndex(nodebInfo.GetGnb().GetNodeConfigs(), i) + break + } + } + } + } +} + +func removeIndex(s []*entities.E2NodeComponentConfig, index int) []*entities.E2NodeComponentConfig { + if index < len(s) { + return append(s[:index], s[index+1:]...) + } + return s +} + +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 +} + +func (e *E2nodeConfigUpdateNotificationHandler) handleSuccessfulResponse(e2NodeConfigUpdate *models.E2nodeConfigurationUpdateMessage, request *models.NotificationRequest, nodebInfo *entities.NodebInfo) error { + e2nodeConfigUpdateResp := models.NewE2nodeConfigurationUpdateSuccessResponseMessage(e2NodeConfigUpdate) + payLoad, err := xml.Marshal(e2nodeConfigUpdateResp) + if err != nil { + e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Error marshalling RIC_SERVICE_UPDATE_ACK. Payload: %s", payLoad) + } + + payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, toReplaceTags) + e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Sending RIC_SERVICE_UPDATE_ACK to RAN name: %s with payload %s", nodebInfo.RanName, payLoad) + msg := models.NewRmrMessage(rmrCgo.RIC_SERVICE_UPDATE_ACK, nodebInfo.RanName, payLoad, request.TransactionId, request.GetMsgSrc()) + err = e.rmrSender.Send(msg) + return err +} 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..50999ea --- /dev/null +++ b/E2Manager/handlers/rmrmsghandlers/e2_node_config_update_notification_handler_test.go @@ -0,0 +1,157 @@ +// +// 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" + E2nodeConfigUpdateOnlyAdditionAndUpdateXmlPath = "../../tests/resources/configurationUpdate/e2NodeConfigurationUpdateAdditionAndUpdateOnly.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, 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) + 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 TestHandleAddAndUpdateConfig(t *testing.T) { + e2NodeConfigUpdateXml := utils.ReadXmlFile(t, E2nodeConfigUpdateOnlyAdditionAndUpdateXmlPath) + + 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)) + assert.Equal(t, "nginterf", nodebInfo.GetGnb().NodeConfigs[0].GetE2NodeComponentInterfaceTypeNG().AmfName) + assert.Equal(t, "72 65 71 70 61 72 73", string(nodebInfo.GetGnb().NodeConfigs[0].E2NodeComponentRequestPart)) + assert.Equal(t, "72 65 73 70 61 72 73", string(nodebInfo.GetGnb().NodeConfigs[0].E2NodeComponentResponsePart)) + + writerMock.AssertExpectations(t) + readerMock.AssertExpectations(t) +} + +func TestHandleAddandDeleteConfig(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 nodeconfig : %d", len(nodebInfo.GetGnb().NodeConfigs)) + + assert.Equal(t, 0, len(nodebInfo.GetGnb().NodeConfigs)) + + writerMock.AssertExpectations(t) + readerMock.AssertExpectations(t) +} diff --git a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go index b2e1633..8f4aacd 100644 --- a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go +++ b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go @@ -34,15 +34,16 @@ import ( "encoding/xml" "errors" "fmt" - "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common" - "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" "strconv" "strings" + + "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 ( emptyTagsToReplaceToSelfClosingTags = []string{"reject", "ignore", "transport-resource-unavailable", "om-intervention", "request-id-unknown", - "v60s", "v20s", "v10s", "v5s", "v2s", "v1s"} + "v60s", "v20s", "v10s", "v5s", "v2s", "v1s", "ng", "xn", "e1", "f1", "w1", "s1", "x2", "success", "failure"} gnbTypesMap = map[string]entities.GnbType{ "gnb": entities.GnbType_GNB, "en_gnb": entities.GnbType_EN_GNB, @@ -93,14 +94,6 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR return } - h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - got general configuration from rnib - enableRic: %t", generalConfiguration.EnableRic) - - if !generalConfiguration.EnableRic { - cause := models.Cause{Misc: &models.CauseMisc{OmIntervention: &struct{}{}}} - h.handleUnsuccessfulResponse(ranName, request, cause) - return - } - setupRequest, e2tIpAddress, err := h.parseSetupRequest(request.Payload) if err != nil { h.logger.Errorf(err.Error()) @@ -110,6 +103,14 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - E2T Address: %s - handling E2_SETUP_REQUEST", e2tIpAddress) h.logger.Debugf("#E2SetupRequestNotificationHandler.Handle - E2_SETUP_REQUEST has been parsed successfully %+v", setupRequest) + h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - got general configuration from rnib - enableRic: %t", generalConfiguration.EnableRic) + + if !generalConfiguration.EnableRic { + cause := models.Cause{Misc: &models.CauseMisc{OmIntervention: &struct{}{}}} + h.handleUnsuccessfulResponse(ranName, request, cause, setupRequest) + return + } + _, err = h.e2tInstancesManager.GetE2TInstance(e2tIpAddress) if err != nil { @@ -131,7 +132,7 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR if nodebInfo, err = h.handleNewRan(ranName, e2tIpAddress, setupRequest); err != nil { if _, ok := err.(*e2managererrors.UnknownSetupRequestRanNameError); ok { cause := models.Cause{RicRequest: &models.CauseRic{RequestIdUnknown: &struct{}{}}} - h.handleUnsuccessfulResponse(ranName, request, cause) + h.handleUnsuccessfulResponse(ranName, request, cause, setupRequest) } return } @@ -157,7 +158,7 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR } cause := models.Cause{Transport: &models.CauseTransport{TransportResourceUnavailable: &struct{}{}}} - h.handleUnsuccessfulResponse(nodebInfo.RanName, request, cause) + h.handleUnsuccessfulResponse(nodebInfo.RanName, request, cause, setupRequest) } return } @@ -220,10 +221,25 @@ func (h *E2SetupRequestNotificationHandler) handleExistingRan(ranName string, no nodebInfo.SetupFromNetwork = true + e2NodeConfig := setupRequest.ExtractE2NodeConfigList() + if e2NodeConfig == nil { + return false, errors.New("Empty E2nodeComponentConfigAddition-List") + } + if nodebInfo.NodeType == entities.Node_ENB { + if len(e2NodeConfig) == 0 && len(nodebInfo.GetEnb().GetNodeConfigs()) == 0 { + return false, errors.New("Empty E2nodeComponentConfigAddition-List") + } + nodebInfo.GetEnb().NodeConfigs = e2NodeConfig + return false, nil } + if len(e2NodeConfig) == 0 && len(nodebInfo.GetGnb().GetNodeConfigs()) == 0 { + return false, errors.New("Empty E2nodeComponentConfigAddition-List") + } + nodebInfo.GetGnb().NodeConfigs = e2NodeConfig + setupMessageRanFuncs := setupRequest.ExtractRanFunctionsList() if setupMessageRanFuncs == nil || (len(setupMessageRanFuncs) == 0 && len(nodebInfo.GetGnb().RanFunctions) == 0) { @@ -234,8 +250,8 @@ func (h *E2SetupRequestNotificationHandler) handleExistingRan(ranName string, no return true, nil } -func (h *E2SetupRequestNotificationHandler) handleUnsuccessfulResponse(ranName string, req *models.NotificationRequest, cause models.Cause) { - failureResponse := models.NewE2SetupFailureResponseMessage(models.TimeToWaitEnum.V60s, cause) +func (h *E2SetupRequestNotificationHandler) handleUnsuccessfulResponse(ranName string, req *models.NotificationRequest, cause models.Cause, setupRequest *models.E2SetupRequestMessage) { + failureResponse := models.NewE2SetupFailureResponseMessage(models.TimeToWaitEnum.V60s, cause, setupRequest) h.logger.Debugf("#E2SetupRequestNotificationHandler.handleUnsuccessfulResponse - E2_SETUP_RESPONSE has been built successfully %+v", failureResponse) responsePayload, err := xml.Marshal(&failureResponse.E2APPDU) @@ -243,7 +259,7 @@ func (h *E2SetupRequestNotificationHandler) handleUnsuccessfulResponse(ranName s h.logger.Warnf("#E2SetupRequestNotificationHandler.handleUnsuccessfulResponse - RAN name: %s - Error marshalling RIC_E2_SETUP_RESP. Payload: %s", ranName, responsePayload) } - responsePayload = utils.ReplaceEmptyTagsWithSelfClosing(responsePayload,emptyTagsToReplaceToSelfClosingTags) + responsePayload = utils.ReplaceEmptyTagsWithSelfClosing(responsePayload, emptyTagsToReplaceToSelfClosingTags) h.logger.Infof("#E2SetupRequestNotificationHandler.handleUnsuccessfulResponse - payload: %s", responsePayload) msg := models.NewRmrMessage(rmrCgo.RIC_E2_SETUP_FAILURE, ranName, responsePayload, req.TransactionId, req.GetMsgSrc()) @@ -268,7 +284,7 @@ func (h *E2SetupRequestNotificationHandler) handleSuccessfulResponse(ranName str h.logger.Warnf("#E2SetupRequestNotificationHandler.handleSuccessfulResponse - RAN name: %s - Error marshalling RIC_E2_SETUP_RESP. Payload: %s", ranName, responsePayload) } - responsePayload = utils.ReplaceEmptyTagsWithSelfClosing(responsePayload,emptyTagsToReplaceToSelfClosingTags) + responsePayload = utils.ReplaceEmptyTagsWithSelfClosing(responsePayload, emptyTagsToReplaceToSelfClosingTags) h.logger.Infof("#E2SetupRequestNotificationHandler.handleSuccessfulResponse - payload: %s", responsePayload) @@ -337,10 +353,25 @@ func (h *E2SetupRequestNotificationHandler) buildNodebInfo(ranName string, e2tAd return nil, err } + e2NodeConfig := request.ExtractE2NodeConfigList() + if e2NodeConfig == nil { + return nil, errors.New("Empty E2nodeComponentConfigAddition-List") + } + if nodebInfo.NodeType == entities.Node_ENB { + if len(e2NodeConfig) == 0 && len(nodebInfo.GetEnb().GetNodeConfigs()) == 0 { + return nil, errors.New("Empty E2nodeComponentConfigAddition-List") + } + nodebInfo.GetEnb().NodeConfigs = e2NodeConfig + return nodebInfo, nil } + if len(e2NodeConfig) == 0 && len(nodebInfo.GetGnb().GetNodeConfigs()) == 0 { + return nil, errors.New("Empty E2nodeComponentConfigAddition-List") + } + nodebInfo.GetGnb().NodeConfigs = e2NodeConfig + ranFuncs := request.ExtractRanFunctionsList() if ranFuncs != nil { diff --git a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go index d3a7ae2..aff0ebb 100644 --- a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go +++ b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go @@ -1,7 +1,7 @@ // // Copyright 2019 AT&T Intellectual Property // Copyright 2019 Nokia -// Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved. +// 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. @@ -32,11 +32,12 @@ import ( "e2mgr/utils" "encoding/xml" "errors" + "testing" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common" "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "testing" ) const ( @@ -50,9 +51,9 @@ const ( NgEnbSetupRequestXmlPath = "../../tests/resources/setupRequest/setupRequest_ng-eNB.xml" EnbSetupRequestXmlPath = "../../tests/resources/setupRequest/setupRequest_enb.xml" GnbWithoutFunctionsSetupRequestXmlPath = "../../tests/resources/setupRequest/setupRequest_gnb_without_functions.xml" - E2SetupFailureResponseWithMiscCause = "1131" - E2SetupFailureResponseWithTransportCause = "1131" - E2SetupFailureResponseWithRicCause = "1131" + E2SetupFailureResponseWithMiscCause = "1491131" + E2SetupFailureResponseWithTransportCause = "1491131" + E2SetupFailureResponseWithRicCause = "1491131" StateChangeMessageChannel = "RAN_CONNECTION_STATUS_CHANGE" ) @@ -468,6 +469,7 @@ func getExpectedGnbNodebForNewRan(payload []byte) *entities.NodebInfo { Gnb: &entities.Gnb{ GnbType: entities.GnbType_GNB, RanFunctions: setupRequest.ExtractRanFunctionsList(), + NodeConfigs: setupRequest.ExtractE2NodeConfigList(), }, }, GlobalNbId: &entities.GlobalNbId{ @@ -491,7 +493,8 @@ func getExpectedEnbNodebForNewRan(payload []byte) *entities.NodebInfo { NodeType: entities.Node_ENB, Configuration: &entities.NodebInfo_Enb{ Enb: &entities.Enb{ - EnbType: entities.EnbType_MACRO_ENB, + EnbType: entities.EnbType_MACRO_ENB, + NodeConfigs: setupRequest.ExtractE2NodeConfigList(), }, }, GlobalNbId: &entities.GlobalNbId{ @@ -515,13 +518,26 @@ func getExpectedNodebForExistingRan(nodeb *entities.NodebInfo, payload []byte) * nb := *nodeb if nodeb.NodeType == entities.Node_ENB { + if e2NodeConfig := setupRequest.ExtractE2NodeConfigList(); e2NodeConfig != nil { + updatedEnb := *nodeb.GetEnb() + updatedEnb.NodeConfigs = e2NodeConfig + nb.Configuration = &entities.NodebInfo_Enb{Enb: &updatedEnb} + } + return &nb } if ranFuncs := setupRequest.ExtractRanFunctionsList(); ranFuncs != nil { updatedGnb := *nodeb.GetGnb() updatedGnb.RanFunctions = ranFuncs - nb.Configuration =&entities.NodebInfo_Gnb{Gnb: &updatedGnb} + nb.Configuration = &entities.NodebInfo_Gnb{Gnb: &updatedGnb} + } + + if e2NodeConfig := setupRequest.ExtractE2NodeConfigList(); e2NodeConfig != nil { + updatedGnb := *nodeb.GetGnb() + updatedGnb.RanFunctions = nb.GetGnb().RanFunctions + updatedGnb.NodeConfigs = e2NodeConfig + nb.Configuration = &entities.NodebInfo_Gnb{Gnb: &updatedGnb} } return &nb @@ -687,6 +703,16 @@ func TestE2SetupRequestNotificationHandler_HandleExistingConnectedGnbRoutingMana gnb := nodebInfo.GetGnb() gnb.RanFunctions = []*entities.RanFunction{{RanFunctionId: 2, RanFunctionRevision: 2}} + gnb.NodeConfigs = []*entities.E2NodeComponentConfig{{ + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeNG{ + E2NodeComponentInterfaceTypeNG: &entities.E2NodeComponentInterfaceNG{ + AmfName: "nginterf", + }, + }, + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_ng, + E2NodeComponentRequestPart: []byte("72 65 73 70 61 72 74"), + E2NodeComponentResponsePart: []byte("72 65 73 70 61 72 74"), + }} readerMock.On("GetNodeb", gnbNodebRanName).Return(nodebInfo, nil) routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceFullAddress, mock.Anything).Return(errors.New("association error")) diff --git a/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler.go b/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler.go index 2f871e7..15f89a8 100644 --- a/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler.go +++ b/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler.go @@ -89,7 +89,7 @@ func (h *RicServiceUpdateHandler) Handle(request *models.NotificationRequest) { h.logger.Infof("#RicServiceUpdateHandler.Handle - RIC_SERVICE_UPDATE has been parsed successfully %+v", ricServiceUpdate) ackFunctionIds := h.updateFunctions(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs, nodebInfo) - if len(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs) != 0 { + if len(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs) > 1 { err = h.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo) if err != nil { h.logger.Errorf("#RicServiceUpdateHandler.Handle - RAN name: %s - Failed at UpdateNodebInfoAndPublish. error: %s", nodebInfo.RanName, err) @@ -104,7 +104,7 @@ func (h *RicServiceUpdateHandler) Handle(request *models.NotificationRequest) { return } - updateAck := models.NewServiceUpdateAck(ackFunctionIds) + updateAck := models.NewServiceUpdateAck(ackFunctionIds, ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs[0].Value.TransactionID) err = h.sendUpdateAck(updateAck, nodebInfo, request) if err != nil { h.logger.Errorf("#RicServiceUpdate.Handle - failed to send RIC_SERVICE_UPDATE_ACK message to RMR: %s", err) diff --git a/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler_test.go b/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler_test.go index 372bf05..6e36298 100644 --- a/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler_test.go +++ b/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler_test.go @@ -29,11 +29,12 @@ import ( "e2mgr/utils" "encoding/xml" "fmt" + "testing" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common" "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "testing" ) const ( @@ -45,11 +46,11 @@ const ( RicServiceUpdateModifiedPath = "../../tests/resources/serviceUpdate/RicServiceUpdate_ModifiedFunction.xml" RicServiceUpdateDeletePath = "../../tests/resources/serviceUpdate/RicServiceUpdate_DeleteFunction.xml" RicServiceUpdateAddedPath = "../../tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction.xml" - RicServiceUpdateEmptyPath = "../../tests/resources/serviceUpdate/RicServiceUpdate_Empty.xml" + RicServiceUpdateEmptyPath = "../../tests/resources/serviceUpdate/RicServiceUpdate_Empty.xml" RicServiceUpdateAckModifiedPath = "../../tests/resources/serviceUpdateAck/RicServiceUpdateAck_ModifiedFunction.xml" RicServiceUpdateAckAddedPath = "../../tests/resources/serviceUpdateAck/RicServiceUpdateAck_AddedFunction.xml" RicServiceUpdateAckDeletePath = "../../tests/resources/serviceUpdateAck/RicServiceUpdateAck_DeleteFunction.xml" - RicServiceUpdateAckEmptyPath = "../../tests/resources/serviceUpdateAck/RicServiceUpdateAck_Empty.xml" + RicServiceUpdateAckEmptyPath = "../../tests/resources/serviceUpdateAck/RicServiceUpdateAck_Empty.xml" ) func initRicServiceUpdateHandler(t *testing.T) (*RicServiceUpdateHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.RanListManagerMock) { @@ -58,7 +59,7 @@ func initRicServiceUpdateHandler(t *testing.T) (*RicServiceUpdateHandler, *mocks RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3, RnibWriter: configuration.RnibWriterConfig{ - StateChangeMessageChannel: StateChangeMessageChannel, + StateChangeMessageChannel: StateChangeMessageChannel, RanManipulationMessageChannel: RanManipulationMessageChannel, }, GlobalRicId: struct { @@ -66,8 +67,8 @@ func initRicServiceUpdateHandler(t *testing.T) (*RicServiceUpdateHandler, *mocks Mcc string Mnc string }{ - Mcc: "337", - Mnc: "94", + Mcc: "337", + Mnc: "94", RicId: "AACCE", }} rmrMessengerMock := &mocks.RmrMessengerMock{} @@ -80,44 +81,22 @@ func initRicServiceUpdateHandler(t *testing.T) (*RicServiceUpdateHandler, *mocks return handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock } - -func TestRICServiceUpdateModifiedFuncSuccess(t *testing.T){ +func TestRICServiceUpdateModifiedFuncSuccess(t *testing.T) { testServiceUpdateSuccess(t, RicServiceUpdateModifiedPath, RicServiceUpdateAckModifiedPath) } -func TestRICServiceUpdateAddedFuncSuccess(t *testing.T){ +func TestRICServiceUpdateAddedFuncSuccess(t *testing.T) { testServiceUpdateSuccess(t, RicServiceUpdateAddedPath, RicServiceUpdateAckAddedPath) } -func TestRICServiceUpdateDeleteFuncSuccess(t *testing.T){ +func TestRICServiceUpdateDeleteFuncSuccess(t *testing.T) { testServiceUpdateSuccess(t, RicServiceUpdateDeletePath, RicServiceUpdateAckDeletePath) } -func TestRICServiceUpdateEmptySuccess(t *testing.T){ +func TestRICServiceUpdateRnibFailure(t *testing.T) { handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t) - xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateEmptyPath) - xmlserviceUpdate = utils.CleanXML(xmlserviceUpdate) - nb1:= createNbInfo(t, serviceUpdateRANName, entities.ConnectionStatus_CONNECTED) - oldnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus} - newnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus} - readerMock.On("GetNodeb", nb1.RanName).Return(nb1, nil) - notificationRequest := &models.NotificationRequest{RanName: serviceUpdateRANName, Payload: append([]byte(serviceUpdateE2SetupMsgPrefix), xmlserviceUpdate...)} - ricServiceAckMsg := createRicServiceQueryAckRMRMbuf(t,RicServiceUpdateAckEmptyPath, notificationRequest ) - ranListManagerMock.On("UpdateHealthcheckTimeStampReceived",nb1.RanName).Return(oldnbIdentity, newnbIdentity) - ranListManagerMock.On("UpdateNbIdentities",nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, []*entities.NbIdentity{newnbIdentity}).Return(nil) - rmrMessengerMock.On("SendMsg",ricServiceAckMsg,true).Return(&rmrCgo.MBuf{}, nil) - - handler.Handle(notificationRequest) - writerMock.AssertExpectations(t) - rmrMessengerMock.AssertNumberOfCalls(t,"SendMsg", 1) - readerMock.AssertExpectations(t) - ranListManagerMock.AssertExpectations(t) -} - -func TestRICServiceUpdateRnibFailure(t *testing.T){ - handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t) - xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateDeletePath) + xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateDeletePath) xmlserviceUpdate = utils.CleanXML(xmlserviceUpdate) readerMock.On("GetNodeb", serviceUpdateRANName).Return(&entities.NodebInfo{}, common.NewInternalError(fmt.Errorf("internal error"))) notificationRequest := &models.NotificationRequest{RanName: serviceUpdateRANName, Payload: append([]byte(serviceUpdateE2SetupMsgPrefix), xmlserviceUpdate...)} @@ -129,9 +108,9 @@ func TestRICServiceUpdateRnibFailure(t *testing.T){ ranListManagerMock.AssertExpectations(t) } -func TestRICServiceUpdateRnibNotFound(t *testing.T){ +func TestRICServiceUpdateRnibNotFound(t *testing.T) { handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t) - xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateModifiedPath) + xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateModifiedPath) xmlserviceUpdate = utils.CleanXML(xmlserviceUpdate) readerMock.On("GetNodeb", serviceUpdateRANName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError("nodeb not found")) notificationRequest := &models.NotificationRequest{RanName: serviceUpdateRANName, Payload: append([]byte(serviceUpdateE2SetupMsgPrefix), xmlserviceUpdate...)} @@ -143,11 +122,11 @@ func TestRICServiceUpdateRnibNotFound(t *testing.T){ ranListManagerMock.AssertExpectations(t) } -func TestRICServiceUpdateNodeBInfoFailure(t *testing.T){ +func TestRICServiceUpdateNodeBInfoFailure(t *testing.T) { handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t) - xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateDeletePath) + xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateDeletePath) xmlserviceUpdate = utils.CleanXML(xmlserviceUpdate) - nb1:= createNbInfo(t, serviceUpdateRANName, entities.ConnectionStatus_CONNECTED) + nb1 := createNbInfo(t, serviceUpdateRANName, entities.ConnectionStatus_CONNECTED) readerMock.On("GetNodeb", nb1.RanName).Return(nb1, nil) notificationRequest := &models.NotificationRequest{RanName: serviceUpdateRANName, Payload: append([]byte(serviceUpdateE2SetupMsgPrefix), xmlserviceUpdate...)} writerMock.On("UpdateNodebInfoAndPublish", mock.Anything).Return(common.NewInternalError(fmt.Errorf("internal error"))) @@ -159,51 +138,51 @@ func TestRICServiceUpdateNodeBInfoFailure(t *testing.T){ ranListManagerMock.AssertExpectations(t) } -func TestSendRICServiceUpdateAckFailure(t *testing.T){ +func TestSendRICServiceUpdateAckFailure(t *testing.T) { handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t) - xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateModifiedPath) + xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateModifiedPath) xmlserviceUpdate = utils.CleanXML(xmlserviceUpdate) - nb1:= createNbInfo(t, serviceUpdateRANName, entities.ConnectionStatus_CONNECTED) + nb1 := createNbInfo(t, serviceUpdateRANName, entities.ConnectionStatus_CONNECTED) oldnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus} newnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus} readerMock.On("GetNodeb", nb1.RanName).Return(nb1, nil) notificationRequest := &models.NotificationRequest{RanName: serviceUpdateRANName, Payload: append([]byte(serviceUpdateE2SetupMsgPrefix), xmlserviceUpdate...)} - ricServiceAckMsg := createRicServiceQueryAckRMRMbuf(t,RicServiceUpdateAckModifiedPath, notificationRequest ) - ranListManagerMock.On("UpdateHealthcheckTimeStampReceived",nb1.RanName).Return(oldnbIdentity, newnbIdentity) + ricServiceAckMsg := createRicServiceQueryAckRMRMbuf(t, RicServiceUpdateAckModifiedPath, notificationRequest) + ranListManagerMock.On("UpdateHealthcheckTimeStampReceived", nb1.RanName).Return(oldnbIdentity, newnbIdentity) writerMock.On("UpdateNodebInfoAndPublish", mock.Anything).Return(nil) - rmrMessengerMock.On("SendMsg",ricServiceAckMsg,true).Return(&rmrCgo.MBuf{}, fmt.Errorf("rmr send failure")) - ranListManagerMock.On("UpdateNbIdentities",nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, []*entities.NbIdentity{newnbIdentity}).Return(nil) + rmrMessengerMock.On("SendMsg", ricServiceAckMsg, true).Return(&rmrCgo.MBuf{}, fmt.Errorf("rmr send failure")) + ranListManagerMock.On("UpdateNbIdentities", nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, []*entities.NbIdentity{newnbIdentity}).Return(nil) handler.Handle(notificationRequest) writerMock.AssertExpectations(t) - rmrMessengerMock.AssertNumberOfCalls(t,"SendMsg", 1) + rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1) readerMock.AssertExpectations(t) ranListManagerMock.AssertExpectations(t) } -func TestRICServiceUpdateUpdateNbIdentitiesFailure(t *testing.T){ +func TestRICServiceUpdateUpdateNbIdentitiesFailure(t *testing.T) { handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t) - xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateDeletePath) + xmlserviceUpdate := utils.ReadXmlFile(t, RicServiceUpdateDeletePath) xmlserviceUpdate = utils.CleanXML(xmlserviceUpdate) - nb1:= createNbInfo(t, serviceUpdateRANName, entities.ConnectionStatus_CONNECTED) + nb1 := createNbInfo(t, serviceUpdateRANName, entities.ConnectionStatus_CONNECTED) oldnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus} newnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus} readerMock.On("GetNodeb", nb1.RanName).Return(nb1, nil) notificationRequest := &models.NotificationRequest{RanName: serviceUpdateRANName, Payload: append([]byte(serviceUpdateE2SetupMsgPrefix), xmlserviceUpdate...)} - ranListManagerMock.On("UpdateHealthcheckTimeStampReceived",nb1.RanName).Return(oldnbIdentity, newnbIdentity) - ranListManagerMock.On("UpdateNbIdentities",nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, []*entities.NbIdentity{newnbIdentity}).Return(common.NewInternalError(fmt.Errorf("internal error"))) + ranListManagerMock.On("UpdateHealthcheckTimeStampReceived", nb1.RanName).Return(oldnbIdentity, newnbIdentity) + ranListManagerMock.On("UpdateNbIdentities", nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, []*entities.NbIdentity{newnbIdentity}).Return(common.NewInternalError(fmt.Errorf("internal error"))) writerMock.On("UpdateNodebInfoAndPublish", mock.Anything).Return(nil) handler.Handle(notificationRequest) writerMock.AssertExpectations(t) - rmrMessengerMock.AssertNumberOfCalls(t,"SendMsg", 0) + rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0) readerMock.AssertExpectations(t) ranListManagerMock.AssertExpectations(t) } func TestRICServiceUpdateParseRequest_PipFailure(t *testing.T) { xmlGnb := utils.ReadXmlFile(t, RICServiceUpdate_E2SetupReqPath) - handler, _, _, _, _:= initRicServiceUpdateHandler(t) + handler, _, _, _, _ := initRicServiceUpdateHandler(t) prefBytes := []byte(serviceUpdateE2tInstanceAddress) ricServiceUpdate, err := handler.parseSetupRequest(append(prefBytes, xmlGnb...)) assert.Nil(t, ricServiceUpdate) @@ -220,31 +199,31 @@ func TestRICServiceUppdateParseRequest_UnmarshalFailure(t *testing.T) { assert.EqualError(t, err, "#RicServiceUpdateHandler.parseSetupRequest - Error unmarshalling RIC SERVICE UPDATE payload: 31302e302e302e32373a393939397c010203") } -func testServiceUpdateSuccess(t *testing.T, servicepdatePath string, serviceUpdateAckPath string){ +func testServiceUpdateSuccess(t *testing.T, servicepdatePath string, serviceUpdateAckPath string) { handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t) - xmlserviceUpdate := utils.ReadXmlFile(t, servicepdatePath) + xmlserviceUpdate := utils.ReadXmlFile(t, servicepdatePath) xmlserviceUpdate = utils.CleanXML(xmlserviceUpdate) - nb1:= createNbInfo(t, serviceUpdateRANName, entities.ConnectionStatus_CONNECTED) + nb1 := createNbInfo(t, serviceUpdateRANName, entities.ConnectionStatus_CONNECTED) oldnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus} newnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus} readerMock.On("GetNodeb", nb1.RanName).Return(nb1, nil) notificationRequest := &models.NotificationRequest{RanName: serviceUpdateRANName, Payload: append([]byte(serviceUpdateE2SetupMsgPrefix), xmlserviceUpdate...)} - ricServiceAckMsg := createRicServiceQueryAckRMRMbuf(t,serviceUpdateAckPath, notificationRequest ) - ranListManagerMock.On("UpdateHealthcheckTimeStampReceived",nb1.RanName).Return(oldnbIdentity, newnbIdentity) - ranListManagerMock.On("UpdateNbIdentities",nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, + ricServiceAckMsg := createRicServiceQueryAckRMRMbuf(t, serviceUpdateAckPath, notificationRequest) + ranListManagerMock.On("UpdateHealthcheckTimeStampReceived", nb1.RanName).Return(oldnbIdentity, newnbIdentity) + ranListManagerMock.On("UpdateNbIdentities", nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, []*entities.NbIdentity{newnbIdentity}).Return(nil) writerMock.On("UpdateNodebInfoAndPublish", mock.Anything).Return(nil) - rmrMessengerMock.On("SendMsg",ricServiceAckMsg,true).Return(&rmrCgo.MBuf{}, nil) + rmrMessengerMock.On("SendMsg", ricServiceAckMsg, true).Return(&rmrCgo.MBuf{}, nil) handler.Handle(notificationRequest) writerMock.AssertExpectations(t) - rmrMessengerMock.AssertNumberOfCalls(t,"SendMsg", 1) + rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1) readerMock.AssertExpectations(t) ranListManagerMock.AssertExpectations(t) } -func createRicServiceQueryAckRMRMbuf(t *testing.T, xmlFile string, req *models.NotificationRequest) *rmrCgo.MBuf{ +func createRicServiceQueryAckRMRMbuf(t *testing.T, xmlFile string, req *models.NotificationRequest) *rmrCgo.MBuf { ricServiceQueryAckXml := utils.ReadXmlFile(t, xmlFile) ricServiceQueryAckXml = utils.CleanXML(ricServiceQueryAckXml) payLoad := utils.NormalizeXml(ricServiceQueryAckXml) @@ -256,7 +235,7 @@ func createRicServiceQueryAckRMRMbuf(t *testing.T, xmlFile string, req *models. return rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction, rmrMessage.GetMsgSrc()) } -func createNbInfo(t *testing.T, RanName string, connectionStatus entities.ConnectionStatus) *entities.NodebInfo { +func createNbInfo(t *testing.T, RanName string, connectionStatus entities.ConnectionStatus) *entities.NodebInfo { xmlgnb := utils.ReadXmlFile(t, RICServiceUpdate_E2SetupReqPath) xmlgnb = utils.CleanXML(xmlgnb) payload := append([]byte(serviceUpdateE2SetupMsgPrefix), xmlgnb...) @@ -272,7 +251,7 @@ func createNbInfo(t *testing.T, RanName string, connectionStatus entities.Conne RanName: RanName, SetupFromNetwork: true, NodeType: entities.Node_GNB, - ConnectionStatus: connectionStatus, + ConnectionStatus: connectionStatus, Configuration: &entities.NodebInfo_Gnb{ Gnb: &entities.Gnb{ GnbType: entities.GnbType_GNB, @@ -286,4 +265,3 @@ func createNbInfo(t *testing.T, RanName string, connectionStatus entities.Conne } return nodeb } - diff --git a/E2Manager/models/constants.go b/E2Manager/models/constants.go new file mode 100644 index 0000000..143aa5d --- /dev/null +++ b/E2Manager/models/constants.go @@ -0,0 +1,39 @@ +// +// 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 models + +const ( + ProtocolIE_ID_id_RANfunctionID_Item = "6" + ProtocolIE_ID_id_RANfunctionsAccepted = "9" + ProtocolIE_ID_id_E2nodeComponentConfigUpdateAck = "35" + ProtocolIE_ID_id_E2nodeComponentConfigUpdateAck_Item = "36" + ProtocolIE_ID_id_TransactionID = "49" + ProtocolIE_ID_id_E2nodeComponentConfigAddition = "50" + ProtocolIE_ID_id_E2nodeComponentConfigAdditionAck = "52" + ProtocolIE_ID_id_E2nodeComponentConfigAdditionAck_Item = "53" + ProtocolIE_ID_id_E2nodeComponentConfigRemoval = "54" + ProtocolIE_ID_id_E2nodeComponentConfigRemovalAck = "56" + ProtocolIE_ID_id_E2nodeComponentConfigRemovalAck_Item = "57" +) + +const ( + ProcedureCode_id_RICserviceQuery = "6" + ProcedureCode_id_E2nodeConfigurationUpdate = "10" + ProcedureCode_id_RICserviceUpdate = "7" +) diff --git a/E2Manager/models/e2_node_configuration_update.go b/E2Manager/models/e2_node_configuration_update.go new file mode 100644 index 0000000..c1773a0 --- /dev/null +++ b/E2Manager/models/e2_node_configuration_update.go @@ -0,0 +1,512 @@ +// +// Copyright 2022 Samsung Electronics Co. +// +// 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 models + +import ( + "encoding/xml" + "strconv" + + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" +) + +type E2nodeConfigurationUpdateMessage struct { + XMLName xml.Name `xml:"E2nodeConfigurationUpdateMessage"` + Text string `xml:",chardata"` + E2APPDU struct { + Text string `xml:",chardata"` + InitiatingMessage struct { + Text string `xml:",chardata"` + ProcedureCode string `xml:"procedureCode"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2nodeConfigurationUpdate E2nodeConfigurationUpdate `xml:"E2nodeConfigurationUpdate"` + } `xml:"value"` + } `xml:"initiatingMessage"` + } `xml:"E2AP-PDU"` +} + +type E2nodeConfigurationUpdate struct { + Text string `xml:",chardata"` + ProtocolIEs struct { + Text string `xml:",chardata"` + E2nodeConfigurationUpdateIEs []E2nodeConfigurationUpdateIE `xml:"E2nodeConfigurationUpdate-IEs"` + } `xml:"protocolIEs"` +} + +type E2nodeConfigurationUpdateIE struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + TransactionID string `xml:"TransactionID"` + E2nodeComponentConfigAdditionList E2nodeComponentConfigAdditionList `xml:"E2nodeComponentConfigAddition-List"` + E2nodeComponentConfigUpdateList E2nodeComponentConfigUpdateList `xml:"E2nodeComponentConfigUpdate-List"` + E2nodeComponentConfigRemovalList E2nodeComponentConfigRemovalList `xml:"E2nodeComponentConfigRemoval-List"` + } `xml:"value"` +} + +type E2nodeComponentConfigAdditionList struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2nodeComponentConfigAdditionItem struct { + Text string `xml:",chardata"` + E2nodeComponentInterfaceType E2nodeComponentInterfaceType `xml:"e2nodeComponentInterfaceType"` + E2nodeComponentID E2nodeComponentID `xml:"e2nodeComponentID"` + E2nodeComponentConfiguration E2nodeComponentConfiguration `xml:"e2nodeComponentConfiguration"` + } `xml:"E2nodeComponentConfigAddition-Item"` + } `xml:"value"` + } `xml:"ProtocolIE-SingleContainer"` +} + +type E2nodeComponentConfigUpdateList struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2nodeComponentConfigUpdateItem struct { + Text string `xml:",chardata"` + E2nodeComponentInterfaceType E2nodeComponentInterfaceType `xml:"e2nodeComponentInterfaceType"` + E2nodeComponentID E2nodeComponentID `xml:"e2nodeComponentID"` + E2nodeComponentConfiguration E2nodeComponentConfiguration `xml:"e2nodeComponentConfiguration"` + } `xml:"E2nodeComponentConfigUpdate-Item"` + } `xml:"value"` + } `xml:"ProtocolIE-SingleContainer"` +} + +type E2nodeComponentConfigRemovalList struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2nodeComponentConfigRemovalItem struct { + Text string `xml:",chardata"` + E2nodeComponentInterfaceType E2nodeComponentInterfaceType `xml:"e2nodeComponentInterfaceType"` + E2nodeComponentID E2nodeComponentID `xml:"e2nodeComponentID"` + } `xml:"E2nodeComponentConfigRemoval-Item"` + } `xml:"value"` + } `xml:"ProtocolIE-SingleContainer"` +} + +type E2nodeComponentInterfaceType struct { + Text string `xml:",chardata"` + Ng *struct{} `xml:"ng"` + Xn *struct{} `xml:"xn"` + E1 *struct{} `xml:"e1"` + F1 *struct{} `xml:"f1"` + W1 *struct{} `xml:"w1"` + S1 *struct{} `xml:"s1"` + X2 *struct{} `xml:"x2"` +} + +type E2nodeComponentID struct { + Text string `xml:",chardata"` + E2nodeComponentInterfaceTypeNG struct { + Text string `xml:",chardata"` + AmfName string `xml:"amf-name"` + } `xml:"e2nodeComponentInterfaceTypeNG"` + E2nodeComponentInterfaceTypeXn struct { + Text string `xml:",chardata"` + GlobalNGRANNodeID string `xml:"global-NG-RAN-Node-ID"` + } `xml:"e2nodeComponentInterfaceTypeXn"` + E2nodeComponentInterfaceTypeE1 struct { + Text string `xml:",chardata"` + GNBCUCPID string `xml:"gNB-CU-CP-ID"` + } `xml:"e2nodeComponentInterfaceTypeE1"` + E2nodeComponentInterfaceTypeF1 struct { + Text string `xml:",chardata"` + GNBDUID string `xml:"gNB-DU-ID"` + } `xml:"e2nodeComponentInterfaceTypeF1"` + E2nodeComponentInterfaceTypeW1 struct { + Text string `xml:",chardata"` + NgENBDUID string `xml:"ng-eNB-DU-ID"` + } `xml:"e2nodeComponentInterfaceTypeW1"` + E2nodeComponentInterfaceTypeS1 struct { + Text string `xml:",chardata"` + MmeName string `xml:"mme-name"` + } `xml:"e2nodeComponentInterfaceTypeS1"` + E2nodeComponentInterfaceTypeX2 struct { + Text string `xml:",chardata"` + GlobalENBID string `xml:"global-eNB-ID"` + GlobalEnGNBID string `xml:"global-en-gNB-ID"` + } `xml:"e2nodeComponentInterfaceTypeX2"` +} + +type E2nodeComponentConfiguration struct { + Text string `xml:",chardata"` + E2nodeComponentRequestPart string `xml:"e2nodeComponentRequestPart"` + E2nodeComponentResponsePart string `xml:"e2nodeComponentResponsePart"` +} + +func (m *E2nodeConfigurationUpdateMessage) ExtractConfigAdditionList() []entities.E2NodeComponentConfig { + var result []entities.E2NodeComponentConfig + e2nodeConfigUpdateIEs := m.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs + + var additionList *E2nodeComponentConfigAdditionList + for _, v := range e2nodeConfigUpdateIEs { + if v.ID == ProtocolIE_ID_id_E2nodeComponentConfigAddition { + additionList = &(v.Value.E2nodeComponentConfigAdditionList) + break + } + } + + // need not to check for empty addtionList + // as list defined as SIZE(1..maxofE2nodeComponents) + if additionList != nil { + for _, val := range additionList.ProtocolIESingleContainer { + componentItem := val.Value.E2nodeComponentConfigAdditionItem + if componentItem.E2nodeComponentInterfaceType.Ng != nil { // NG Interface + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_ng, + E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeNG{ + E2NodeComponentInterfaceTypeNG: &entities.E2NodeComponentInterfaceNG{ + AmfName: componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeNG.AmfName, + }, + }, + }) + } + + // TODO - Not Supported Yet + if componentItem.E2nodeComponentInterfaceType.Xn != nil { // xn inetrface + // result = append(result, entities.E2NodeComponentConfig{ + // E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_xn, + // E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + // E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + // E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeXn{}, + // }) + } + + if componentItem.E2nodeComponentInterfaceType.E1 != nil { // e1 interface + gnbCuCpId, err := strconv.ParseInt(componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeE1.GNBCUCPID, 10, 64) + if err != nil { + continue + } + + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_e1, + E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeE1{ + E2NodeComponentInterfaceTypeE1: &entities.E2NodeComponentInterfaceE1{ + GNBCuCpId: gnbCuCpId, + }, + }, + }) + } + + if componentItem.E2nodeComponentInterfaceType.F1 != nil { // f1 interface + gnbDuId, err := strconv.ParseInt(componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeF1.GNBDUID, 10, 64) + if err != nil { + continue + } + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_f1, + E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeF1{ + E2NodeComponentInterfaceTypeF1: &entities.E2NodeComponentInterfaceF1{ + GNBDuId: gnbDuId, + }, + }, + }) + } + + if componentItem.E2nodeComponentInterfaceType.W1 != nil { // w1 interface + ngenbDuId, err := strconv.ParseInt(componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeW1.NgENBDUID, 10, 64) + if err != nil { + continue + } + + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_w1, + E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeW1{ + E2NodeComponentInterfaceTypeW1: &entities.E2NodeComponentInterfaceW1{ + NgenbDuId: ngenbDuId, + }, + }, + }) + } + + if componentItem.E2nodeComponentInterfaceType.S1 != nil { // s1 interface + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_s1, + E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeS1{ + E2NodeComponentInterfaceTypeS1: &entities.E2NodeComponentInterfaceS1{ + MmeName: componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeS1.MmeName, + }, + }, + }) + } + + // TODO - Not Supported Yet + if componentItem.E2nodeComponentInterfaceType.X2 != nil { // x2 interface + // result = append(result, entities.E2NodeComponentConfig{ + // E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_x2, + // E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + // E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + // E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeX2{}, + // }) + + } + } + } + return result +} + +func (m *E2nodeConfigurationUpdateMessage) ExtractConfigUpdateList() []entities.E2NodeComponentConfig { + var result []entities.E2NodeComponentConfig + e2nodeConfigUpdateIEs := m.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs + + var updateList *E2nodeComponentConfigUpdateList + for _, v := range e2nodeConfigUpdateIEs { + if v.ID == "33" { + updateList = &(v.Value.E2nodeComponentConfigUpdateList) + break + } + } + + // need not to check for empty addtionList + // as list defined as SIZE(1..maxofE2nodeComponents) + if updateList != nil { + for _, val := range updateList.ProtocolIESingleContainer { + componentItem := val.Value.E2nodeComponentConfigUpdateItem + if componentItem.E2nodeComponentInterfaceType.Ng != nil { // NG Interface + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_ng, + E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeNG{ + E2NodeComponentInterfaceTypeNG: &entities.E2NodeComponentInterfaceNG{ + AmfName: componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeNG.AmfName, + }, + }, + }) + continue + } + + if componentItem.E2nodeComponentInterfaceType.Xn != nil { // xn inetrface + // TODO - Not Supported Yet + continue + } + + if componentItem.E2nodeComponentInterfaceType.E1 != nil { // e1 interface + gnbCuCpId, err := strconv.ParseInt(componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeE1.GNBCUCPID, 10, 64) + if err == nil { + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_e1, + E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeE1{ + E2NodeComponentInterfaceTypeE1: &entities.E2NodeComponentInterfaceE1{ + GNBCuCpId: gnbCuCpId, + }, + }, + }) + } + continue + } + + if componentItem.E2nodeComponentInterfaceType.F1 != nil { // f1 interface + gnbDuId, err := strconv.ParseInt(componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeF1.GNBDUID, 10, 64) + if err == nil { + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_f1, + E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeF1{ + E2NodeComponentInterfaceTypeF1: &entities.E2NodeComponentInterfaceF1{ + GNBDuId: gnbDuId, + }, + }, + }) + } + continue + } + + if componentItem.E2nodeComponentInterfaceType.W1 != nil { // w1 interface + ngenbDuId, err := strconv.ParseInt(componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeW1.NgENBDUID, 10, 64) + if err == nil { + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_w1, + E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeW1{ + E2NodeComponentInterfaceTypeW1: &entities.E2NodeComponentInterfaceW1{ + NgenbDuId: ngenbDuId, + }, + }, + }) + } + continue + } + + if componentItem.E2nodeComponentInterfaceType.S1 != nil { // s1 interface + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_s1, + E2NodeComponentRequestPart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentRequestPart), + E2NodeComponentResponsePart: []byte(componentItem.E2nodeComponentConfiguration.E2nodeComponentResponsePart), + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeS1{ + E2NodeComponentInterfaceTypeS1: &entities.E2NodeComponentInterfaceS1{ + MmeName: componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeS1.MmeName, + }, + }, + }) + continue + } + + if componentItem.E2nodeComponentInterfaceType.X2 != nil { // x2 interface + // TODO - Not Supported Yet + continue + } + } + } + return result +} + +func (m *E2nodeConfigurationUpdateMessage) ExtractConfigDeletionList() []entities.E2NodeComponentConfig { + var result []entities.E2NodeComponentConfig + e2nodeConfigUpdateIEs := m.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs + + var deletionList *E2nodeComponentConfigRemovalList + for _, v := range e2nodeConfigUpdateIEs { + if v.ID == ProtocolIE_ID_id_E2nodeComponentConfigRemoval { + deletionList = &(v.Value.E2nodeComponentConfigRemovalList) + break + } + } + + // need not to check for empty addtionList + // as list defined as SIZE(1..maxofE2nodeComponents) + if deletionList != nil { + for _, val := range deletionList.ProtocolIESingleContainer { + componentItem := val.Value.E2nodeComponentConfigRemovalItem + + if componentItem.E2nodeComponentInterfaceType.Ng != nil { // NG Interface + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_ng, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeNG{ + E2NodeComponentInterfaceTypeNG: &entities.E2NodeComponentInterfaceNG{ + AmfName: componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeNG.AmfName, + }, + }, + }) + } + + if componentItem.E2nodeComponentInterfaceType.Xn != nil { // xn inetrface + // TODO - Not Supported Yet + } + + if componentItem.E2nodeComponentInterfaceType.E1 != nil { // e1 interface + gnbCuCpId, err := strconv.ParseInt(componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeE1.GNBCUCPID, 10, 64) + if err != nil { + continue + } + + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_e1, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeE1{ + E2NodeComponentInterfaceTypeE1: &entities.E2NodeComponentInterfaceE1{ + GNBCuCpId: gnbCuCpId, + }, + }, + }) + } + + if componentItem.E2nodeComponentInterfaceType.F1 != nil { // f1 interface + gnbDuId, err := strconv.ParseInt(componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeF1.GNBDUID, 10, 64) + if err != nil { + continue + } + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_f1, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeF1{ + E2NodeComponentInterfaceTypeF1: &entities.E2NodeComponentInterfaceF1{ + GNBDuId: gnbDuId, + }, + }, + }) + } + + if componentItem.E2nodeComponentInterfaceType.W1 != nil { // w1 interface + ngenbDuId, err := strconv.ParseInt(componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeW1.NgENBDUID, 10, 64) + if err != nil { + continue + } + + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_w1, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeW1{ + E2NodeComponentInterfaceTypeW1: &entities.E2NodeComponentInterfaceW1{ + NgenbDuId: ngenbDuId, + }, + }, + }) + } + + if componentItem.E2nodeComponentInterfaceType.S1 != nil { // s1 interface + result = append(result, entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_s1, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeS1{ + E2NodeComponentInterfaceTypeS1: &entities.E2NodeComponentInterfaceS1{ + MmeName: componentItem.E2nodeComponentID.E2nodeComponentInterfaceTypeS1.MmeName, + }, + }, + }) + } + + if componentItem.E2nodeComponentInterfaceType.X2 != nil { // x2 interface + // TODO - Not Supported Yet + } + } + } + return result +} diff --git a/E2Manager/models/e2_node_configuration_update_ack.go b/E2Manager/models/e2_node_configuration_update_ack.go new file mode 100644 index 0000000..4c4a717 --- /dev/null +++ b/E2Manager/models/e2_node_configuration_update_ack.go @@ -0,0 +1,338 @@ +// +// 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 models + +import ( + "encoding/xml" + + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" +) + +type E2nodeConfigurationUpdateAcknowledgeE2APPDU struct { + XMLName xml.Name `xml:"E2AP-PDU"` + Text string `xml:",chardata"` + Outcome interface{} +} + +type E2nodeConfigurationUpdateAcknowledgeSuccessfulOutcome struct { + XMLName xml.Name `xml:"successfulOutcome"` + Text string `xml:",chardata"` + ProcedureCode string `xml:"procedureCode"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2nodeConfigurationUpdateAcknowledge struct { + Text string `xml:",chardata"` + ProtocolIEs struct { + Text string `xml:",chardata"` + E2nodeConfigurationUpdateAcknowledgeIEs []E2nodeConfigurationUpdateAcknowledgeIEs `xml:"E2nodeConfigurationUpdateAcknowledge-IEs"` + } `xml:"protocolIEs"` + } `xml:"E2nodeConfigurationUpdateAcknowledge"` + } `xml:"value"` +} + +type E2nodeConfigurationUpdateAcknowledgeIEs struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value interface{} `xml:"value"` +} + +type E2nodeConfigurationUpdateAcknowledgeTransID struct { + Text string `xml:",chardata"` + TransactionID string `xml:"TransactionID"` +} + +type E2nodeComponentConfigAdditionAckList struct { + Text string `xml:",chardata"` + E2nodeComponentConfigAdditionAckList struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []AdditionListProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + } `xml:"E2nodeComponentConfigAdditionAck-List"` +} + +type AdditionListProtocolIESingleContainer struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2nodeComponentConfigAdditionAckItem ComponentAckDetail `xml:"E2nodeComponentConfigAdditionAck-Item"` + } `xml:"value"` +} + +type E2nodeComponentConfigUpdateAckList struct { + Text string `xml:",chardata"` + E2nodeComponentConfigUpdateAckList struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []UpdateProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + } `xml:"E2nodeComponentConfigUpdateAck-List"` +} + +type UpdateProtocolIESingleContainer struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2nodeComponentConfigUpdateAckItem ComponentAckDetail `xml:"E2nodeComponentConfigUpdateAck-Item"` + } `xml:"value"` +} + +type E2nodeComponentConfigRemovalAckList struct { + Text string `xml:",chardata"` + E2nodeComponentConfigRemovalAckList struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []RemovalProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + } `xml:"E2nodeComponentConfigRemovalAck-List"` +} + +type RemovalProtocolIESingleContainer struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2nodeComponentConfigRemovalAckItem ComponentAckDetail `xml:"E2nodeComponentConfigRemovalAck-Item"` + } `xml:"value"` +} + +type ComponentAckDetail struct { + Text string `xml:",chardata"` + E2nodeComponentInterfaceType E2NodeComponentType `xml:"e2nodeComponentInterfaceType"` + E2nodeComponentID E2NodeComponentIDResp `xml:"e2nodeComponentID"` + E2nodeConfigUpdateAck E2nodeConfigUpdateAckResp +} + +func prepareAdditionAckList(e2nodeConfigs []entities.E2NodeComponentConfig) []AdditionListProtocolIESingleContainer { + additionListAckSingle := []AdditionListProtocolIESingleContainer{} + for _, v := range e2nodeConfigs { + c := convertEntitiyToModelComponent(v) + + t := AdditionListProtocolIESingleContainer{ + ID: ProtocolIE_ID_id_E2nodeComponentConfigAdditionAck_Item, + Value: struct { + Text string `xml:",chardata"` + E2nodeComponentConfigAdditionAckItem ComponentAckDetail `xml:"E2nodeComponentConfigAdditionAck-Item"` + }{ + E2nodeComponentConfigAdditionAckItem: *c, + }, + } + additionListAckSingle = append(additionListAckSingle, t) + } + return additionListAckSingle +} + +func prepareUpdateAckList(e2nodeConfigs []entities.E2NodeComponentConfig) []UpdateProtocolIESingleContainer { + updateListAckSingle := []UpdateProtocolIESingleContainer{} + for _, v := range e2nodeConfigs { + c := convertEntitiyToModelComponent(v) + + t := UpdateProtocolIESingleContainer{ + ID: ProtocolIE_ID_id_E2nodeComponentConfigUpdateAck_Item, + Value: struct { + Text string `xml:",chardata"` + E2nodeComponentConfigUpdateAckItem ComponentAckDetail `xml:"E2nodeComponentConfigUpdateAck-Item"` + }{ + E2nodeComponentConfigUpdateAckItem: *c, + }, + } + updateListAckSingle = append(updateListAckSingle, t) + } + return updateListAckSingle +} + +func prepareRemovalAckList(e2nodeConfigs []entities.E2NodeComponentConfig) []RemovalProtocolIESingleContainer { + removalListAckSingle := []RemovalProtocolIESingleContainer{} + for _, v := range e2nodeConfigs { + c := convertEntitiyToModelComponent(v) + + t := RemovalProtocolIESingleContainer{ + ID: ProtocolIE_ID_id_E2nodeComponentConfigRemovalAck_Item, + Value: struct { + Text string `xml:",chardata"` + E2nodeComponentConfigRemovalAckItem ComponentAckDetail `xml:"E2nodeComponentConfigRemovalAck-Item"` + }{ + E2nodeComponentConfigRemovalAckItem: *c, + }, + } + removalListAckSingle = append(removalListAckSingle, t) + } + return removalListAckSingle +} + +func updateIDAndStatus(t *ComponentAckDetail, c entities.E2NodeComponentConfig, succss bool) { + switch c.E2NodeComponentInterfaceType { + case entities.E2NodeComponentInterfaceType_ng: + t.E2nodeComponentID.Value = E2NodeIFTypeNG{ + AMFName: c.GetE2NodeComponentInterfaceTypeNG().AmfName, + } + case entities.E2NodeComponentInterfaceType_e1: + t.E2nodeComponentID.Value = E2NodeIFTypeE1{ + GNBCUCPID: c.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId(), + } + case entities.E2NodeComponentInterfaceType_s1: + t.E2nodeComponentID.Value = E2NodeIFTypeS1{ + MMENAME: c.GetE2NodeComponentInterfaceTypeS1().GetMmeName(), + } + case entities.E2NodeComponentInterfaceType_f1: + t.E2nodeComponentID.Value = E2NodeIFTypeF1{ + GNBDUID: c.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId(), + } + case entities.E2NodeComponentInterfaceType_w1: + t.E2nodeComponentID.Value = E2NodeIFTypeW1{ + NGENBDUID: c.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId(), + } + } + + if succss { + t.E2nodeConfigUpdateAck = E2nodeConfigUpdateAckResp{ + Value: struct { + XMLName xml.Name `xml:"updateOutcome"` + Text string `xml:",chardata"` + Success string `xml:"success"` + }{}, + } + } else { + t.E2nodeConfigUpdateAck = E2nodeConfigUpdateAckResp{ + Value: struct { + XMLName xml.Name `xml:"updateOutcome"` + Text string `xml:",chardata"` + Success string `xml:"failure"` + }{}, + } + } +} + +func updateInterfaceType(t *ComponentAckDetail, c entities.E2NodeComponentConfig) { + switch c.E2NodeComponentInterfaceType { + case entities.E2NodeComponentInterfaceType_ng: + t.E2nodeComponentInterfaceType = E2NodeComponentType{ + NG: &struct{}{}, + } + case entities.E2NodeComponentInterfaceType_e1: + t.E2nodeComponentInterfaceType = E2NodeComponentType{ + E1: &struct{}{}, + } + case entities.E2NodeComponentInterfaceType_f1: + t.E2nodeComponentInterfaceType = E2NodeComponentType{ + F1: &struct{}{}, + } + case entities.E2NodeComponentInterfaceType_w1: + t.E2nodeComponentInterfaceType = E2NodeComponentType{ + W1: &struct{}{}, + } + case entities.E2NodeComponentInterfaceType_s1: + t.E2nodeComponentInterfaceType = E2NodeComponentType{ + S1: &struct{}{}, + } + } +} + +func convertEntitiyToModelComponent(component entities.E2NodeComponentConfig) *ComponentAckDetail { + componentAckDetail := &ComponentAckDetail{} + updateInterfaceType(componentAckDetail, component) + updateIDAndStatus(componentAckDetail, component, true) + return componentAckDetail +} + +func NewE2nodeConfigurationUpdateSuccessResponseMessage(e2nodeConfigupdateMessage *E2nodeConfigurationUpdateMessage) *E2nodeConfigurationUpdateAcknowledgeE2APPDU { + successfulOutcome := E2nodeConfigurationUpdateAcknowledgeSuccessfulOutcome{ + ProcedureCode: ProcedureCode_id_E2nodeConfigurationUpdate, + } + + e2nodeConfigurationUpdateAckIEs := []E2nodeConfigurationUpdateAcknowledgeIEs{} + txIEs := E2nodeConfigurationUpdateAcknowledgeIEs{ + ID: ProtocolIE_ID_id_TransactionID, + Value: E2nodeConfigurationUpdateAcknowledgeTransID{ + TransactionID: e2nodeConfigupdateMessage.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs[0].Value.TransactionID, + }, + } + + e2nodeConfigurationUpdateAckIEs = append(e2nodeConfigurationUpdateAckIEs, txIEs) + + items := e2nodeConfigupdateMessage.ExtractConfigAdditionList() + if len(items) > 0 { + addtionListAckIEs := E2nodeConfigurationUpdateAcknowledgeIEs{ + ID: ProtocolIE_ID_id_E2nodeComponentConfigAdditionAck, + Value: E2nodeComponentConfigAdditionAckList{ + E2nodeComponentConfigAdditionAckList: struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []AdditionListProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + }{ + ProtocolIESingleContainer: prepareAdditionAckList(items), + }, + }, + } + e2nodeConfigurationUpdateAckIEs = append(e2nodeConfigurationUpdateAckIEs, addtionListAckIEs) + } + + items = e2nodeConfigupdateMessage.ExtractConfigUpdateList() + if len(items) > 0 { + updateListAckIEs := E2nodeConfigurationUpdateAcknowledgeIEs{ + ID: ProtocolIE_ID_id_E2nodeComponentConfigUpdateAck, + Value: E2nodeComponentConfigUpdateAckList{ + E2nodeComponentConfigUpdateAckList: struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []UpdateProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + }{ + ProtocolIESingleContainer: prepareUpdateAckList(items), + }, + }, + } + e2nodeConfigurationUpdateAckIEs = append(e2nodeConfigurationUpdateAckIEs, updateListAckIEs) + } + + items = e2nodeConfigupdateMessage.ExtractConfigDeletionList() + if len(items) > 0 { + removalListAckIEs := E2nodeConfigurationUpdateAcknowledgeIEs{ + ID: ProtocolIE_ID_id_E2nodeComponentConfigRemovalAck, + Value: E2nodeComponentConfigRemovalAckList{ + E2nodeComponentConfigRemovalAckList: struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []RemovalProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + }{ + ProtocolIESingleContainer: prepareRemovalAckList(items), + }, + }, + } + e2nodeConfigurationUpdateAckIEs = append(e2nodeConfigurationUpdateAckIEs, removalListAckIEs) + } + + successfulOutcome.Value.E2nodeConfigurationUpdateAcknowledge.ProtocolIEs.E2nodeConfigurationUpdateAcknowledgeIEs = e2nodeConfigurationUpdateAckIEs + response := &E2nodeConfigurationUpdateAcknowledgeE2APPDU{ + Outcome: successfulOutcome, + } + return response +} diff --git a/E2Manager/models/e2_node_configuration_update_ack_test.go b/E2Manager/models/e2_node_configuration_update_ack_test.go new file mode 100644 index 0000000..0356178 --- /dev/null +++ b/E2Manager/models/e2_node_configuration_update_ack_test.go @@ -0,0 +1,68 @@ +// +// 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 models_test + +import ( + "e2mgr/models" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewE2nodeConfigurationUpdateSuccessResponseMessage(t *testing.T) { + configurationUpdate := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateXmlPath) + ack := models.NewE2nodeConfigurationUpdateSuccessResponseMessage(configurationUpdate) + successOutcome := ack.Outcome.(models.E2nodeConfigurationUpdateAcknowledgeSuccessfulOutcome) + + assert.Equal(t, models.ProcedureCode_id_E2nodeConfigurationUpdate, successOutcome.ProcedureCode) + assert.Equal(t, 4, len(successOutcome.Value.E2nodeConfigurationUpdateAcknowledge.ProtocolIEs.E2nodeConfigurationUpdateAcknowledgeIEs)) + + txIE := successOutcome.Value.E2nodeConfigurationUpdateAcknowledge.ProtocolIEs.E2nodeConfigurationUpdateAcknowledgeIEs[0] + assert.Equal(t, models.ProtocolIE_ID_id_TransactionID, txIE.ID) + assert.Equal(t, "1234", txIE.Value.(models.E2nodeConfigurationUpdateAcknowledgeTransID).TransactionID) + + additionIE := successOutcome.Value.E2nodeConfigurationUpdateAcknowledge.ProtocolIEs.E2nodeConfigurationUpdateAcknowledgeIEs[1] + assert.Equal(t, models.ProtocolIE_ID_id_E2nodeComponentConfigAdditionAck, additionIE.ID) + assert.Equal(t, 5, len(additionIE.Value.(models.E2nodeComponentConfigAdditionAckList).E2nodeComponentConfigAdditionAckList.ProtocolIESingleContainer)) + + updateIE := successOutcome.Value.E2nodeConfigurationUpdateAcknowledge.ProtocolIEs.E2nodeConfigurationUpdateAcknowledgeIEs[2] + assert.Equal(t, models.ProtocolIE_ID_id_E2nodeComponentConfigUpdateAck, updateIE.ID) + assert.Equal(t, 5, len(updateIE.Value.(models.E2nodeComponentConfigUpdateAckList).E2nodeComponentConfigUpdateAckList.ProtocolIESingleContainer)) + + removalIE := successOutcome.Value.E2nodeConfigurationUpdateAcknowledge.ProtocolIEs.E2nodeConfigurationUpdateAcknowledgeIEs[3] + assert.Equal(t, models.ProtocolIE_ID_id_E2nodeComponentConfigRemovalAck, removalIE.ID) + assert.Equal(t, 5, len(removalIE.Value.(models.E2nodeComponentConfigRemovalAckList).E2nodeComponentConfigRemovalAckList.ProtocolIESingleContainer)) +} + +func TestNewE2nodeConfigurationUpdateSuccessResponseMessageAdditionOnly(t *testing.T) { + configurationUpdate := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateOnlyAdditionXmlPath) + ack := models.NewE2nodeConfigurationUpdateSuccessResponseMessage(configurationUpdate) + successOutcome := ack.Outcome.(models.E2nodeConfigurationUpdateAcknowledgeSuccessfulOutcome) + + assert.Equal(t, models.ProcedureCode_id_E2nodeConfigurationUpdate, successOutcome.ProcedureCode) + assert.Equal(t, 2, len(successOutcome.Value.E2nodeConfigurationUpdateAcknowledge.ProtocolIEs.E2nodeConfigurationUpdateAcknowledgeIEs)) + + txIE := successOutcome.Value.E2nodeConfigurationUpdateAcknowledge.ProtocolIEs.E2nodeConfigurationUpdateAcknowledgeIEs[0] + assert.Equal(t, models.ProtocolIE_ID_id_TransactionID, txIE.ID) + assert.Equal(t, "1234", txIE.Value.(models.E2nodeConfigurationUpdateAcknowledgeTransID).TransactionID) + + additionIE := successOutcome.Value.E2nodeConfigurationUpdateAcknowledge.ProtocolIEs.E2nodeConfigurationUpdateAcknowledgeIEs[1] + assert.Equal(t, models.ProtocolIE_ID_id_E2nodeComponentConfigAdditionAck, additionIE.ID) + assert.Equal(t, 1, len(additionIE.Value.(models.E2nodeComponentConfigAdditionAckList).E2nodeComponentConfigAdditionAckList.ProtocolIESingleContainer)) +} diff --git a/E2Manager/models/e2_node_configuration_update_test.go b/E2Manager/models/e2_node_configuration_update_test.go new file mode 100644 index 0000000..8323999 --- /dev/null +++ b/E2Manager/models/e2_node_configuration_update_test.go @@ -0,0 +1,119 @@ +// +// Copyright 2022 Samsung Electronics Co. +// +// 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 models_test + +import ( + "e2mgr/models" + "e2mgr/utils" + "encoding/xml" + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + e2NodeConfigurationUpdateOnlyAdditionXmlPath = "../tests/resources/configurationUpdate/e2NodeConfigurationUpdateOnlyAddition.xml" + e2NodeConfigurationUpdateXmlPath = "../tests/resources/configurationUpdate/e2NodeConfigurationUpdate.xml" +) + +func getTestE2NodeConfigurationUpdateMessage(t *testing.T, reqXmlPath string) *models.E2nodeConfigurationUpdateMessage { + xmlConfUpdate := utils.ReadXmlFile(t, reqXmlPath) + confUpdateMsg := &models.E2nodeConfigurationUpdateMessage{} + err := xml.Unmarshal(utils.NormalizeXml(xmlConfUpdate), &confUpdateMsg.E2APPDU) + assert.Nil(t, err) + return confUpdateMsg +} + +func TestParseE2NodeConfigurationUpdateSuccessAdditionOnly(t *testing.T) { + configurationUpdate := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateOnlyAdditionXmlPath) + assert.NotEqual(t, nil, configurationUpdate, "xml is not parsed correctly") + assert.Equal(t, models.ProcedureCode_id_E2nodeConfigurationUpdate, configurationUpdate.E2APPDU.InitiatingMessage.ProcedureCode) + assert.Equal(t, 2, len(configurationUpdate.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs)) + + additionIE := configurationUpdate.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs[1] + assert.Equal(t, 1, len(additionIE.Value.E2nodeComponentConfigAdditionList.ProtocolIESingleContainer)) + assert.Equal(t, false, additionIE.Value.E2nodeComponentConfigAdditionList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigAdditionItem.E2nodeComponentInterfaceType.Ng == nil) + assert.Equal(t, true, additionIE.Value.E2nodeComponentConfigAdditionList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigAdditionItem.E2nodeComponentInterfaceType.E1 == nil) + assert.Equal(t, true, additionIE.Value.E2nodeComponentConfigAdditionList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigAdditionItem.E2nodeComponentInterfaceType.E1 == nil) +} + +func TestParseE2NodeConfigurationUpdateSuccess(t *testing.T) { + configurationUpdate := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateXmlPath) + assert.NotEqual(t, nil, configurationUpdate, "xml is not parsed correctly") + assert.Equal(t, models.ProcedureCode_id_E2nodeConfigurationUpdate, configurationUpdate.E2APPDU.InitiatingMessage.ProcedureCode) + assert.Equal(t, 4, len(configurationUpdate.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs)) + + additionIE := configurationUpdate.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs[1] + assert.Equal(t, 7, len(additionIE.Value.E2nodeComponentConfigAdditionList.ProtocolIESingleContainer)) + assert.Equal(t, false, additionIE.Value.E2nodeComponentConfigAdditionList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigAdditionItem.E2nodeComponentInterfaceType.Ng == nil) + assert.Equal(t, true, additionIE.Value.E2nodeComponentConfigAdditionList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigAdditionItem.E2nodeComponentInterfaceType.E1 == nil) + + updateIE := configurationUpdate.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs[2] + assert.Equal(t, 7, len(updateIE.Value.E2nodeComponentConfigUpdateList.ProtocolIESingleContainer)) + assert.Equal(t, false, updateIE.Value.E2nodeComponentConfigUpdateList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigUpdateItem.E2nodeComponentInterfaceType.Ng == nil) + assert.Equal(t, true, updateIE.Value.E2nodeComponentConfigUpdateList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigUpdateItem.E2nodeComponentInterfaceType.E1 == nil) + assert.Equal(t, true, updateIE.Value.E2nodeComponentConfigUpdateList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigUpdateItem.E2nodeComponentInterfaceType.E1 == nil) + + removalIE := configurationUpdate.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs[3] + assert.Equal(t, 7, len(removalIE.Value.E2nodeComponentConfigRemovalList.ProtocolIESingleContainer)) + assert.Equal(t, false, removalIE.Value.E2nodeComponentConfigRemovalList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigRemovalItem.E2nodeComponentInterfaceType.Ng == nil) + assert.Equal(t, true, removalIE.Value.E2nodeComponentConfigRemovalList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigRemovalItem.E2nodeComponentInterfaceType.E1 == nil) + assert.Equal(t, true, removalIE.Value.E2nodeComponentConfigRemovalList.ProtocolIESingleContainer[0].Value.E2nodeComponentConfigRemovalItem.E2nodeComponentInterfaceType.E1 == nil) +} + +func TestExtractAdditionConfigList(t *testing.T) { + configurationUpdate1 := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateXmlPath) + additionList := configurationUpdate1.ExtractConfigAdditionList() + + assert.Equal(t, 5, len(additionList), "Addtion List is not matching") + + configurationUpdate2 := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateOnlyAdditionXmlPath) + additionList2 := configurationUpdate2.ExtractConfigAdditionList() + + assert.Equal(t, 1, len(additionList2), "Addtion List is not matching") +} + +func TestExtractUpdateConfigList(t *testing.T) { + configurationUpdate1 := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateXmlPath) + updateList1 := configurationUpdate1.ExtractConfigUpdateList() + + assert.Equal(t, 5, len(updateList1), "Update List is not matching") + + configurationUpdate2 := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateOnlyAdditionXmlPath) + updateList2 := configurationUpdate2.ExtractConfigUpdateList() + + assert.Equal(t, 0, len(updateList2), "Update List is not matching") +} + +func TestExtractDeleteConfigList(t *testing.T) { + configurationRemoval1 := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateXmlPath) + removalList1 := configurationRemoval1.ExtractConfigDeletionList() + + assert.Equal(t, 5, len(removalList1), "Removal List is not matching") + + configurationRemoval2 := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateOnlyAdditionXmlPath) + removalList2 := configurationRemoval2.ExtractConfigDeletionList() + + assert.Equal(t, 0, len(removalList2), "Removal List is not matching") +} + +func TestGetTxID(t *testing.T) { + configuration1 := getTestE2NodeConfigurationUpdateMessage(t, e2NodeConfigurationUpdateXmlPath) + assert.Equal(t, "1234", configuration1.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs[0].Value.TransactionID) +} diff --git a/E2Manager/models/e2_setup_request_message.go b/E2Manager/models/e2_setup_request_message.go index 96a7bcf..435ad7c 100644 --- a/E2Manager/models/e2_setup_request_message.go +++ b/E2Manager/models/e2_setup_request_message.go @@ -1,6 +1,7 @@ // // Copyright 2019 AT&T Intellectual Property // Copyright 2019 Nokia +// 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. @@ -104,8 +105,10 @@ type E2SetupRequest struct { } `xml:"criticality"` Value struct { Text string `xml:",chardata"` + TransactionID string `xml:"TransactionID"` GlobalE2nodeID GlobalE2NodeId `xml:"GlobalE2node-ID"` RANfunctionsList RANfunctionsList `xml:"RANfunctions-List"` + E2NodeConfigList E2NodeConfigList `xml:"E2nodeComponentConfigAddition-List"` } `xml:"value"` } `xml:"E2setupRequestIEs"` } `xml:"protocolIEs"` @@ -155,14 +158,157 @@ type RANfunctionsList struct { } `xml:"ProtocolIE-SingleContainer"` } +type E2NodeConfigList struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2nodeConfigAdditionItem E2NodeConfigAdditionItem `xml:"E2nodeComponentConfigAddition-Item"` + } `xml:"value"` + } `xml:"ProtocolIE-SingleContainer"` +} + +type E2NodeComponentType struct { + Text string `xml:",chardata"` + NG *struct{} `xml:"ng"` + XN *struct{} `xml:"xn"` + E1 *struct{} `xml:"e1"` + F1 *struct{} `xml:"f1"` + W1 *struct{} `xml:"w1"` + S1 *struct{} `xml:"s1"` + X2 *struct{} `xml:"x2"` +} + +type E2NodeConfigAdditionItem struct { + Text string `xml:",chardata"` + E2nodeComponentType E2NodeComponentType `xml:"e2nodeComponentInterfaceType"` + E2nodeComponentID E2NodeComponentId `xml:"e2nodeComponentID"` + E2nodeConfiguration E2NodeConfigValue `xml:"e2nodeComponentConfiguration"` +} + +type E2NodeConfigValue struct { + Text string `xml:",chardata"` + E2NodeRequestPart []byte `xml:"e2nodeComponentRequestPart"` + E2NodeResponsePart []byte `xml:"e2nodeComponentResponsePart"` +} + +type E2NodeComponentId struct { + Text string `xml:",chardata"` + E2NodeIFTypeNG E2NodeIFTypeNG + E2NodeIFTypeXN E2NodeIFTypeXN + E2NodeIFTypeE1 E2NodeIFTypeE1 + E2NodeIFTypeF1 E2NodeIFTypeF1 + E2NodeIFTypeW1 E2NodeIFTypeW1 + E2NodeIFTypeS1 E2NodeIFTypeS1 + E2NodeIFTypeX2 E2NodeIFTypeX2 +} + +type E2NodeIFTypeNG struct { + XMLName xml.Name `xml:"e2nodeComponentInterfaceTypeNG"` + Text string `xml:",chardata"` + AMFName string `xml:"amf-name"` +} + +type E2NodeIFTypeXN struct { + XMLName xml.Name `xml:"e2nodeComponentInterfaceTypeXn"` + Text string `xml:",chardata"` + GlobalNgENBID struct { + Text string `xml:",chardata"` + GNB struct { + Text string `xml:",chardata"` + PLMNID string `xml:"plmn-id"` + GnbID struct { + Text string `xml:",chardata"` + GnbID string `xml:"gnb-ID"` + } `xml:"gnb-id"` + } `xml:"gNB"` + NGENB struct { + Text string `xml:",chardata"` + PLMNID string `xml:"plmn-id"` + GnbID struct { + Text string `xml:",chardata"` + ENBIDMacro string `xml:"enb-ID-macro"` + ENBIDShortMacro string `xml:"enb-ID-shortmacro"` + ENBIDLongMacro string `xml:"enb-ID-longmacro"` + } `xml:"gnb-id"` + } `xml:"ng-eNB"` + } `xml:"global-NG-RAN-Node-ID"` +} + +type E2NodeIFTypeE1 struct { + XMLName xml.Name `xml:"e2nodeComponentInterfaceTypeE1"` + Text string `xml:",chardata"` + GNBCUCPID int64 `xml:"gNB-CU-CP-ID"` +} + +type E2NodeIFTypeF1 struct { + XMLName xml.Name `xml:"e2nodeComponentInterfaceTypeF1"` + Text string `xml:",chardata"` + GNBDUID int64 `xml:"gNB-DU-ID"` +} + +type E2NodeIFTypeW1 struct { + XMLName xml.Name `xml:"e2nodeComponentInterfaceTypeW1"` + Text string `xml:",chardata"` + NGENBDUID int64 `xml:"ng-eNB-DU-ID"` +} + +type E2NodeIFTypeS1 struct { + XMLName xml.Name `xml:"e2nodeComponentInterfaceTypeS1"` + Text string `xml:",chardata"` + MMENAME string `xml:"mme-name"` +} + +type E2NodeIFTypeX2 struct { + XMLName xml.Name `xml:"e2nodeComponentInterfaceTypeX2"` + Text string `xml:",chardata"` + GlobalENBID struct { + Text string `xml:",chardata"` + PLMNIdentity string `xml:"pLMN-Identity"` + ENBID struct { + Text string `xml:",chardata"` + MacroENBID string `xml:"macro-eNB-ID"` + HomeENBID string `xml:"home-eNB-ID"` + ShortMacroENBID string `xml:"short-Macro-eNB-ID"` + LongMacroENBID string `xml:"long-Macro-eNB-ID"` + } `xml:"eNB-ID"` + } `xml:"global-eNB-ID"` + GlobalEnGNBID struct { + Text string `xml:",chardata"` + PLMNIdentity string `xml:"pLMN-Identity"` + GNBID struct { + Text string `xml:",chardata"` + GNBID string `xml:"gNB-ID"` + } `xml:"gNB-ID"` + } `xml:"global-en-gNB-ID"` +} + func (m *E2SetupRequestMessage) ExtractRanFunctionsList() []*entities.RanFunction { // TODO: verify e2SetupRequestIEs structure with Adi e2SetupRequestIes := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs - if len(e2SetupRequestIes) < 2 { + + var ranFuntionsList RANfunctionsList + var isPopulated bool + + for _, v := range e2SetupRequestIes { + if v.ID == RanFunctionsAddedID { + ranFuntionsList = v.Value.RANfunctionsList + isPopulated = true + break + } + } + + if !isPopulated { return nil } - ranFunctionsListContainer := e2SetupRequestIes[1].Value.RANfunctionsList.ProtocolIESingleContainer + ranFunctionsListContainer := ranFuntionsList.ProtocolIESingleContainer funcs := make([]*entities.RanFunction, len(ranFunctionsListContainer)) for i := 0; i < len(funcs); i++ { ranFunctionItem := ranFunctionsListContainer[i].Value.RANfunctionItem @@ -177,8 +323,143 @@ func (m *E2SetupRequestMessage) ExtractRanFunctionsList() []*entities.RanFunctio return funcs } +func (m *E2SetupRequestMessage) ExtractE2NodeConfigList() []*entities.E2NodeComponentConfig { + e2SetupRequestIes := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs + numOfIes := len(e2SetupRequestIes) + var e2NodeConfigListContainer E2NodeConfigList + var isPopulated bool + + for ieCount := 0; ieCount < numOfIes; ieCount++ { + + if e2SetupRequestIes[ieCount].ID == E2nodeConfigAdditionID { + e2NodeConfigListContainer = e2SetupRequestIes[ieCount].Value.E2NodeConfigList + isPopulated = true + break + } + } + + if !isPopulated { + return nil + } + + e2nodeComponentConfigs := make([]*entities.E2NodeComponentConfig, len(e2NodeConfigListContainer.ProtocolIESingleContainer)) + for i := 0; i < len(e2nodeComponentConfigs); i++ { + e2NodeConfigItem := e2NodeConfigListContainer.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem + + if e2NodeConfigItem.E2nodeComponentType.NG != nil { + e2nodeComponentConfigs[i] = &entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_ng, + E2NodeComponentRequestPart: e2NodeConfigItem.E2nodeConfiguration.E2NodeRequestPart, + E2NodeComponentResponsePart: e2NodeConfigItem.E2nodeConfiguration.E2NodeResponsePart, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeNG{ + E2NodeComponentInterfaceTypeNG: &entities.E2NodeComponentInterfaceNG{ + AmfName: e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeNG.AMFName, + }, + }, + } + } else if e2NodeConfigItem.E2nodeComponentType.E1 != nil { + e2nodeComponentConfigs[i] = &entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_e1, + E2NodeComponentRequestPart: e2NodeConfigItem.E2nodeConfiguration.E2NodeRequestPart, + E2NodeComponentResponsePart: e2NodeConfigItem.E2nodeConfiguration.E2NodeResponsePart, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeE1{ + E2NodeComponentInterfaceTypeE1: &entities.E2NodeComponentInterfaceE1{ + GNBCuCpId: e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeE1.GNBCUCPID, + }, + }, + } + } else if e2NodeConfigItem.E2nodeComponentType.F1 != nil { + e2nodeComponentConfigs[i] = &entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_f1, + E2NodeComponentRequestPart: e2NodeConfigItem.E2nodeConfiguration.E2NodeRequestPart, + E2NodeComponentResponsePart: e2NodeConfigItem.E2nodeConfiguration.E2NodeResponsePart, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeF1{ + E2NodeComponentInterfaceTypeF1: &entities.E2NodeComponentInterfaceF1{ + GNBDuId: e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeF1.GNBDUID, + }, + }, + } + } else if e2NodeConfigItem.E2nodeComponentType.W1 != nil { + e2nodeComponentConfigs[i] = &entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_w1, + E2NodeComponentRequestPart: e2NodeConfigItem.E2nodeConfiguration.E2NodeRequestPart, + E2NodeComponentResponsePart: e2NodeConfigItem.E2nodeConfiguration.E2NodeResponsePart, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeW1{ + E2NodeComponentInterfaceTypeW1: &entities.E2NodeComponentInterfaceW1{ + NgenbDuId: e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeW1.NGENBDUID, + }, + }, + } + } else if e2NodeConfigItem.E2nodeComponentType.S1 != nil { + e2nodeComponentConfigs[i] = &entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_s1, + E2NodeComponentRequestPart: e2NodeConfigItem.E2nodeConfiguration.E2NodeRequestPart, + E2NodeComponentResponsePart: e2NodeConfigItem.E2nodeConfiguration.E2NodeResponsePart, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeS1{ + E2NodeComponentInterfaceTypeS1: &entities.E2NodeComponentInterfaceS1{ + MmeName: e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeS1.MMENAME, + }, + }, + } + } + /*else if e2NodeConfigItem.E2nodeComponentType.XN != nil { + funcs[i] = &entities.E2NodeComponentConfig{ + E2NodeComponentInterfaceType: entities.E2NodeComponentInterfaceType_xn, + E2NodeComponentRequestPart: e2NodeConfigItem.E2nodeConfiguration.E2NodeRequestPart, + E2NodeComponentResponsePart: e2NodeConfigItem.E2nodeConfiguration.E2NodeResponsePart, + E2NodeComponentID: &entities.E2NodeComponentConfig_E2NodeComponentInterfaceTypeNG{ + E2NodeComponentInterfaceTypeXn: &entities.E2NodeComponentInterfaceXn{ + GlobalNgRanNodeId: &entities.E2NodeComponentInterfaceXn_GlobalNgenbId{ + GlobalNgenbId:&entities.GlobalNGENBID{ + PlmnIdentity: e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.PLMNID, + EnbId: e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.GNB.GnbID.GnbID, + }, + }, + GlobalNgRanNodeId: &entities.E2NodeComponentInterfaceXn_GlobalGnbId{ + GlobalGnbId:&entities.GlobalGNBID{ + PlmnIdentity: e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.PLMNID, + EnbId: e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.GNB.GnbID.GnbID, + }, + }, + }, + }, + } + ifXn.GlobalNgENBID.NGENB.PLMNID = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.PLMNID + ifXn.GlobalNgENBID.NGENB.GnbID.ENBIDMacro = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.GnbID.ENBIDMacro + ifXn.GlobalNgENBID.NGENB.GnbID.ENBIDShortMacro = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.GnbID.ENBIDShortMacro + ifXn.GlobalNgENBID.NGENB.GnbID.ENBIDLongMacro = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.GnbID.ENBIDLongMacro + + }*/ + /*else if e2NodeConfigItem.E2nodeComponentType.X2 != nil { + ifX2 := E2NodeIFTypeX2 {} + ifX2.GlobalENBID.PLMNIdentity = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.PLMNIdentity + ifX2.GlobalENBID.ENBID.MacroENBID = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.MacroENBID + ifX2.GlobalENBID.ENBID.HomeENBID = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.HomeENBID + ifX2.GlobalENBID.ENBID.ShortMacroENBID = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.ShortMacroENBID + ifX2.GlobalENBID.ENBID.LongMacroENBID = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.LongMacroENBID + + ifX2.GlobalEnGNBID.PLMNIdentity = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalEnGNBID.PLMNIdentity + ifX2.GlobalEnGNBID.GNBID.GNBID = e2NodeConfigItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalEnGNBID.GNBID.GNBID + }*/ + } + return e2nodeComponentConfigs +} + func (m *E2SetupRequestMessage) getGlobalE2NodeId() GlobalE2NodeId { - return m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID + + // TODO: Handle error case if GlobalE2NodeId not available + e2SetupRequestIes := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs + numOfIes := len(e2SetupRequestIes) + index := 1 + + for ieCount := 0; ieCount < numOfIes; ieCount++ { + if e2SetupRequestIes[ieCount].ID == GlobalE2nodeID { + index = ieCount + break + } + } + + return m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[index].Value.GlobalE2nodeID } func (m *E2SetupRequestMessage) GetPlmnId() string { diff --git a/E2Manager/models/e2_setup_request_message_test.go b/E2Manager/models/e2_setup_request_message_test.go index a609eed..b50d0d7 100644 --- a/E2Manager/models/e2_setup_request_message_test.go +++ b/E2Manager/models/e2_setup_request_message_test.go @@ -23,8 +23,9 @@ import ( "e2mgr/models" "e2mgr/utils" "encoding/xml" - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) const ( @@ -73,6 +74,17 @@ func TestExtractRanFunctionsListFromGnbRequestwithOidSuccess(t *testing.T) { assert.Equal(t, "OID125", ranFuncList[2].RanFunctionOid) } +func TestExtractE2nodeConfigSuccess(t *testing.T) { + setupRequest := getTestE2SetupRequest(t, e2SetupReqGnbSetupRequestWithOIDXmlPath) + e2nodeConfigs := setupRequest.ExtractE2NodeConfigList() + + assert.Equal(t, 2, len(e2nodeConfigs)) + + assert.Equal(t, "nginterf1", e2nodeConfigs[0].GetE2NodeComponentInterfaceTypeNG().GetAmfName()) + assert.Equal(t, "nginterf2", e2nodeConfigs[1].GetE2NodeComponentInterfaceTypeNG().GetAmfName()) + +} + func TestGetPlmnIdFromGnbRequestSuccess(t *testing.T) { setupRequest := getTestE2SetupRequest(t, e2SetupReqGnbSetupRequestXmlPath) diff --git a/E2Manager/models/e2_setup_response_message.go b/E2Manager/models/e2_setup_response_message.go index 04d63a1..1b62b01 100644 --- a/E2Manager/models/e2_setup_response_message.go +++ b/E2Manager/models/e2_setup_response_message.go @@ -1,6 +1,7 @@ // // Copyright 2019 AT&T Intellectual Property // Copyright 2019 Nokia +// 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. @@ -23,6 +24,21 @@ import ( "encoding/xml" ) +const ( + CauseID = "1" + GlobalE2nodeID = "3" + GlobalRicID = "4" + RanFunctionIDItemID = "6" + RanFunctionsAcceptedID = "9" + RanFunctionsAddedID = "10" + TimeToWaitID = "31" + TransactionID = "49" + E2nodeConfigAdditionID = "50" + E2nodeConfigAdditionItemID = "51" + E2nodeConfigAdditionAckID = "52" + E2nodeConfigAdditionAckItemID = "53" +) + type TimeToWait = int var TimeToWaitEnum = struct { @@ -67,41 +83,87 @@ var timeToWaitMap = map[TimeToWait]interface{}{ }{}, } +type ConfigStatus = int + +var ConfigStatusEnum = struct { + Success ConfigStatus + Failure ConfigStatus +}{0, 1} + +var configStatusMap = map[ConfigStatus]interface{}{ + ConfigStatusEnum.Success: struct { + XMLName xml.Name `xml:"updateOutcome"` + Text string `xml:",chardata"` + Success string `xml:"success"` + }{}, + ConfigStatusEnum.Failure: struct { + XMLName xml.Name `xml:"updateOutcome"` + Text string `xml:",chardata"` + Failure string `xml:"failure"` + }{}, +} + func NewE2SetupSuccessResponseMessage(plmnId string, ricId string, request *E2SetupRequestMessage) E2SetupResponseMessage { outcome := SuccessfulOutcome{} outcome.ProcedureCode = "1" e2SetupRequestIes := request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs + numOfIes := len(e2SetupRequestIes) - outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs = make([]E2setupResponseIEs, len(e2SetupRequestIes)) - outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[0].ID = "4" - outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[0].Value = GlobalRICID{GlobalRICID: struct { - Text string `xml:",chardata"` - PLMNIdentity string `xml:"pLMN-Identity"` - RicID string `xml:"ric-ID"` - }{PLMNIdentity: plmnId, RicID: ricId}} + outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs = make([]E2setupResponseIEs, numOfIes) + + for ieCount := 0; ieCount < numOfIes; ieCount++ { + switch e2SetupRequestIes[ieCount].ID { + case TransactionID: + outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = TransactionID + outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = TransID{ + TransactionID: request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[ieCount].Value.TransactionID, + } + + case GlobalE2nodeID: + outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = GlobalRicID + outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = GlobalRICID{GlobalRICID: struct { + Text string `xml:",chardata"` + PLMNIdentity string `xml:"pLMN-Identity"` + RicID string `xml:"ric-ID"` + }{PLMNIdentity: plmnId, RicID: ricId}} + + case RanFunctionsAddedID: + outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = RanFunctionsAcceptedID + outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = RANfunctionsIDList{RANfunctionsIDList: struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []ProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + }{ProtocolIESingleContainer: extractRanFunctionsIDList(request, ieCount)}} - if len(e2SetupRequestIes) < 2 { - return E2SetupResponseMessage{E2APPDU: E2APPDU{Outcome: outcome}} + case E2nodeConfigAdditionID: + outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = E2nodeConfigAdditionAckID + outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = E2NodeConfigUpdateAckList{E2NodeConfigUpdateAckList: struct { + Text string `xml:",chardata"` + E2NodeConfigSingleContainer []E2NodeConfigSingleContainer `xml:"ProtocolIE-SingleContainer"` + }{E2NodeConfigSingleContainer: extractE2NodeConfigUpdateList(request, ieCount, 0)}} + } } - outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[1].ID = "9" - outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[1].Value = RANfunctionsIDList{RANfunctionsIDList: struct { - Text string `xml:",chardata"` - ProtocolIESingleContainer []ProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` - }{ProtocolIESingleContainer: extractRanFunctionsIDList(request)}} return E2SetupResponseMessage{E2APPDU: E2APPDU{Outcome: outcome}} } -func NewE2SetupFailureResponseMessage(timeToWait TimeToWait, cause Cause) E2SetupResponseMessage { +func NewE2SetupFailureResponseMessage(timeToWait TimeToWait, cause Cause, request *E2SetupRequestMessage) E2SetupResponseMessage { outcome := UnsuccessfulOutcome{} - outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs = make([]E2setupFailureIEs, 2) + + outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs = make([]E2setupFailureIEs, 3) outcome.ProcedureCode = "1" - outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[0].ID = "1" - outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[0].Value.Value = cause - outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].ID = "31" - outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].Value.Value = timeToWaitMap[timeToWait] + outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[0].ID = TransactionID + outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[0].Value.Value = TransFailID{ + ID: request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.TransactionID, + } + + outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].ID = CauseID + outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].Value.Value = cause + + outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[2].ID = TimeToWaitID + outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[2].Value.Value = timeToWaitMap[timeToWait] + return E2SetupResponseMessage{E2APPDU: E2APPDU{Outcome: outcome}} } @@ -181,6 +243,52 @@ type ProtocolIESingleContainer struct { } `xml:"value"` } +type TransID struct { + Text string `xml:",chardata"` + TransactionID string `xml:"TransactionID"` +} + +type TransFailID struct { + XMLName xml.Name `xml:"TransactionID"` + ID string `xml:",chardata"` +} + +type E2NodeConfigUpdateAckList struct { + Text string `xml:",chardata"` + E2NodeConfigUpdateAckList struct { + Text string `xml:",chardata"` + E2NodeConfigSingleContainer []E2NodeConfigSingleContainer `xml:"ProtocolIE-SingleContainer"` + } `xml:"E2nodeComponentConfigAdditionAck-List"` +} + +type E2NodeConfigSingleContainer struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2NodeConfigUpdateAckItem struct { + Text string `xml:",chardata"` + E2nodeComponentType E2NodeComponentType `xml:"e2nodeComponentInterfaceType"` + E2nodeComponentID E2NodeComponentIDResp + E2nodeConfigUpdateAck E2nodeConfigUpdateAckResp + } `xml:"E2nodeComponentConfigAdditionAck-Item"` + } `xml:"value"` +} + +type E2NodeComponentIDResp struct { + XMLName xml.Name `xml:"e2nodeComponentID"` + Value interface{} +} + +type E2nodeConfigUpdateAckResp struct { + XMLName xml.Name `xml:"e2nodeComponentConfigurationAck"` + Value interface{} +} + type UnsuccessfulOutcome struct { XMLName xml.Name `xml:"unsuccessfulOutcome"` Text string `xml:",chardata"` @@ -214,8 +322,8 @@ type E2setupFailureIEs struct { } `xml:"value"` } -func extractRanFunctionsIDList(request *E2SetupRequestMessage) []ProtocolIESingleContainer { - list := &request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[1].Value.RANfunctionsList +func extractRanFunctionsIDList(request *E2SetupRequestMessage, index int) []ProtocolIESingleContainer { + list := &request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[index].Value.RANfunctionsList ids := make([]ProtocolIESingleContainer, len(list.ProtocolIESingleContainer)) for i := 0; i < len(ids); i++ { ids[i] = convertToRANfunctionID(list, i) @@ -225,8 +333,74 @@ func extractRanFunctionsIDList(request *E2SetupRequestMessage) []ProtocolIESingl func convertToRANfunctionID(list *RANfunctionsList, i int) ProtocolIESingleContainer { id := ProtocolIESingleContainer{} - id.ID = "6" + + id.ID = RanFunctionIDItemID id.Value.RANfunctionIDItem.RanFunctionID = list.ProtocolIESingleContainer[i].Value.RANfunctionItem.RanFunctionID id.Value.RANfunctionIDItem.RanFunctionRevision = list.ProtocolIESingleContainer[i].Value.RANfunctionItem.RanFunctionRevision + + return id +} + +func extractE2NodeConfigUpdateList(request *E2SetupRequestMessage, index int, outcome int) []E2NodeConfigSingleContainer { + list := &request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[index].Value.E2NodeConfigList + ids := make([]E2NodeConfigSingleContainer, len(list.ProtocolIESingleContainer)) + for i := 0; i < len(ids); i++ { + ids[i] = convertToE2NodeConfig(list, i, outcome) + } + return ids +} + +func convertToE2NodeConfig(list *E2NodeConfigList, i int, outcome int) E2NodeConfigSingleContainer { + id := E2NodeConfigSingleContainer{} + id.ID = E2nodeConfigAdditionAckItemID + + id.Value.E2NodeConfigUpdateAckItem.E2nodeConfigUpdateAck.Value = configStatusMap[outcome] + + id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentType = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType + + if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.NG != nil { + id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeNG{ + AMFName: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeNG.AMFName, + } + } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.XN != nil { + ifXn := E2NodeIFTypeXN{} + ifXn.GlobalNgENBID.GNB.PLMNID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.GNB.PLMNID + ifXn.GlobalNgENBID.GNB.GnbID.GnbID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.GNB.GnbID.GnbID + ifXn.GlobalNgENBID.NGENB.PLMNID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.PLMNID + ifXn.GlobalNgENBID.NGENB.GnbID.ENBIDMacro = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.GnbID.ENBIDMacro + ifXn.GlobalNgENBID.NGENB.GnbID.ENBIDShortMacro = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.GnbID.ENBIDShortMacro + ifXn.GlobalNgENBID.NGENB.GnbID.ENBIDLongMacro = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.GnbID.ENBIDLongMacro + + id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = ifXn + } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.E1 != nil { + id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeE1{ + GNBCUCPID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeE1.GNBCUCPID, + } + } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.F1 != nil { + id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeF1{ + GNBDUID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeF1.GNBDUID, + } + } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.W1 != nil { + id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeW1{ + NGENBDUID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeW1.NGENBDUID, + } + } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.S1 != nil { + id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeS1{ + MMENAME: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeS1.MMENAME, + } + } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.X2 != nil { + ifX2 := E2NodeIFTypeX2{} + ifX2.GlobalENBID.PLMNIdentity = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.PLMNIdentity + ifX2.GlobalENBID.ENBID.MacroENBID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.MacroENBID + ifX2.GlobalENBID.ENBID.HomeENBID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.HomeENBID + ifX2.GlobalENBID.ENBID.ShortMacroENBID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.ShortMacroENBID + ifX2.GlobalENBID.ENBID.LongMacroENBID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.LongMacroENBID + + ifX2.GlobalEnGNBID.PLMNIdentity = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalEnGNBID.PLMNIdentity + ifX2.GlobalEnGNBID.GNBID.GNBID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalEnGNBID.GNBID.GNBID + + id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = ifX2 + } + return id } diff --git a/E2Manager/models/e2_setup_response_message_test.go b/E2Manager/models/e2_setup_response_message_test.go index 2e2d7ba..744a8c9 100644 --- a/E2Manager/models/e2_setup_response_message_test.go +++ b/E2Manager/models/e2_setup_response_message_test.go @@ -1,6 +1,7 @@ // // Copyright 2020 AT&T Intellectual Property // Copyright 2020 Nokia +// 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. @@ -23,8 +24,9 @@ import ( "e2mgr/models" "e2mgr/utils" "encoding/xml" - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) const ( @@ -47,10 +49,10 @@ func TestNewE2SetupSuccessResponseMessageSuccess(t *testing.T) { resp := models.NewE2SetupSuccessResponseMessage(plmn, ricNearRtId, setupRequest) respIEs := resp.E2APPDU.Outcome.(models.SuccessfulOutcome).Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs - assert.Equal(t, "4", respIEs[0].ID) - assert.Equal(t, plmn, respIEs[0].Value.(models.GlobalRICID).GlobalRICID.PLMNIdentity) - assert.Equal(t, ricNearRtId, respIEs[0].Value.(models.GlobalRICID).GlobalRICID.RicID) - assert.Equal(t, "9", respIEs[1].ID) + assert.Equal(t, models.GlobalRicID, respIEs[1].ID) + assert.Equal(t, plmn, respIEs[1].Value.(models.GlobalRICID).GlobalRICID.PLMNIdentity) + assert.Equal(t, ricNearRtId, respIEs[1].Value.(models.GlobalRICID).GlobalRICID.RicID) + assert.Equal(t, models.RanFunctionsAcceptedID, respIEs[2].ID) } func TestNewE2SetupSuccessResponseMessageWithoutRanFunctionsSuccess(t *testing.T) { @@ -60,18 +62,19 @@ func TestNewE2SetupSuccessResponseMessageWithoutRanFunctionsSuccess(t *testing.T resp := models.NewE2SetupSuccessResponseMessage(plmn, ricNearRtId, setupRequest) respIEs := resp.E2APPDU.Outcome.(models.SuccessfulOutcome).Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs - assert.Equal(t, "4", respIEs[0].ID) - assert.Equal(t, plmn, respIEs[0].Value.(models.GlobalRICID).GlobalRICID.PLMNIdentity) - assert.Equal(t, ricNearRtId, respIEs[0].Value.(models.GlobalRICID).GlobalRICID.RicID) - assert.Equal(t, 1, len(respIEs)) + assert.Equal(t, models.GlobalRicID, respIEs[1].ID) + assert.Equal(t, plmn, respIEs[1].Value.(models.GlobalRICID).GlobalRICID.PLMNIdentity) + assert.Equal(t, ricNearRtId, respIEs[1].Value.(models.GlobalRICID).GlobalRICID.RicID) + assert.Equal(t, 3, len(respIEs)) } func TestNewE2SetupFailureResponseMessageSuccess(t *testing.T) { waitTime := models.TimeToWaitEnum.V60s cause := models.Cause{Misc: &models.CauseMisc{OmIntervention: &struct{}{}}} + setupRequest := getE2SetupRespTestE2SetupRequest(t, e2SetupRespGnbSetupRequestXmlPath) - resp := models.NewE2SetupFailureResponseMessage(waitTime, cause) + resp := models.NewE2SetupFailureResponseMessage(waitTime, cause, setupRequest) respIEs := resp.E2APPDU.Outcome.(models.UnsuccessfulOutcome).Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs - assert.Equal(t, "1", respIEs[0].ID) - assert.Equal(t, cause, respIEs[0].Value.Value.(models.Cause)) + assert.Equal(t, models.CauseID, respIEs[1].ID) + assert.Equal(t, cause, respIEs[1].Value.Value.(models.Cause)) } diff --git a/E2Manager/models/ric_service_query_message.go b/E2Manager/models/ric_service_query_message.go index dc6d315..ec8ed40 100644 --- a/E2Manager/models/ric_service_query_message.go +++ b/E2Manager/models/ric_service_query_message.go @@ -20,13 +20,17 @@ package models import ( "encoding/xml" + "math/rand" + "strconv" + "time" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" ) type RanFunctionIdItem struct { - Text string `xml:",chardata"` - RanFunctionId uint32 `xml:"ranFunctionID"` - RanFunctionRevision uint32 `xml:"ranFunctionRevision"` + Text string `xml:",chardata"` + RanFunctionId uint32 `xml:"ranFunctionID"` + RanFunctionRevision uint32 `xml:"ranFunctionRevision"` } type RicServiceQueryProtocolIESingleContainer struct { @@ -37,8 +41,8 @@ type RicServiceQueryProtocolIESingleContainer struct { Reject string `xml:"reject"` } `xml:"criticality"` Value struct { - Text string `xml:",chardata"` - RanFunctionIdItem RanFunctionIdItem `xml:"RANfunctionID-Item"` + Text string `xml:",chardata"` + RanFunctionIdItem RanFunctionIdItem `xml:"RANfunctionID-Item"` } `xml:"value"` } @@ -49,19 +53,25 @@ type RICServiceQueryIEs struct { Text string `xml:",chardata"` Reject string `xml:"reject"` } `xml:"criticality"` - Value struct { - Text string `xml:",chardata"` - RANFunctionIdList struct { - Text string `xml:",chardata"` - ProtocolIESingleContainer []RicServiceQueryProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` - } `xml:"RANfunctionsID-List"` - } `xml:"value"` + Value interface{} `xml:"value"` +} + +type RICServiceQueryRANFunctionIdList struct { + Text string `xml:",chardata"` + RANFunctionIdList struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []RicServiceQueryProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + } `xml:"RANfunctionsID-List"` +} +type RICServiceQueryTransactionID struct { + Text string `xml:",chardata"` + TransactionID string `xml:"TransactionID"` } type RICServiceQuery struct { - Text string `xml:",chardata"` + Text string `xml:",chardata"` ProtocolIEs struct { - Text string `xml:",chardata"` + Text string `xml:",chardata"` RICServiceQueryIEs []RICServiceQueryIEs `xml:"RICserviceQuery-IEs"` } `xml:"protocolIEs"` } @@ -74,38 +84,68 @@ type InitiatingMessage struct { Ignore string `xml:"ignore"` } `xml:"criticality"` Value struct { - Text string `xml:",chardata"` + Text string `xml:",chardata"` RICServiceQuery RICServiceQuery `xml:"RICserviceQuery"` } `xml:"value"` } type RicServiceQueryE2APPDU struct { - XMLName xml.Name `xml:"E2AP-PDU"` - Text string `xml:",chardata"` + XMLName xml.Name `xml:"E2AP-PDU"` + Text string `xml:",chardata"` InitiatingMessage InitiatingMessage `xml:"initiatingMessage"` } - -type RICServiceQueryMessage struct{ - XMLName xml.Name `xml:"RICserviceQueryMessage"` - Text string `xml:",chardata"` - E2APPDU RicServiceQueryE2APPDU `xml:"E2AP-PDU"` +type RICServiceQueryMessage struct { + XMLName xml.Name `xml:"RICserviceQueryMessage"` + Text string `xml:",chardata"` + E2APPDU RicServiceQueryE2APPDU `xml:"E2AP-PDU"` } func NewRicServiceQueryMessage(ranFunctions []*entities.RanFunction) RICServiceQueryMessage { - initiatingMessage := InitiatingMessage{} - initiatingMessage.ProcedureCode = "6" - initiatingMessage.Value.RICServiceQuery.ProtocolIEs.RICServiceQueryIEs = make([]RICServiceQueryIEs,1) - initiatingMessage.Value.RICServiceQuery.ProtocolIEs.RICServiceQueryIEs[0].Id = "9" - protocolIESingleContainer := make([]RicServiceQueryProtocolIESingleContainer,len(ranFunctions)) + rand.Seed(time.Now().Unix()) + + txIE := RICServiceQueryIEs{ + Id: ProtocolIE_ID_id_TransactionID, + Value: RICServiceQueryTransactionID{ + TransactionID: strconv.FormatUint(rand.Uint64(), 10), + }, + } + + protocolIESingleContainer := make([]RicServiceQueryProtocolIESingleContainer, len(ranFunctions)) for i := 0; i < len(ranFunctions); i++ { - protocolIESingleContainer[i].Id = "6" + protocolIESingleContainer[i].Id = ProtocolIE_ID_id_RANfunctionID_Item protocolIESingleContainer[i].Value.RanFunctionIdItem.RanFunctionId = ranFunctions[i].RanFunctionId protocolIESingleContainer[i].Value.RanFunctionIdItem.RanFunctionRevision = ranFunctions[i].RanFunctionRevision } - initiatingMessage.Value.RICServiceQuery.ProtocolIEs.RICServiceQueryIEs[0].Value.RANFunctionIdList.ProtocolIESingleContainer = protocolIESingleContainer - return RICServiceQueryMessage{E2APPDU:RicServiceQueryE2APPDU{InitiatingMessage:initiatingMessage}} -} + funcListIE := RICServiceQueryIEs{ + Id: ProtocolIE_ID_id_RANfunctionsAccepted, + Value: RICServiceQueryRANFunctionIdList{ + RANFunctionIdList: struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []RicServiceQueryProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + }{ + ProtocolIESingleContainer: protocolIESingleContainer, + }, + }, + } + initiatingMessage := InitiatingMessage{ + ProcedureCode: ProcedureCode_id_RICserviceQuery, + Value: struct { + Text string `xml:",chardata"` + RICServiceQuery RICServiceQuery `xml:"RICserviceQuery"` + }{ + RICServiceQuery: RICServiceQuery{ + ProtocolIEs: struct { + Text string `xml:",chardata"` + RICServiceQueryIEs []RICServiceQueryIEs `xml:"RICserviceQuery-IEs"` + }{ + RICServiceQueryIEs: []RICServiceQueryIEs{txIE, funcListIE}, + }, + }, + }, + } + return RICServiceQueryMessage{E2APPDU: RicServiceQueryE2APPDU{InitiatingMessage: initiatingMessage}} +} diff --git a/E2Manager/models/ric_service_query_message_test.go b/E2Manager/models/ric_service_query_message_test.go index 3ed2fbc..281f679 100644 --- a/E2Manager/models/ric_service_query_message_test.go +++ b/E2Manager/models/ric_service_query_message_test.go @@ -23,9 +23,10 @@ import ( "e2mgr/models" "e2mgr/utils" "encoding/xml" + "testing" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" "github.com/stretchr/testify/assert" - "testing" ) func getTestRicServiceQueryRanFunctions(t *testing.T) []*entities.RanFunction { @@ -47,7 +48,15 @@ func TestRicServiceQueryMessageSuccess(t *testing.T) { serviceQuery := models.NewRicServiceQueryMessage(ranFunctionList) initMsg := serviceQuery.E2APPDU.InitiatingMessage - assert.Equal(t, "6", initMsg.ProcedureCode) - assert.Equal(t, "9", initMsg.Value.RICServiceQuery.ProtocolIEs.RICServiceQueryIEs[0].Id) - assert.Equal(t, 3, len(initMsg.Value.RICServiceQuery.ProtocolIEs.RICServiceQueryIEs[0].Value.RANFunctionIdList.ProtocolIESingleContainer)) + assert.Equal(t, models.ProcedureCode_id_RICserviceQuery, initMsg.ProcedureCode) + assert.Equal(t, models.ProtocolIE_ID_id_TransactionID, initMsg.Value.RICServiceQuery.ProtocolIEs.RICServiceQueryIEs[0].Id) + assert.Equal(t, models.ProtocolIE_ID_id_RANfunctionsAccepted, initMsg.Value.RICServiceQuery.ProtocolIEs.RICServiceQueryIEs[1].Id) + assert.Equal(t, 3, len(initMsg.Value.RICServiceQuery.ProtocolIEs.RICServiceQueryIEs[1].Value.(models.RICServiceQueryRANFunctionIdList).RANFunctionIdList.ProtocolIESingleContainer)) +} + +func TestTransactionIdServiceQuery(t *testing.T) { + ranFunctionList := getTestRicServiceQueryRanFunctions(t) + serviceQuery := models.NewRicServiceQueryMessage(ranFunctionList) + txIE := serviceQuery.E2APPDU.InitiatingMessage.Value.RICServiceQuery.ProtocolIEs.RICServiceQueryIEs[0].Value.(models.RICServiceQueryTransactionID) + assert.NotEmpty(t, txIE.TransactionID, "transaction ID should not be empty") } diff --git a/E2Manager/models/ric_service_update_ack_message.go b/E2Manager/models/ric_service_update_ack_message.go index 1388f14..9ba085c 100644 --- a/E2Manager/models/ric_service_update_ack_message.go +++ b/E2Manager/models/ric_service_update_ack_message.go @@ -19,89 +19,123 @@ package models import ( - "encoding/xml" + "encoding/xml" ) type RicServiceAckRANFunctionIDItem struct { Text string `xml:",chardata"` - RanFunctionID uint32 `xml:"ranFunctionID"` - RanFunctionRevision uint32 `xml:"ranFunctionRevision"` + RanFunctionID uint32 `xml:"ranFunctionID"` + RanFunctionRevision uint32 `xml:"ranFunctionRevision"` } type RICserviceUpdateAcknowledgeProtocolIESingleContainer struct { - Text string `xml:",chardata"` - Id string `xml:"id"` - Criticality struct { - Text string `xml:",chardata"` - //Ignore string `xml:"ignore"` - Reject string `xml:"reject"` - } `xml:"criticality"` - Value struct { - Text string `xml:",chardata"` - RANfunctionIDItem RicServiceAckRANFunctionIDItem `xml:"RANfunctionID-Item"` - } `xml:"value"` + Text string `xml:",chardata"` + Id string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + //Ignore string `xml:"ignore"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + RANfunctionIDItem RicServiceAckRANFunctionIDItem `xml:"RANfunctionID-Item"` + } `xml:"value"` } type RICserviceUpdateAcknowledgeIEs struct { Text string `xml:",chardata"` - ID string `xml:"id"` - Criticality struct { - Text string `xml:",chardata"` - Reject string `xml:"reject"` - } `xml:"criticality"` - Value struct { + ID string `xml:"id"` + Criticality struct { Text string `xml:",chardata"` - RANfunctionsIDList struct { - Text string `xml:",chardata"` - ProtocolIESingleContainer []RICserviceUpdateAcknowledgeProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` - } `xml:"RANfunctionsID-List"` - }`xml:"value"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value interface{} `xml:"value"` } +type RICserviceUpdateAcknowledgeTransactionID struct { + Text string `xml:",chardata"` + TransactionID string `xml:"TransactionID"` +} + +type RICserviceUpdateAcknowledgeRANfunctionsList struct { + Text string `xml:",chardata"` + RANfunctionsIDList struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []RICserviceUpdateAcknowledgeProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + } `xml:"RANfunctionsID-List"` +} type RicServiceUpdateAckSuccessfulOutcome struct { - XMLName xml.Name `xml:"successfulOutcome"` - Text string `xml:",chardata"` - ProcedureCode string `xml:"procedureCode"` - Criticality struct { - Text string `xml:",chardata"` - Reject string `xml:"reject"` - } `xml:"criticality"` + XMLName xml.Name `xml:"successfulOutcome"` + Text string `xml:",chardata"` + ProcedureCode string `xml:"procedureCode"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` Value struct { - Text string `xml:",chardata"` - RICserviceUpdateAcknowledge RICserviceUpdateAcknowledge `xml:"RICserviceUpdateAcknowledge"` + Text string `xml:",chardata"` + RICserviceUpdateAcknowledge RICserviceUpdateAcknowledge `xml:"RICserviceUpdateAcknowledge"` } `xml:"value"` } type RICserviceUpdateAcknowledge struct { Text string `xml:",chardata"` ProtocolIEs struct { - Text string `xml:",chardata"` + Text string `xml:",chardata"` RICserviceUpdateAcknowledgeIEs []RICserviceUpdateAcknowledgeIEs `xml:"RICserviceUpdateAcknowledge-IEs"` } `xml:"protocolIEs"` } type RicServiceUpdateAckE2APPDU struct { - XMLName xml.Name `xml:"E2AP-PDU"` - Text string `xml:",chardata"` - InitiatingMessage interface{} + XMLName xml.Name `xml:"E2AP-PDU"` + Text string `xml:",chardata"` + SuccessfulOutcome interface{} } -func NewServiceUpdateAck(ricServiceUpdate []RicServiceAckRANFunctionIDItem) RicServiceUpdateAckE2APPDU { - successfulOutcome := RicServiceUpdateAckSuccessfulOutcome{} - successfulOutcome.ProcedureCode = "7" - if len(ricServiceUpdate) == 0 { - return RicServiceUpdateAckE2APPDU{InitiatingMessage:successfulOutcome} +func NewServiceUpdateAck(ricServiceUpdate []RicServiceAckRANFunctionIDItem, txId string) RicServiceUpdateAckE2APPDU { + + txIE := RICserviceUpdateAcknowledgeIEs{ + ID: ProtocolIE_ID_id_TransactionID, + Value: RICserviceUpdateAcknowledgeTransactionID{ + TransactionID: txId, + }, } - ricServiceUpdateAcknowledgeIEs := make([]RICserviceUpdateAcknowledgeIEs, 1) - ricServiceUpdateAcknowledgeIEs[0].ID = "9" protocolIESingleContainer := make([]RICserviceUpdateAcknowledgeProtocolIESingleContainer, len(ricServiceUpdate)) for i := 0; i < len(ricServiceUpdate); i++ { protocolIESingleContainer[i].Value.RANfunctionIDItem = ricServiceUpdate[i] - protocolIESingleContainer[i].Id = "6" + protocolIESingleContainer[i].Id = ProtocolIE_ID_id_RANfunctionID_Item + } + + // mandatory RANFunctionsAccepted + functionListIE := RICserviceUpdateAcknowledgeIEs{ + ID: ProtocolIE_ID_id_RANfunctionsAccepted, + Value: RICserviceUpdateAcknowledgeRANfunctionsList{ + RANfunctionsIDList: struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []RICserviceUpdateAcknowledgeProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` + }{ + ProtocolIESingleContainer: protocolIESingleContainer, + }, + }, } - ricServiceUpdateAcknowledgeIEs[0].Value.RANfunctionsIDList.ProtocolIESingleContainer = protocolIESingleContainer - successfulOutcome.Value.RICserviceUpdateAcknowledge.ProtocolIEs.RICserviceUpdateAcknowledgeIEs = ricServiceUpdateAcknowledgeIEs - return RicServiceUpdateAckE2APPDU{InitiatingMessage:successfulOutcome} -} + successfulOutcome := RicServiceUpdateAckSuccessfulOutcome{ + ProcedureCode: ProcedureCode_id_RICserviceUpdate, + Value: struct { + Text string `xml:",chardata"` + RICserviceUpdateAcknowledge RICserviceUpdateAcknowledge `xml:"RICserviceUpdateAcknowledge"` + }{ + RICserviceUpdateAcknowledge: RICserviceUpdateAcknowledge{ + ProtocolIEs: struct { + Text string `xml:",chardata"` + RICserviceUpdateAcknowledgeIEs []RICserviceUpdateAcknowledgeIEs `xml:"RICserviceUpdateAcknowledge-IEs"` + }{ + RICserviceUpdateAcknowledgeIEs: []RICserviceUpdateAcknowledgeIEs{txIE, functionListIE}, + }, + }, + }, + } + + return RicServiceUpdateAckE2APPDU{SuccessfulOutcome: successfulOutcome} +} diff --git a/E2Manager/models/ric_service_update_ack_message_test.go b/E2Manager/models/ric_service_update_ack_message_test.go index 8dfd4bb..85f2568 100644 --- a/E2Manager/models/ric_service_update_ack_message_test.go +++ b/E2Manager/models/ric_service_update_ack_message_test.go @@ -21,8 +21,9 @@ package models_test import ( "e2mgr/models" - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestRicServiceUpdateAckMessageSuccess(t *testing.T) { @@ -33,20 +34,20 @@ func TestRicServiceUpdateAckMessageSuccess(t *testing.T) { item2, } - serviceUpdateAck := models.NewServiceUpdateAck(serviceupdateAckFunctionIds) - ies := serviceUpdateAck.InitiatingMessage.(models.RicServiceUpdateAckSuccessfulOutcome).Value.RICserviceUpdateAcknowledge.ProtocolIEs.RICserviceUpdateAcknowledgeIEs - assert.Equal(t, "9", ies[0].ID) - assert.Equal(t, "6", ies[0].Value.RANfunctionsIDList.ProtocolIESingleContainer[0].Id) - assert.Equal(t, "6", ies[0].Value.RANfunctionsIDList.ProtocolIESingleContainer[1].Id) - assert.Equal(t, item1, ies[0].Value.RANfunctionsIDList.ProtocolIESingleContainer[0].Value.RANfunctionIDItem) - assert.Equal(t, item2, ies[0].Value.RANfunctionsIDList.ProtocolIESingleContainer[1].Value.RANfunctionIDItem) + serviceUpdateAck := models.NewServiceUpdateAck(serviceupdateAckFunctionIds, "1234") + ies := serviceUpdateAck.SuccessfulOutcome.(models.RicServiceUpdateAckSuccessfulOutcome).Value.RICserviceUpdateAcknowledge.ProtocolIEs.RICserviceUpdateAcknowledgeIEs + assert.Equal(t, models.ProtocolIE_ID_id_RANfunctionsAccepted, ies[1].ID) + assert.Equal(t, models.ProtocolIE_ID_id_RANfunctionID_Item, ies[1].Value.(models.RICserviceUpdateAcknowledgeRANfunctionsList).RANfunctionsIDList.ProtocolIESingleContainer[0].Id) + assert.Equal(t, models.ProtocolIE_ID_id_RANfunctionID_Item, ies[1].Value.(models.RICserviceUpdateAcknowledgeRANfunctionsList).RANfunctionsIDList.ProtocolIESingleContainer[1].Id) + assert.Equal(t, item1, ies[1].Value.(models.RICserviceUpdateAcknowledgeRANfunctionsList).RANfunctionsIDList.ProtocolIESingleContainer[0].Value.RANfunctionIDItem) + assert.Equal(t, item2, ies[1].Value.(models.RICserviceUpdateAcknowledgeRANfunctionsList).RANfunctionsIDList.ProtocolIESingleContainer[1].Value.RANfunctionIDItem) + + txIE := serviceUpdateAck.SuccessfulOutcome.(models.RicServiceUpdateAckSuccessfulOutcome).Value.RICserviceUpdateAcknowledge.ProtocolIEs.RICserviceUpdateAcknowledgeIEs[0] + assert.Equal(t, models.ProtocolIE_ID_id_TransactionID, txIE.ID) + assert.Equal(t, "1234", txIE.Value.(models.RICserviceUpdateAcknowledgeTransactionID).TransactionID) } func TestRicServiceUpdateAckMessageNoRanFunctionIdItemsSuccess(t *testing.T) { - successfulOutcome := models.RicServiceUpdateAckSuccessfulOutcome{} - successfulOutcome.ProcedureCode = "7" - - expectedAck := models.RicServiceUpdateAckE2APPDU{InitiatingMessage: successfulOutcome} - serviceUpdateAck := models.NewServiceUpdateAck(nil) - assert.Equal(t, expectedAck, serviceUpdateAck) + serviceUpdateAck := models.NewServiceUpdateAck(nil, "1234") + assert.Equal(t, 2, len(serviceUpdateAck.SuccessfulOutcome.(models.RicServiceUpdateAckSuccessfulOutcome).Value.RICserviceUpdateAcknowledge.ProtocolIEs.RICserviceUpdateAcknowledgeIEs), "Trasaction ID is mandatory IE") } diff --git a/E2Manager/models/ric_service_update_message.go b/E2Manager/models/ric_service_update_message.go index 0ffe458..29055d5 100644 --- a/E2Manager/models/ric_service_update_message.go +++ b/E2Manager/models/ric_service_update_message.go @@ -69,6 +69,7 @@ type RICServiceUpdateIEs struct { } `xml:"criticality"` Value struct { Text string `xml:",chardata"` + TransactionID string `xml:"TransactionID"` RANfunctionsList struct { Text string `xml:",chardata"` RANfunctionsItemProtocolIESingleContainer []RANfunctionsItemProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"` @@ -113,11 +114,11 @@ type RICServiceUpdateMessage struct { func (m *RICServiceUpdateE2APPDU) ExtractRanFunctionsList() []*entities.RanFunction { serviceUpdateRequestIes := m.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs - if len(serviceUpdateRequestIes) < 2 { + if len(serviceUpdateRequestIes) < 3 { return nil } - ranFunctionsListContainer := serviceUpdateRequestIes[1].Value.RANfunctionsList.RANfunctionsItemProtocolIESingleContainer + ranFunctionsListContainer := serviceUpdateRequestIes[2].Value.RANfunctionsList.RANfunctionsItemProtocolIESingleContainer funcs := make([]*entities.RanFunction, len(ranFunctionsListContainer)) for i := 0; i < len(funcs); i++ { ranFunctionItem := ranFunctionsListContainer[i].Value.RANfunctionItem diff --git a/E2Manager/models/ric_service_update_message_test.go b/E2Manager/models/ric_service_update_message_test.go index 3edff8a..de6a136 100644 --- a/E2Manager/models/ric_service_update_message_test.go +++ b/E2Manager/models/ric_service_update_message_test.go @@ -58,3 +58,8 @@ func TestRicServiceUpdateMessageWithOID(t *testing.T) { assert.Equal(t, uint32(2), ranFunctions[0].RanFunctionRevision) assert.Equal(t, "OID20", ranFunctions[0].RanFunctionOid) } + +func TestRICServiceUpdateMessageTxId(t *testing.T) { + serviceUpdate := getTestRicServiceUpdate(t, "../tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction_With_OID.xml") + assert.Equal(t, "1234", serviceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs[0].Value.TransactionID) +} diff --git a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go index 463b230..5f02168 100644 --- a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go +++ b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go @@ -94,6 +94,7 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config e2TKeepAliveResponseHandler := rmrmsghandlers.NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManager) e2SetupRequestNotificationHandler := rmrmsghandlers.NewE2SetupRequestNotificationHandler(logger, config, e2tInstancesManager, rmrSender, rnibDataService, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager) ricServiceUpdateHandler := rmrmsghandlers.NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManager) + ricE2nodeConfigUpdateHandler := rmrmsghandlers.NewE2nodeConfigUpdateNotificationHandler(logger, rnibDataService, rmrSender) provider.Register(rmrCgo.RIC_X2_SETUP_RESP, x2SetupResponseHandler) provider.Register(rmrCgo.RIC_X2_SETUP_FAILURE, x2SetupFailureResponseHandler) @@ -109,4 +110,5 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config provider.Register(rmrCgo.E2_TERM_KEEP_ALIVE_RESP, e2TKeepAliveResponseHandler) provider.Register(rmrCgo.RIC_E2_SETUP_REQ, e2SetupRequestNotificationHandler) provider.Register(rmrCgo.RIC_SERVICE_UPDATE, ricServiceUpdateHandler) + provider.Register(rmrCgo.RIC_E2NODE_CONFIG_UPDATE, ricE2nodeConfigUpdateHandler) } diff --git a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go index 28bff54..2e3d364 100644 --- a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go +++ b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go @@ -98,6 +98,7 @@ func TestGetNotificationHandlerSuccess(t *testing.T) { {rmrCgo.RIC_X2_RESET_RESP, rmrmsghandlers.NewX2ResetResponseHandler(logger, rnibDataService, ranStatusChangeManager, converters.NewX2ResetResponseExtractor(logger))}, {rmrCgo.RIC_X2_RESET, rmrmsghandlers.NewX2ResetRequestNotificationHandler(logger, rnibDataService, ranStatusChangeManager, rmrSender)}, {rmrCgo.RIC_SERVICE_UPDATE, rmrmsghandlers.NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManager)}, + {rmrCgo.RIC_E2NODE_CONFIG_UPDATE, rmrmsghandlers.NewE2nodeConfigUpdateNotificationHandler(logger, rnibDataService, rmrSender)}, } for _, tc := range testCases { diff --git a/E2Manager/rmrCgo/rmrCgoTypes.go b/E2Manager/rmrCgo/rmrCgoTypes.go index d3886b4..0cab4da 100644 --- a/E2Manager/rmrCgo/rmrCgoTypes.go +++ b/E2Manager/rmrCgo/rmrCgoTypes.go @@ -18,7 +18,6 @@ // This source code is part of the near-RT RIC (RAN Intelligent Controller) // platform project (RICP). - package rmrCgo // #cgo LDFLAGS: -L/usr/local/lib -lrmr_si @@ -72,25 +71,28 @@ const ( RIC_SCTP_CLEAR_ALL = C.RIC_SCTP_CLEAR_ALL RIC_X2_RESET_RESP = C.RIC_X2_RESET_RESP RIC_X2_RESET = C.RIC_X2_RESET - RIC_E2_TERM_INIT = C.E2_TERM_INIT - RAN_CONNECTED = C.RAN_CONNECTED - RAN_RESTARTED = C.RAN_RESTARTED - RAN_RECONFIGURED = C.RAN_RECONFIGURED - E2_TERM_KEEP_ALIVE_REQ = C.E2_TERM_KEEP_ALIVE_REQ - E2_TERM_KEEP_ALIVE_RESP = C.E2_TERM_KEEP_ALIVE_RESP - RIC_E2_SETUP_REQ = C.RIC_E2_SETUP_REQ + RIC_E2_TERM_INIT = C.E2_TERM_INIT + RAN_CONNECTED = C.RAN_CONNECTED + RAN_RESTARTED = C.RAN_RESTARTED + RAN_RECONFIGURED = C.RAN_RECONFIGURED + E2_TERM_KEEP_ALIVE_REQ = C.E2_TERM_KEEP_ALIVE_REQ + E2_TERM_KEEP_ALIVE_RESP = C.E2_TERM_KEEP_ALIVE_RESP + RIC_E2_SETUP_REQ = C.RIC_E2_SETUP_REQ RIC_E2_SETUP_RESP = C.RIC_E2_SETUP_RESP RIC_E2_SETUP_FAILURE = C.RIC_E2_SETUP_FAILURE RIC_SERVICE_QUERY = C.RIC_SERVICE_QUERY RIC_SERVICE_UPDATE = C.RIC_SERVICE_UPDATE RIC_SERVICE_UPDATE_ACK = C.RIC_SERVICE_UPDATE_ACK RIC_SERVICE_UPDATE_FAILURE = C.RIC_SERVICE_UPDATE_FAILURE + RIC_E2NODE_CONFIG_UPDATE = C.RIC_E2NODE_CONFIG_UPDATE + RIC_E2NODE_CONFIG_UPDATE_ACK = C.RIC_E2NODE_CONFIG_UPDATE_ACK + RIC_E2NODE_CONFIG_UPDATE_FAILURE = C.RIC_E2NODE_CONFIG_UPDATE_FAILURE ) const ( RMR_MAX_XACTION_LEN = int(C.RMR_MAX_XID) RMR_MAX_MEID_LEN = int(C.RMR_MAX_MEID) - RMR_MAX_SRC_LEN = int(C.RMR_MAX_SRC) + RMR_MAX_SRC_LEN = int(C.RMR_MAX_SRC) //states RMR_OK = C.RMR_OK diff --git a/E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdate.xml b/E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdate.xml new file mode 100644 index 0000000..a86f941 --- /dev/null +++ b/E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdate.xml @@ -0,0 +1,410 @@ + + + 10 + + + + + + 49 + + + 1234 + + + + 50 + + + + + 51 + + + + + + + nginterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + + + + 67 6E 62 3A 31 32 33 34 35 36 37 38 39 73 64 66 + 67 31 31 31 + + + + 0011000100110010001100110011010000110101001100010011001000110011 + 0011010000110101001100010011001000110011001101000011001000110010 + 00110010001100100011001000110010 + + + + + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + 100 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + 100 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + 121 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + s1interf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + x2interf + x2interf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + + + 33 + + + + + 34 + + + + + + + nginterf + + + + 72 65 71 70 61 72 73 + 72 65 73 70 61 72 73 + + + + + + 34 + + + + + + + xninterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 34 + + + + + + + 1234 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 34 + + + + + + + 2345 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 34 + + + + + + + 3456 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 34 + + + + + + + s1interf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 34 + + + + + + + x2interf + x2interf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + + + 54 + + + + + 55 + + + + + + + nginterf + + + + + + + 55 + + + + + + + xninterf + + + + + + + 55 + + + + + + + 100 + + + + + + + 55 + + + + + + + 100 + + + + + + + 55 + + + + + + + 121 + + + + + + + 55 + + + + + + + s1interf + + + + + + + 55 + + + + + + + x2interf + x2interf + + + + + + + + + + + + + \ No newline at end of file diff --git a/E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdateAdditionAndUpdateOnly.xml b/E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdateAdditionAndUpdateOnly.xml new file mode 100644 index 0000000..1d8ca8c --- /dev/null +++ b/E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdateAdditionAndUpdateOnly.xml @@ -0,0 +1,303 @@ + + + 6 + + + + + + 49 + + + 1234 + + + + 50 + + + + + 51 + + + + + + + nginterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + + + + 67 6E 62 3A 31 32 33 34 35 36 37 38 39 73 64 66 + 67 31 31 31 + + + + 0011000100110010001100110011010000110101001100010011001000110011 + 0011010000110101001100010011001000110011001101000011001000110010 + 00110010001100100011001000110010 + + + + + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + 100 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + 100 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + 121 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + s1interf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + x2interf + x2interf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + + + 33 + + + + + 34 + + + + + + + nginterf + + + + 72 65 71 70 61 72 73 + 72 65 73 70 61 72 73 + + + + + + 34 + + + + + + + xninterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 34 + + + + + + + 1234 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 34 + + + + + + + 2345 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 34 + + + + + + + 3456 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 34 + + + + + + + s1interf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 34 + + + + + + + x2interf + x2interf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + + + + + + \ No newline at end of file diff --git a/E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdateOnlyAddition.xml b/E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdateOnlyAddition.xml new file mode 100644 index 0000000..83b5093 --- /dev/null +++ b/E2Manager/tests/resources/configurationUpdate/e2NodeConfigurationUpdateOnlyAddition.xml @@ -0,0 +1,45 @@ + + + 10 + + + + + + 49 + + + 1234 + + + + 50 + + + + + 51 + + + + + + + nginterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + + + + + + \ No newline at end of file diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction.xml index c8b246c..1a08f45 100644 --- a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction.xml +++ b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction.xml @@ -5,6 +5,13 @@ + + 49 + + + 1234 + + 10 diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction_With_OID.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction_With_OID.xml index 319b681..7bd3631 100644 --- a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction_With_OID.xml +++ b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction_With_OID.xml @@ -5,6 +5,13 @@ + + 49 + + + 1234 + + 10 diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_DeleteFunction.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_DeleteFunction.xml index af0d259..07b93b6 100644 --- a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_DeleteFunction.xml +++ b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_DeleteFunction.xml @@ -5,6 +5,13 @@ + + 49 + + + 1234 + + 11 diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_Empty.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_Empty.xml index 1a7b23b..b52a34c 100644 --- a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_Empty.xml +++ b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_Empty.xml @@ -5,6 +5,13 @@ + + 49 + + + 1234 + + diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_ModifiedFunction.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_ModifiedFunction.xml index 30311e1..9756b37 100644 --- a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_ModifiedFunction.xml +++ b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_ModifiedFunction.xml @@ -5,6 +5,13 @@ + + 49 + + + 1234 + + 12 diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_SetupRequest.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_SetupRequest.xml index d210242..b8f6548 100644 --- a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_SetupRequest.xml +++ b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_SetupRequest.xml @@ -5,6 +5,13 @@ + + 49 + + + 1234 + + 3 diff --git a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_AddedFunction.xml b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_AddedFunction.xml index 1e6caf0..723c1e0 100644 --- a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_AddedFunction.xml +++ b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_AddedFunction.xml @@ -7,6 +7,13 @@ + + 49 + + + 1234 + + 9 diff --git a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_DeleteFunction.xml b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_DeleteFunction.xml index f418f7b..b79b269 100644 --- a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_DeleteFunction.xml +++ b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_DeleteFunction.xml @@ -7,6 +7,13 @@ + + 49 + + + 1234 + + 9 diff --git a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_Empty.xml b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_Empty.xml index 3aaa58a..eec0066 100644 --- a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_Empty.xml +++ b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_Empty.xml @@ -5,6 +5,13 @@ + + 49 + + + 1234 + + diff --git a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_ModifiedFunction.xml b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_ModifiedFunction.xml index f90d78c..e7a883c 100644 --- a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_ModifiedFunction.xml +++ b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_ModifiedFunction.xml @@ -7,6 +7,13 @@ + + 49 + + + 1234 + + 9 diff --git a/E2Manager/tests/resources/setupRequest/setupRequest_en-gNB.xml b/E2Manager/tests/resources/setupRequest/setupRequest_en-gNB.xml index bb2115f..68986af 100644 --- a/E2Manager/tests/resources/setupRequest/setupRequest_en-gNB.xml +++ b/E2Manager/tests/resources/setupRequest/setupRequest_en-gNB.xml @@ -7,6 +7,15 @@ + + 49 + + + + + 1 + + 3 @@ -42,6 +51,7 @@ 1 334455 0 + OID123 @@ -55,12 +65,39 @@ 7 334455 0 + OID123 + + 50 + + + + + 51 + + + + + + + nginterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + diff --git a/E2Manager/tests/resources/setupRequest/setupRequest_enb.xml b/E2Manager/tests/resources/setupRequest/setupRequest_enb.xml index 230e06f..7bab858 100644 --- a/E2Manager/tests/resources/setupRequest/setupRequest_enb.xml +++ b/E2Manager/tests/resources/setupRequest/setupRequest_enb.xml @@ -7,6 +7,15 @@ + + 49 + + + + + 1 + + 3 @@ -63,6 +72,32 @@ + + 50 + + + + + 51 + + + + + + + nginterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + diff --git a/E2Manager/tests/resources/setupRequest/setupRequest_gnb.xml b/E2Manager/tests/resources/setupRequest/setupRequest_gnb.xml index 847df6a..89e7ff2 100644 --- a/E2Manager/tests/resources/setupRequest/setupRequest_gnb.xml +++ b/E2Manager/tests/resources/setupRequest/setupRequest_gnb.xml @@ -7,6 +7,15 @@ + + 49 + + + + + 1 + + 3 @@ -44,6 +53,7 @@ 790280674E422D5832000020312E332E362E312E342E312E32383435382E39392E302E32312E332E332E312E320B80674E42205832204E6574776F726B20496E74657266616365010000010108004D6573736167652054797065206F6E6C7901010001010780436F6D706C657465206D6573736167650101000001058041646454696D657374616D7020010101010001010780436F6D706C657465206D6573736167650101000001058041646454696D657374616D70200101010101010001010780436F6D706C657465206D657373616765010101010101 1 + OID123 @@ -59,6 +69,7 @@ 680300674E422D4E5254000020312E332E362E312E342E312E32383435382E39392E302E32312E332E332E332E330D80674E42204E65696768626F75722052656C6174696F6E205461626C6500010105804E6F74696669636174696F6E01010001010680436F6D706C657465207461626C650101000001058041646454696D657374616D70200101010100010107804E5254206D6F64696669636174696F6E010101010100 1 + OID123 @@ -74,12 +85,39 @@ 450280674E422D5832000020312E332E362E312E342E312E32383435382E39392E302E32312E332E332E312E320B80674E42205832204E6574776F726B20496E74657266616365010100010108004D6573736167652054797065206F6E6C79010100010108004D6573736167652041646D697373696F6E01020400010180514349310002018041525031000301805350494400040300552D5445494431400A05004C6F61645F6F666673657400 1 + OID123 + + 50 + + + + + 51 + + + + + + + nginterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + diff --git a/E2Manager/tests/resources/setupRequest/setupRequest_gnb_with_zero_functions.xml b/E2Manager/tests/resources/setupRequest/setupRequest_gnb_with_zero_functions.xml index 3246799..29f1256 100644 --- a/E2Manager/tests/resources/setupRequest/setupRequest_gnb_with_zero_functions.xml +++ b/E2Manager/tests/resources/setupRequest/setupRequest_gnb_with_zero_functions.xml @@ -7,6 +7,15 @@ + + 49 + + + + + 1 + + 3 @@ -35,6 +44,32 @@ + + 50 + + + + + 51 + + + + + + + nginterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + diff --git a/E2Manager/tests/resources/setupRequest/setupRequest_gnb_without_functions.xml b/E2Manager/tests/resources/setupRequest/setupRequest_gnb_without_functions.xml index db28387..17f8134 100644 --- a/E2Manager/tests/resources/setupRequest/setupRequest_gnb_without_functions.xml +++ b/E2Manager/tests/resources/setupRequest/setupRequest_gnb_without_functions.xml @@ -7,6 +7,15 @@ + + 49 + + + + + 1 + + 3 @@ -27,6 +36,32 @@ + + 50 + + + + + 51 + + + + + + + nginterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + diff --git a/E2Manager/tests/resources/setupRequest/setupRequest_ng-eNB.xml b/E2Manager/tests/resources/setupRequest/setupRequest_ng-eNB.xml index 6bcd1f1..cbcbe80 100644 --- a/E2Manager/tests/resources/setupRequest/setupRequest_ng-eNB.xml +++ b/E2Manager/tests/resources/setupRequest/setupRequest_ng-eNB.xml @@ -7,6 +7,15 @@ + + 49 + + + + + 1 + + 3 @@ -42,6 +51,7 @@ 1 334455 0 + OID123 @@ -55,12 +65,39 @@ 7 334455 0 + OID123 + + 50 + + + + + 51 + + + + + + + nginterf + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + diff --git a/E2Manager/tests/resources/setupRequest/setupRequest_with_oid_gnb.xml b/E2Manager/tests/resources/setupRequest/setupRequest_with_oid_gnb.xml index d5d0bff..918b37f 100644 --- a/E2Manager/tests/resources/setupRequest/setupRequest_with_oid_gnb.xml +++ b/E2Manager/tests/resources/setupRequest/setupRequest_with_oid_gnb.xml @@ -7,6 +7,15 @@ + + 49 + + + + + 1 + + 3 @@ -83,6 +92,50 @@ + + 50 + + + + + 51 + + + + + + + nginterf1 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + 51 + + + + + + + nginterf2 + + + + 72 65 71 70 61 72 74 + 72 65 73 70 61 72 74 + + + + + + + -- 2.16.6