[RIC-249] [RIC-588] US RIC SERVICE UPDATE - Health Check Received | RIC SERVICE UPDAT... 98/4798/3
authorRahul Banerji <r.banerji@samsung.com>
Thu, 1 Oct 2020 11:30:32 +0000 (17:00 +0530)
committerRahul Banerji <r.banerji@samsung.com>
Tue, 13 Oct 2020 06:16:20 +0000 (11:46 +0530)
Change-Id: Ibee3f761cd5cd0051747d71c7e2e91f14279b072
Signed-off-by: Rahul Banerji <r.banerji@samsung.com>
40 files changed:
E2Manager/container-tag.yaml
E2Manager/controllers/nodeb_controller.go
E2Manager/controllers/nodeb_controller_test.go
E2Manager/handlers/httpmsghandlers/health_check_handler.go
E2Manager/handlers/httpmsghandlers/health_check_handler_test.go
E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go
E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go
E2Manager/handlers/rmrmsghandlers/ric_service_update_handler.go [new file with mode: 0644]
E2Manager/handlers/rmrmsghandlers/ric_service_update_handler_test.go [new file with mode: 0644]
E2Manager/httpserver/http_server.go
E2Manager/httpserver/http_server_test.go
E2Manager/managers/ran_list_manager.go
E2Manager/mocks/nodeb_controller_mock.go
E2Manager/mocks/ran_list_manager_mock.go
E2Manager/models/ric_service_update_ack_message.go [new file with mode: 0644]
E2Manager/models/ric_service_update_message.go [new file with mode: 0644]
E2Manager/providers/httpmsghandlerprovider/incoming_request_handler_provider.go
E2Manager/providers/httpmsghandlerprovider/incoming_request_handler_provider_test.go
E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go
E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go
E2Manager/rmrCgo/rmrCgoTypes.go
E2Manager/services/rnib_data_service.go
E2Manager/tests/resources/serviceQuery/RICServiceQuery_Empty.xml [new file with mode: 0644]
E2Manager/tests/resources/serviceQuery/RICServiceQuery_Sample.xml [new file with mode: 0644]
E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction.xml [new file with mode: 0644]
E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_DeleteFunction.xml [new file with mode: 0644]
E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_Empty.xml [new file with mode: 0644]
E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_ModifiedFunction.xml [new file with mode: 0644]
E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_SetupRequest.xml [new file with mode: 0644]
E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_AddedFunction.xml [new file with mode: 0644]
E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_DeleteFunction.xml [new file with mode: 0644]
E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_Empty.xml [new file with mode: 0644]
E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_ModifiedFunction.xml [new file with mode: 0644]
E2Manager/tests/resources/setupRequest/setupRequest_en-gNB.xml [moved from E2Manager/tests/resources/setupRequest_en-gNB.xml with 97% similarity]
E2Manager/tests/resources/setupRequest/setupRequest_enb.xml [moved from E2Manager/tests/resources/setupRequest_enb.xml with 100% similarity]
E2Manager/tests/resources/setupRequest/setupRequest_gnb.xml [moved from E2Manager/tests/resources/setupRequest_gnb.xml with 100% similarity]
E2Manager/tests/resources/setupRequest/setupRequest_gnb_with_zero_functions.xml [moved from E2Manager/tests/resources/setupRequest_gnb_with_zero_functions.xml with 100% similarity]
E2Manager/tests/resources/setupRequest/setupRequest_gnb_without_functions.xml [moved from E2Manager/tests/resources/setupRequest_gnb_without_functions.xml with 100% similarity]
E2Manager/tests/resources/setupRequest/setupRequest_ng-eNB.xml [moved from E2Manager/tests/resources/setupRequest_ng-eNB.xml with 100% similarity]
E2Manager/utils/xml_utils.go [new file with mode: 0644]

index cfda56b..a7a9b1b 100644 (file)
@@ -1,4 +1,4 @@
 # The Jenkins job requires a tag to build the Docker image.
 # Global-JJB script assumes this file is in the repo root.
 ---
-tag: 5.4.10
+tag: 5.4.11
index f2efd65..8ed6cbf 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
index c01d7c9..bfdf270 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
index 718a49b..7399912 100644 (file)
@@ -26,16 +26,15 @@ import (
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
+       "e2mgr/utils"
        "encoding/xml"
-       "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"
-       "strings"
        "unsafe"
 )
 
 var(
-       emptyTagsToReplaceToSelfClosingTags = []string{"reject", "ignore", "protocolIEs"}
+       healthCheckEmptyTagsToReplaceToSelfClosingTags = []string{"reject", "ignore", "protocolIEs", "procedureCode"}
 )
 
 type HealthCheckRequestHandler struct {
@@ -111,7 +110,7 @@ func (h *HealthCheckRequestHandler) sendRICServiceQuery(nodebInfo *entities.Node
                //return nil, e2managererrors.NewInternalError()
        }
 
-       payLoad = replaceEmptyTagsWithSelfClosing(payLoad)
+       payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad,healthCheckEmptyTagsToReplaceToSelfClosingTags)
 
        var xAction []byte
        var msgSrc unsafe.Pointer
@@ -148,19 +147,3 @@ func (h *HealthCheckRequestHandler) getRanNameList(request models.Request) []str
 
        return ranNameList
 }
-
-func replaceEmptyTagsWithSelfClosing(responsePayload []byte) []byte {
-
-       emptyTagVsSelfClosingTagPairs := make([]string, len(emptyTagsToReplaceToSelfClosingTags)*2)
-
-       j := 0
-
-       for i := 0; i < len(emptyTagsToReplaceToSelfClosingTags); i++ {
-               emptyTagVsSelfClosingTagPairs[j] = fmt.Sprintf("<%[1]s></%[1]s>", emptyTagsToReplaceToSelfClosingTags[i])
-               emptyTagVsSelfClosingTagPairs[j+1] = fmt.Sprintf("<%s/>", emptyTagsToReplaceToSelfClosingTags[i])
-               j += 2
-       }
-
-       responseString := strings.NewReplacer(emptyTagVsSelfClosingTagPairs...).Replace(string(responsePayload))
-       return []byte(responseString)
-}
index af21f04..bbd7acd 100644 (file)
@@ -26,13 +26,12 @@ import (
        "e2mgr/models"
        "e2mgr/rmrCgo"
        "e2mgr/services"
+       "e2mgr/utils"
        "encoding/xml"
        "errors"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
-       "io/ioutil"
-       "path/filepath"
        "strings"
        "testing"
        "unsafe"
@@ -41,7 +40,7 @@ import (
 const (
        e2tInstanceFullAddress                   = "10.0.2.15:9999"
        e2SetupMsgPrefix                         = e2tInstanceFullAddress + "|"
-       GnbSetupRequestXmlPath                   = "../../tests/resources/setupRequest_gnb.xml"
+       GnbSetupRequestXmlPath                   = "../../tests/resources/setupRequest/setupRequest_gnb.xml"
 )
 
 func setupHealthCheckHandlerTest(t *testing.T) (*HealthCheckRequestHandler, services.RNibDataService, *mocks.RnibReaderMock, *mocks.RanListManagerMock, *mocks.RmrMessengerMock) {
@@ -150,7 +149,9 @@ func TestHealthCheckRequestHandlerArguementHasRanNameDBErrorFailure(t *testing.T
 func createRMRMbuf(t *testing.T, nodebInfo *entities.NodebInfo) *rmrCgo.MBuf{
        serviceQuery := models.NewRicServiceQueryMessage(nodebInfo.GetGnb().RanFunctions)
        payLoad, err := xml.Marshal(&serviceQuery.E2APPDU)
-       payLoad = normalizeXml(payLoad)
+       payLoad = utils.NormalizeXml(payLoad)
+       tagsToReplace := []string{"reject","ignore","protocolIEs"}
+       payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, tagsToReplace)
 
        if err != nil {
                t.Fatal(err)
@@ -164,11 +165,11 @@ func createRMRMbuf(t *testing.T, nodebInfo *entities.NodebInfo) *rmrCgo.MBuf{
 }
 
 func createNbIdentity(t *testing.T, RanName string,  connectionStatus entities.ConnectionStatus) *entities.NodebInfo {
-       xmlgnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlgnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        payload := append([]byte(e2SetupMsgPrefix), xmlgnb...)
        pipInd := bytes.IndexByte(payload, '|')
        setupRequest := &models.E2SetupRequestMessage{}
-       err := xml.Unmarshal(normalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
+       err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
        if err != nil {
                t.Fatal(err)
        }
@@ -200,16 +201,3 @@ func normalizeXml(payload []byte) []byte {
                "<protocolIEs></protocolIEs>","<protocolIEs/>").Replace(xmlStr)
        return []byte(normalized)
 }
-
-func readXmlFile(t *testing.T, xmlPath string) []byte {
-       path, err := filepath.Abs(xmlPath)
-       if err != nil {
-               t.Fatal(err)
-       }
-       xmlAsBytes, err := ioutil.ReadFile(path)
-       if err != nil {
-               t.Fatal(err)
-       }
-
-       return xmlAsBytes
-}
index a6888d9..b2e1633 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
@@ -29,6 +30,7 @@ import (
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
+       "e2mgr/utils"
        "encoding/xml"
        "errors"
        "fmt"
@@ -241,7 +243,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 = replaceEmptyTagsWithSelfClosing(responsePayload)
+       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())
@@ -266,7 +268,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 = replaceEmptyTagsWithSelfClosing(responsePayload)
+       responsePayload = utils.ReplaceEmptyTagsWithSelfClosing(responsePayload,emptyTagsToReplaceToSelfClosingTags)
 
        h.logger.Infof("#E2SetupRequestNotificationHandler.handleSuccessfulResponse - payload: %s", responsePayload)
 
@@ -292,21 +294,6 @@ func buildPlmnId(mmc string, mnc string) string {
        return b.String()
 }
 
-func replaceEmptyTagsWithSelfClosing(responsePayload []byte) []byte {
-
-       emptyTagVsSelfClosingTagPairs := make([]string, len(emptyTagsToReplaceToSelfClosingTags)*2)
-
-       j := 0
-
-       for i := 0; i < len(emptyTagsToReplaceToSelfClosingTags); i++ {
-               emptyTagVsSelfClosingTagPairs[j] = fmt.Sprintf("<%[1]s></%[1]s>", emptyTagsToReplaceToSelfClosingTags[i])
-               emptyTagVsSelfClosingTagPairs[j+1] = fmt.Sprintf("<%s/>", emptyTagsToReplaceToSelfClosingTags[i])
-               j += 2
-       }
-       responseString := strings.NewReplacer(emptyTagVsSelfClosingTagPairs...).Replace(string(responsePayload))
-       return []byte(responseString)
-}
-
 func convertTo20BitString(ricNearRtId string) (string, error) {
        r, err := strconv.ParseUint(ricNearRtId, 16, 32)
        if err != nil {
@@ -330,7 +317,7 @@ func (h *E2SetupRequestNotificationHandler) parseSetupRequest(payload []byte) (*
        h.logger.Infof("#E2SetupRequestNotificationHandler.parseSetupRequest - payload: %s", payload[pipInd+1:])
 
        setupRequest := &models.E2SetupRequestMessage{}
-       err := xml.Unmarshal(normalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
+       err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
        if err != nil {
                return nil, "", errors.New(fmt.Sprintf("#E2SetupRequestNotificationHandler.parseSetupRequest - Error unmarshalling E2 Setup Request payload: %x", payload))
        }
@@ -338,12 +325,6 @@ func (h *E2SetupRequestNotificationHandler) parseSetupRequest(payload []byte) (*
        return setupRequest, e2tIpAddress, nil
 }
 
-func normalizeXml(payload []byte) []byte {
-       xmlStr := string(payload)
-       normalized := strings.NewReplacer("&lt;", "<", "&gt;", ">").Replace(xmlStr)
-       return []byte(normalized)
-}
-
 func (h *E2SetupRequestNotificationHandler) buildNodebInfo(ranName string, e2tAddress string, request *models.E2SetupRequestMessage) (*entities.NodebInfo, error) {
        nodebInfo := &entities.NodebInfo{
                AssociatedE2TInstanceAddress: e2tAddress,
index 0d58a3b..d3a7ae2 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
@@ -28,14 +29,13 @@ import (
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/tests"
+       "e2mgr/utils"
        "encoding/xml"
        "errors"
        "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"
-       "io/ioutil"
-       "path/filepath"
        "testing"
 )
 
@@ -44,12 +44,12 @@ const (
        e2SetupMsgPrefix                         = e2tInstanceFullAddress + "|"
        gnbNodebRanName                          = "gnb:310-410-b5c67788"
        enbNodebRanName                          = "enB_macro:P310-410-b5c67788"
-       GnbSetupRequestXmlPath                   = "../../tests/resources/setupRequest_gnb.xml"
-       GnbWithZeroFunctionsSetupRequestXmlPath  = "../../tests/resources/setupRequest_gnb_with_zero_functions.xml"
-       EnGnbSetupRequestXmlPath                 = "../../tests/resources/setupRequest_en-gNB.xml"
-       NgEnbSetupRequestXmlPath                 = "../../tests/resources/setupRequest_ng-eNB.xml"
-       EnbSetupRequestXmlPath                   = "../../tests/resources/setupRequest_enb.xml"
-       GnbWithoutFunctionsSetupRequestXmlPath   = "../../tests/resources/setupRequest_gnb_without_functions.xml"
+       GnbSetupRequestXmlPath                   = "../../tests/resources/setupRequest/setupRequest_gnb.xml"
+       GnbWithZeroFunctionsSetupRequestXmlPath  = "../../tests/resources/setupRequest/setupRequest_gnb_with_zero_functions.xml"
+       EnGnbSetupRequestXmlPath                 = "../../tests/resources/setupRequest/setupRequest_en-gNB.xml"
+       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      = "<E2AP-PDU><unsuccessfulOutcome><procedureCode>1</procedureCode><criticality><reject/></criticality><value><E2setupFailure><protocolIEs><E2setupFailureIEs><id>1</id><criticality><ignore/></criticality><value><Cause><misc><om-intervention/></misc></Cause></value></E2setupFailureIEs><E2setupFailureIEs><id>31</id><criticality><ignore/></criticality><value><TimeToWait><v60s/></TimeToWait></value></E2setupFailureIEs></protocolIEs></E2setupFailure></value></unsuccessfulOutcome></E2AP-PDU>"
        E2SetupFailureResponseWithTransportCause = "<E2AP-PDU><unsuccessfulOutcome><procedureCode>1</procedureCode><criticality><reject/></criticality><value><E2setupFailure><protocolIEs><E2setupFailureIEs><id>1</id><criticality><ignore/></criticality><value><Cause><transport><transport-resource-unavailable/></transport></Cause></value></E2setupFailureIEs><E2setupFailureIEs><id>31</id><criticality><ignore/></criticality><value><TimeToWait><v60s/></TimeToWait></value></E2setupFailureIEs></protocolIEs></E2setupFailure></value></unsuccessfulOutcome></E2AP-PDU>"
        E2SetupFailureResponseWithRicCause       = "<E2AP-PDU><unsuccessfulOutcome><procedureCode>1</procedureCode><criticality><reject/></criticality><value><E2setupFailure><protocolIEs><E2setupFailureIEs><id>1</id><criticality><ignore/></criticality><value><Cause><ricRequest><request-id-unknown/></ricRequest></Cause></value></E2setupFailureIEs><E2setupFailureIEs><id>31</id><criticality><ignore/></criticality><value><TimeToWait><v60s/></TimeToWait></value></E2setupFailureIEs></protocolIEs></E2setupFailure></value></unsuccessfulOutcome></E2AP-PDU>"
@@ -90,21 +90,8 @@ func getMbuf(ranName string, msgType int, payloadStr string, request *models.Not
        return mbuf
 }
 
-func readXmlFile(t *testing.T, xmlPath string) []byte {
-       path, err := filepath.Abs(xmlPath)
-       if err != nil {
-               t.Fatal(err)
-       }
-       xmlAsBytes, err := ioutil.ReadFile(path)
-       if err != nil {
-               t.Fatal(err)
-       }
-
-       return xmlAsBytes
-}
-
 func TestParseGnbSetupRequest_Success(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, _, _, _, _, _, _ := initMocks(t)
        prefBytes := []byte(e2SetupMsgPrefix)
        request, _, err := handler.parseSetupRequest(append(prefBytes, xmlGnb...))
@@ -114,7 +101,7 @@ func TestParseGnbSetupRequest_Success(t *testing.T) {
 }
 
 func TestParseEnGnbSetupRequest_Success(t *testing.T) {
-       enGnbXml := readXmlFile(t, EnGnbSetupRequestXmlPath)
+       enGnbXml := utils.ReadXmlFile(t, EnGnbSetupRequestXmlPath)
        handler, _, _, _, _, _, _ := initMocks(t)
        prefBytes := []byte(e2SetupMsgPrefix)
        request, _, err := handler.parseSetupRequest(append(prefBytes, enGnbXml...))
@@ -124,7 +111,7 @@ func TestParseEnGnbSetupRequest_Success(t *testing.T) {
 }
 
 func TestParseNgEnbSetupRequest_Success(t *testing.T) {
-       ngEnbXml := readXmlFile(t, NgEnbSetupRequestXmlPath)
+       ngEnbXml := utils.ReadXmlFile(t, NgEnbSetupRequestXmlPath)
        handler, _, _, _, _, _, _ := initMocks(t)
        prefBytes := []byte(e2SetupMsgPrefix)
        request, _, err := handler.parseSetupRequest(append(prefBytes, ngEnbXml...))
@@ -134,7 +121,7 @@ func TestParseNgEnbSetupRequest_Success(t *testing.T) {
 }
 
 func TestParseEnbSetupRequest_Success(t *testing.T) {
-       enbXml := readXmlFile(t, EnbSetupRequestXmlPath)
+       enbXml := utils.ReadXmlFile(t, EnbSetupRequestXmlPath)
        handler, _, _, _, _, _, _ := initMocks(t)
        prefBytes := []byte(e2SetupMsgPrefix)
        request, _, err := handler.parseSetupRequest(append(prefBytes, enbXml...))
@@ -144,7 +131,7 @@ func TestParseEnbSetupRequest_Success(t *testing.T) {
 }
 
 func TestParseSetupRequest_PipFailure(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, _, _, _, _, _, _ := initMocks(t)
        prefBytes := []byte("10.0.2.15:9999")
        request, _, err := handler.parseSetupRequest(append(prefBytes, xmlGnb...))
@@ -163,7 +150,7 @@ func TestParseSetupRequest_UnmarshalFailure(t *testing.T) {
 }
 
 func TestE2SetupRequestNotificationHandler_HandleParseError(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, _ := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil)
        notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte("invalid_prefix"), xmlGnb...)}
@@ -190,7 +177,7 @@ func TestE2SetupRequestNotificationHandler_HandleUnmarshalError(t *testing.T) {
 }
 
 func TestE2SetupRequestNotificationHandler_ConvertTo20BitStringError(t *testing.T) {
-       xmlEnGnb := readXmlFile(t, EnGnbSetupRequestXmlPath)
+       xmlEnGnb := utils.ReadXmlFile(t, EnGnbSetupRequestXmlPath)
        logger := tests.InitLog(t)
        config := &configuration.Configuration{
                RnibRetryIntervalMs:       10,
@@ -259,7 +246,7 @@ func TestExtractionOfNodeTypeFromRanName(t *testing.T) {
 }
 
 func TestE2SetupRequestNotificationHandler_GetGeneralConfigurationFailure(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, _ := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{}, common.NewInternalError(errors.New("some error")))
        notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)}
@@ -272,7 +259,7 @@ func TestE2SetupRequestNotificationHandler_GetGeneralConfigurationFailure(t *tes
 }
 
 func TestE2SetupRequestNotificationHandler_EnableRicFalse(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, _ := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: false}, nil)
        notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)}
@@ -287,7 +274,7 @@ func TestE2SetupRequestNotificationHandler_EnableRicFalse(t *testing.T) {
 }
 
 func TestE2SetupRequestNotificationHandler_HandleGetE2TInstanceError(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, _ := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil)
        e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, common.NewResourceNotFoundError("Not found"))
@@ -304,7 +291,7 @@ func TestE2SetupRequestNotificationHandler_HandleGetE2TInstanceError(t *testing.
 }
 
 func TestE2SetupRequestNotificationHandler_HandleGetNodebError(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, readerMock, writerMock, routingManagerClientMock, e2tInstancesManagerMock, rmrMessengerMock, _ := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil)
        e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil)
@@ -324,7 +311,7 @@ func TestE2SetupRequestNotificationHandler_HandleGetNodebError(t *testing.T) {
 /* New Ran UTs - BEGIN */
 
 func TestE2SetupRequestNotificationHandler_HandleNewRanSaveNodebFailure(t *testing.T) {
-       xml := readXmlFile(t, GnbSetupRequestXmlPath)
+       xml := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, readerMock, writerMock, _, e2tInstancesManagerMock, _, _ := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil)
        e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil)
@@ -341,7 +328,7 @@ func TestE2SetupRequestNotificationHandler_HandleNewRanSaveNodebFailure(t *testi
 }
 
 func TestE2SetupRequestNotificationHandler_HandleNewRan_invalidRanName(t *testing.T) {
-       xml := readXmlFile(t, EnbSetupRequestXmlPath)
+       xml := utils.ReadXmlFile(t, EnbSetupRequestXmlPath)
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _, _ := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil)
        e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil)
@@ -360,7 +347,7 @@ func TestE2SetupRequestNotificationHandler_HandleNewRan_invalidRanName(t *testin
 }
 
 func TestE2SetupRequestNotificationHandler_HandleNewRanAddNbIdentityFailure(t *testing.T) {
-       xml := readXmlFile(t, GnbSetupRequestXmlPath)
+       xml := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, readerMock, writerMock, _, e2tInstancesManagerMock, _, _ := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil)
        e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil)
@@ -378,7 +365,7 @@ func TestE2SetupRequestNotificationHandler_HandleNewRanAddNbIdentityFailure(t *t
 }
 
 func TestE2SetupRequestNotificationHandler_HandleNewRanRoutingManagerError(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
 
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, _ := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil)
@@ -407,7 +394,7 @@ func TestE2SetupRequestNotificationHandler_HandleNewRanRoutingManagerError(t *te
 }
 
 func testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t *testing.T, xmlPath string, nodeType entities.Node_Type) {
-       xml := readXmlFile(t, xmlPath)
+       xml := utils.ReadXmlFile(t, xmlPath)
        var ranName string
        if nodeType == entities.Node_GNB {
                ranName = gnbNodebRanName
@@ -470,7 +457,7 @@ func TestE2SetupRequestNotificationHandler_HandleNewNgEnbSuccess(t *testing.T) {
 func getExpectedGnbNodebForNewRan(payload []byte) *entities.NodebInfo {
        pipInd := bytes.IndexByte(payload, '|')
        setupRequest := &models.E2SetupRequestMessage{}
-       _ = xml.Unmarshal(normalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
+       _ = xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
 
        nodeb := &entities.NodebInfo{
                AssociatedE2TInstanceAddress: e2tInstanceFullAddress,
@@ -495,7 +482,7 @@ func getExpectedGnbNodebForNewRan(payload []byte) *entities.NodebInfo {
 func getExpectedEnbNodebForNewRan(payload []byte) *entities.NodebInfo {
        pipInd := bytes.IndexByte(payload, '|')
        setupRequest := &models.E2SetupRequestMessage{}
-       _ = xml.Unmarshal(normalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
+       _ = xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
 
        nodeb := &entities.NodebInfo{
                AssociatedE2TInstanceAddress: e2tInstanceFullAddress,
@@ -523,7 +510,7 @@ func getExpectedEnbNodebForNewRan(payload []byte) *entities.NodebInfo {
 func getExpectedNodebForExistingRan(nodeb *entities.NodebInfo, payload []byte) *entities.NodebInfo {
        pipInd := bytes.IndexByte(payload, '|')
        setupRequest := &models.E2SetupRequestMessage{}
-       _ = xml.Unmarshal(normalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
+       _ = xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
 
        nb := *nodeb
 
@@ -541,7 +528,7 @@ func getExpectedNodebForExistingRan(nodeb *entities.NodebInfo, payload []byte) *
 }
 
 func TestE2SetupRequestNotificationHandler_HandleExistingConnectedEnbSuccess(t *testing.T) {
-       xmlEnb := readXmlFile(t, EnbSetupRequestXmlPath)
+       xmlEnb := utils.ReadXmlFile(t, EnbSetupRequestXmlPath)
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, ranListManager := initMocks(t)
 
        oldNbIdentity := &entities.NbIdentity{InventoryName: enbNodebRanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}}
@@ -581,7 +568,7 @@ func TestE2SetupRequestNotificationHandler_HandleExistingConnectedEnbSuccess(t *
 }
 
 func TestE2SetupRequestNotificationHandler_HandleExistingDisconnectedEnbSuccess(t *testing.T) {
-       xmlEnb := readXmlFile(t, EnbSetupRequestXmlPath)
+       xmlEnb := utils.ReadXmlFile(t, EnbSetupRequestXmlPath)
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, ranListManager := initMocks(t)
 
        oldNbIdentity := &entities.NbIdentity{InventoryName: enbNodebRanName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}}
@@ -631,7 +618,7 @@ func TestE2SetupRequestNotificationHandler_HandleExistingDisconnectedEnbSuccess(
 }
 
 func testE2SetupRequestNotificationHandler_HandleExistingConnectedGnbSuccess(t *testing.T, withFunctions bool, xmlToRead string) {
-       xmlGnb := readXmlFile(t, xmlToRead)
+       xmlGnb := utils.ReadXmlFile(t, xmlToRead)
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, ranListManager := initMocks(t)
 
        oldNbIdentity := &entities.NbIdentity{InventoryName: gnbNodebRanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}}
@@ -680,7 +667,7 @@ func testE2SetupRequestNotificationHandler_HandleExistingConnectedGnbSuccess(t *
 }
 
 func TestE2SetupRequestNotificationHandler_HandleExistingConnectedGnbRoutingManagerError(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, ranListManager := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil)
        e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil)
@@ -724,7 +711,7 @@ func TestE2SetupRequestNotificationHandler_HandleExistingConnectedGnbRoutingMana
 }
 
 func TestE2SetupRequestNotificationHandler_HandleExistingGnbInvalidConnectionStatusError(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, readerMock, writerMock, _, e2tInstancesManagerMock, rmrMessengerMock, _ := initMocks(t)
        var gnb = &entities.NodebInfo{RanName: gnbNodebRanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN}
        readerMock.On("GetNodeb", gnbNodebRanName).Return(gnb, nil)
@@ -752,7 +739,7 @@ func TestE2SetupRequestNotificationHandler_HandleExistingConnectedGnbWithZeroFun
 }
 
 func TestE2SetupRequestNotificationHandler_HandleExistingDisconnectedGnbSuccess(t *testing.T) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       xmlGnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, ranListManager := initMocks(t)
        oldNbIdentity := &entities.NbIdentity{InventoryName: gnbNodebRanName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}}
        readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{oldNbIdentity}, nil)
diff --git a/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler.go b/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler.go
new file mode 100644 (file)
index 0000000..ccce4a8
--- /dev/null
@@ -0,0 +1,247 @@
+//
+// Copyright (c) 2020 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 (
+       "bytes"
+       "e2mgr/utils"
+       "e2mgr/logger"
+       "e2mgr/managers"
+       "e2mgr/models"
+       "e2mgr/rmrCgo"
+       "e2mgr/services"
+       "e2mgr/services/rmrsender"
+       "encoding/xml"
+       "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"
+)
+
+//type FunctionChange int
+
+const (
+       RAN_FUNCTIONS_ADDED int = 10 + iota
+       RAN_FUNCTIONS_DELETED
+       RAN_FUNCTIONS_MODIFIED
+)
+
+type functionDetails struct {
+       functionChange       int
+       functionId           uint32
+       functionDefinition   string
+       functionRevision     uint32
+}
+
+type RicServiceUpdateHandler struct {
+       logger                *logger.Logger
+    rmrSender             *rmrsender.RmrSender
+       rNibDataService       services.RNibDataService
+       ranListManager        managers.RanListManager
+}
+
+func NewRicServiceUpdateHandler(logger *logger.Logger, rmrSender *rmrsender.RmrSender, rNibDataService services.RNibDataService, ranListManager managers.RanListManager) *RicServiceUpdateHandler {
+       return &RicServiceUpdateHandler {
+                logger:                logger,
+                rmrSender:             rmrSender,
+                rNibDataService:       rNibDataService,
+                               ranListManager:            ranListManager,
+        }
+}
+
+func (h *RicServiceUpdateHandler) Handle(request *models.NotificationRequest) {
+       ranName := request.RanName
+       h.logger.Infof("#RicServiceUpdateHandler.Handle - RAN name: %s - received RIC_SERVICE_UPDATE. Payload: %s", ranName, request.Payload)
+
+       nodebInfo, err := h.rNibDataService.GetNodeb(ranName)
+        if err != nil {
+                _, ok := err.(*common.ResourceNotFoundError)
+               if !ok {
+                       h.logger.Errorf("#RicServiceUpdateHandler.Handle - failed to get nodeB entity for ran name: %v due to RNIB Error: %s", ranName, err)
+               } else{
+                        h.logger.Errorf("#RicServiceUpdateHandler.Handle - nobeB entity of RanName:%s absent in RNIB. Error: %s", ranName, err)
+                }
+                return
+       }
+
+       ricServiceUpdate, err := h.parseSetupRequest(request.Payload)
+       if err != nil {
+               h.logger.Errorf(err.Error())
+               return
+       }
+       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 {
+               err = h.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
+               if err != nil {
+                       h.logger.Errorf("#RicServiceUpdateHandler.Handle - RAN name: %s - Failed at UpdateNodebInfoAndPublish. error: %s", nodebInfo.RanName, err)
+                       return
+               }
+       }
+
+       oldNbIdentity, newNbIdentity := h.ranListManager.UpdateHealthcheckTimeStampReceived(nodebInfo.RanName)
+       err = h.ranListManager.UpdateNbIdentities(nodebInfo.NodeType, []*entities.NbIdentity{oldNbIdentity}, []*entities.NbIdentity{newNbIdentity})
+       if err != nil {
+               h.logger.Errorf("#RicServiceUpdate.Handle - failed to Update NbIdentities: %s", err)
+               return
+       }
+
+       updateAck := models.NewServiceUpdateAck(ackFunctionIds)
+       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)
+               return
+       }
+
+       h.logger.Infof("#RicServiceUpdate.Handle - Completed successfully")
+}
+
+func (h *RicServiceUpdateHandler) sendUpdateAck(updateAck models.RicServiceUpdateAckE2APPDU, nodebInfo *entities.NodebInfo, request *models.NotificationRequest) error {
+       payLoad, err := xml.Marshal(updateAck)
+       if err != nil {
+               h.logger.Errorf("#RicServiceUpdate.sendUpdateAck - RAN name: %s - Error marshalling RIC_SERVICE_UPDATE_ACK. Payload: %s", nodebInfo.RanName, payLoad)
+       }
+
+       toReplaceTags := []string{"reject", "ignore", "procedureCode", "id", "RANfunctionID-Item", "RANfunctionsID-List"}
+       payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad,toReplaceTags)
+
+       h.logger.Infof("#RicServiceUpdate.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 = h.rmrSender.Send(msg)
+       return err
+}
+
+func (h *RicServiceUpdateHandler) updateFunctions(RICServiceUpdateIEs []models.RICServiceUpdateIEs,nodebInfo *entities.NodebInfo) []models.RicServiceAckRANFunctionIDItem {
+       ranFunctions := nodebInfo.GetGnb().RanFunctions
+       RanFIdtoIdxMap := make(map[uint32]int)
+       var acceptedFunctionIds []models.RicServiceAckRANFunctionIDItem
+       functionsToBeDeleted := make(map[int]bool)
+
+       for index, ranFunction := range ranFunctions {
+               RanFIdtoIdxMap[ranFunction.RanFunctionId] = index
+       }
+
+       for _, ricServiceUpdateIE := range RICServiceUpdateIEs {
+               functionDetails, err := h.getFunctionDetails(ricServiceUpdateIE)
+               if err != nil {
+                       h.logger.Errorf("#RicServiceUpdate.updateFunctions- GetFunctionDetails returned err: %s", err)
+               }
+
+               for _, functionDetail := range functionDetails {
+                       functionChange, functionId, functionDefinition, functionRevision := functionDetail.functionChange,
+                       functionDetail.functionId, functionDetail.functionDefinition, functionDetail.functionRevision
+                       ranFIndex, ok := RanFIdtoIdxMap[functionId]
+                       if !ok {
+                               switch functionChange {
+                               case RAN_FUNCTIONS_ADDED,RAN_FUNCTIONS_MODIFIED :
+                                       ranFunctions = append(ranFunctions, &entities.RanFunction{RanFunctionId:functionId,
+                                               RanFunctionDefinition:functionDefinition, RanFunctionRevision:functionRevision})
+                               case RAN_FUNCTIONS_DELETED:
+                                       //Do nothing
+                               }
+                       } else {
+                               switch functionChange {
+                               case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
+                                       ranFunctions[ranFIndex].RanFunctionDefinition = functionDefinition
+                                       ranFunctions[ranFIndex].RanFunctionRevision = functionRevision
+                               case RAN_FUNCTIONS_DELETED:
+                                       functionsToBeDeleted[ranFIndex] = true
+                               }
+                       }
+                       serviceupdateAckFunctionId := models.RicServiceAckRANFunctionIDItem{RanFunctionID:functionId, RanFunctionRevision:functionRevision}
+                       acceptedFunctionIds = append(acceptedFunctionIds, serviceupdateAckFunctionId)
+               }
+       }
+       finalranFunctions := h.remove(ranFunctions, functionsToBeDeleted)
+       nodebInfo.GetGnb().RanFunctions = finalranFunctions
+       return acceptedFunctionIds
+}
+
+func (h *RicServiceUpdateHandler) remove(ranFunctions []*entities.RanFunction, functionsToBeDeleted map[int]bool) []*entities.RanFunction {
+       if len(functionsToBeDeleted) == 0 {
+               return ranFunctions
+       }
+       var finalranFunctions []*entities.RanFunction
+       for i := 0; i < len(ranFunctions); i++ {
+               _, ok := functionsToBeDeleted[i]
+               if !ok {
+                       finalranFunctions = append(finalranFunctions, ranFunctions[i])
+               }
+       }
+       return finalranFunctions
+}
+
+func (h *RicServiceUpdateHandler) getFunctionDetails(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails , error) {
+       functionChange := ricServiceUpdateIE.ID
+       switch functionChange{
+               case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
+                       return h.getFunctionsAddedModifiedHandler(ricServiceUpdateIE)
+               case RAN_FUNCTIONS_DELETED:
+                       return h.getFunctionsDeleteHandler(ricServiceUpdateIE)
+               default:
+                       return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - Unknown change type %v", functionChange))
+       }
+       return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - Internal Error"))
+}
+
+func (h *RicServiceUpdateHandler) getFunctionsAddedModifiedHandler(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails , error){
+       functionChange := ricServiceUpdateIE.ID
+       ranFunctionsIEList := ricServiceUpdateIE.Value.RANfunctionsList.RANfunctionsItemProtocolIESingleContainer
+       if len(ranFunctionsIEList) ==0 {
+               return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - function change type is %v but Functions list is empty", functionChange))
+       }
+
+       functionDetailsList := make([]functionDetails, len(ranFunctionsIEList))
+       for index, ranFunctionIE := range ranFunctionsIEList {
+               ranFunction := ranFunctionIE.Value.RANfunctionItem
+               functionDetailsList[index] = functionDetails{functionChange:functionChange, functionId:ranFunction.RanFunctionID,
+                       functionDefinition:ranFunction.RanFunctionDefinition, functionRevision:ranFunction.RanFunctionRevision}
+       }
+       return functionDetailsList, nil
+}
+
+func (h *RicServiceUpdateHandler) getFunctionsDeleteHandler(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails , error){
+       functionChange := ricServiceUpdateIE.ID
+       ranFunctionIdIEsList := ricServiceUpdateIE.Value.RANfunctionsIDList.RANfunctionsItemIDProtocolIESingleContainer
+       if len(ranFunctionIdIEsList) == 0 {
+               return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - function change type is %v but FunctionIds list is empty", functionChange))
+       }
+
+       functionDetailsList := make([]functionDetails, len(ranFunctionIdIEsList))
+       for index, ranFunctionIdIE := range ranFunctionIdIEsList {
+               ranFunctionId := ranFunctionIdIE.Value.RANfunctionIDItem
+               functionDetailsList[index] = functionDetails{functionChange:functionChange, functionId:ranFunctionId.RanFunctionID,
+                       functionDefinition:"", functionRevision:ranFunctionId.RanFunctionRevision}
+       }
+       return functionDetailsList, nil
+}
+
+func (h *RicServiceUpdateHandler) parseSetupRequest(payload []byte) (*models.RICServiceUpdateMessage, error) {
+        pipInd := bytes.IndexByte(payload, '|')
+        if pipInd < 0 {
+                return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdateHandler.parseSetupRequest - Error parsing RIC SERVICE UPDATE failed extract Payload: no | separator found"))
+        }
+
+        ricServiceUpdate := &models.RICServiceUpdateMessage{}
+        err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &ricServiceUpdate.E2APPDU)
+        if err != nil {
+                return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdateHandler.parseSetupRequest - Error unmarshalling RIC SERVICE UPDATE payload: %x", payload))
+        }
+        return ricServiceUpdate, nil
+}
diff --git a/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler_test.go b/E2Manager/handlers/rmrmsghandlers/ric_service_update_handler_test.go
new file mode 100644 (file)
index 0000000..372bf05
--- /dev/null
@@ -0,0 +1,289 @@
+//
+// Copyright (c) 2020 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 (
+       "bytes"
+       "e2mgr/configuration"
+       "e2mgr/mocks"
+       "e2mgr/models"
+       "e2mgr/rmrCgo"
+       "e2mgr/services"
+       "e2mgr/tests"
+       "e2mgr/utils"
+       "encoding/xml"
+       "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"
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/mock"
+       "testing"
+)
+
+const (
+       serviceUpdateE2tInstanceAddress = "10.0.0.27:9999"
+       serviceUpdateE2SetupMsgPrefix   = serviceUpdateE2tInstanceAddress + "|"
+       serviceUpdateRANName            = "gnb:TestRan"
+       RanManipulationMessageChannel   = "RAN_MANIPULATION"
+       RICServiceUpdate_E2SetupReqPath = "../../tests/resources/serviceUpdate/RicServiceUpdate_SetupRequest.xml"
+       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"
+       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"
+)
+
+func initRicServiceUpdateHandler(t *testing.T) (*RicServiceUpdateHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.RanListManagerMock) {
+       logger := tests.InitLog(t)
+       config := &configuration.Configuration{
+               RnibRetryIntervalMs:       10,
+               MaxRnibConnectionAttempts: 3,
+               RnibWriter: configuration.RnibWriterConfig{
+                       StateChangeMessageChannel: StateChangeMessageChannel,
+                       RanManipulationMessageChannel: RanManipulationMessageChannel,
+               },
+               GlobalRicId: struct {
+                       RicId string
+                       Mcc   string
+                       Mnc   string
+               }{
+                       Mcc: "337",
+                       Mnc: "94",
+                       RicId: "AACCE",
+               }}
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
+       rmrSender := tests.InitRmrSender(rmrMessengerMock, logger)
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+       ranListManagerMock := &mocks.RanListManagerMock{}
+       handler := NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManagerMock)
+       return handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock
+}
+
+
+func TestRICServiceUpdateModifiedFuncSuccess(t *testing.T){
+       testServiceUpdateSuccess(t, RicServiceUpdateModifiedPath, RicServiceUpdateAckModifiedPath)
+}
+
+func TestRICServiceUpdateAddedFuncSuccess(t *testing.T){
+
+       testServiceUpdateSuccess(t, RicServiceUpdateAddedPath, RicServiceUpdateAckAddedPath)
+}
+
+func TestRICServiceUpdateDeleteFuncSuccess(t *testing.T){
+       testServiceUpdateSuccess(t, RicServiceUpdateDeletePath, RicServiceUpdateAckDeletePath)
+}
+
+func TestRICServiceUpdateEmptySuccess(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.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...)}
+
+       handler.Handle(notificationRequest)
+       writerMock.AssertExpectations(t)
+       rmrMessengerMock.AssertNotCalled(t, "SendMsg", mock.Anything, mock.Anything)
+       readerMock.AssertExpectations(t)
+       ranListManagerMock.AssertExpectations(t)
+}
+
+func TestRICServiceUpdateRnibNotFound(t *testing.T){
+       handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t)
+       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...)}
+
+       handler.Handle(notificationRequest)
+       writerMock.AssertExpectations(t)
+       rmrMessengerMock.AssertNotCalled(t, "SendMsg", mock.Anything, mock.Anything)
+       readerMock.AssertExpectations(t)
+       ranListManagerMock.AssertExpectations(t)
+}
+
+func TestRICServiceUpdateNodeBInfoFailure(t *testing.T){
+       handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t)
+       xmlserviceUpdate  := utils.ReadXmlFile(t, RicServiceUpdateDeletePath)
+       xmlserviceUpdate = utils.CleanXML(xmlserviceUpdate)
+       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")))
+
+       handler.Handle(notificationRequest)
+       writerMock.AssertExpectations(t)
+       rmrMessengerMock.AssertNotCalled(t, "SendMsg", mock.Anything, mock.Anything)
+       readerMock.AssertExpectations(t)
+       ranListManagerMock.AssertExpectations(t)
+}
+
+func TestSendRICServiceUpdateAckFailure(t *testing.T){
+       handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t)
+       xmlserviceUpdate  := utils.ReadXmlFile(t, RicServiceUpdateModifiedPath)
+       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,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)
+
+       handler.Handle(notificationRequest)
+       writerMock.AssertExpectations(t)
+       rmrMessengerMock.AssertNumberOfCalls(t,"SendMsg", 1)
+       readerMock.AssertExpectations(t)
+       ranListManagerMock.AssertExpectations(t)
+}
+
+func TestRICServiceUpdateUpdateNbIdentitiesFailure(t *testing.T){
+       handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t)
+       xmlserviceUpdate  := utils.ReadXmlFile(t, RicServiceUpdateDeletePath)
+       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...)}
+       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)
+       readerMock.AssertExpectations(t)
+       ranListManagerMock.AssertExpectations(t)
+}
+
+func TestRICServiceUpdateParseRequest_PipFailure(t *testing.T) {
+       xmlGnb := utils.ReadXmlFile(t, RICServiceUpdate_E2SetupReqPath)
+       handler, _, _, _, _:= initRicServiceUpdateHandler(t)
+       prefBytes := []byte(serviceUpdateE2tInstanceAddress)
+       ricServiceUpdate, err := handler.parseSetupRequest(append(prefBytes, xmlGnb...))
+       assert.Nil(t, ricServiceUpdate)
+       assert.NotNil(t, err)
+       assert.EqualError(t, err, "#RicServiceUpdateHandler.parseSetupRequest - Error parsing RIC SERVICE UPDATE failed extract Payload: no | separator found")
+}
+
+func TestRICServiceUppdateParseRequest_UnmarshalFailure(t *testing.T) {
+       handler, _, _, _, _ := initRicServiceUpdateHandler(t)
+       prefBytes := []byte(serviceUpdateE2SetupMsgPrefix)
+       ricServiceUpdate, err := handler.parseSetupRequest(append(prefBytes, 1, 2, 3))
+       assert.Nil(t, ricServiceUpdate)
+       assert.NotNil(t, err)
+       assert.EqualError(t, err, "#RicServiceUpdateHandler.parseSetupRequest - Error unmarshalling RIC SERVICE UPDATE payload: 31302e302e302e32373a393939397c010203")
+}
+
+func testServiceUpdateSuccess(t *testing.T, servicepdatePath string, serviceUpdateAckPath string){
+       handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock := initRicServiceUpdateHandler(t)
+       xmlserviceUpdate  := utils.ReadXmlFile(t, servicepdatePath)
+       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,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)
+
+       handler.Handle(notificationRequest)
+       writerMock.AssertExpectations(t)
+       rmrMessengerMock.AssertNumberOfCalls(t,"SendMsg", 1)
+       readerMock.AssertExpectations(t)
+       ranListManagerMock.AssertExpectations(t)
+}
+
+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)
+
+       xAction := req.TransactionId
+       msgsrc := req.GetMsgSrc()
+
+       rmrMessage := models.NewRmrMessage(rmrCgo.RIC_SERVICE_UPDATE_ACK, serviceUpdateRANName, payLoad, xAction, msgsrc)
+       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 {
+       xmlgnb := utils.ReadXmlFile(t, RICServiceUpdate_E2SetupReqPath)
+       xmlgnb = utils.CleanXML(xmlgnb)
+       payload := append([]byte(serviceUpdateE2SetupMsgPrefix), xmlgnb...)
+       pipInd := bytes.IndexByte(payload, '|')
+       setupRequest := &models.E2SetupRequestMessage{}
+       err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       nodeb := &entities.NodebInfo{
+               AssociatedE2TInstanceAddress: serviceUpdateE2tInstanceAddress,
+               RanName:                      RanName,
+               SetupFromNetwork:             true,
+               NodeType:                     entities.Node_GNB,
+               ConnectionStatus:                         connectionStatus,
+               Configuration: &entities.NodebInfo_Gnb{
+                       Gnb: &entities.Gnb{
+                               GnbType:      entities.GnbType_GNB,
+                               RanFunctions: setupRequest.ExtractRanFunctionsList(),
+                       },
+               },
+               GlobalNbId: &entities.GlobalNbId{
+                       PlmnId: setupRequest.GetPlmnId(),
+                       NbId:   setupRequest.GetNbId(),
+               },
+       }
+       return nodeb
+}
+
index d1a210c..1c4ac6c 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
index b798186..b6ccb6d 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
index 060d3ea..49d7689 100755 (executable)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
index 8308fc1..d51e840 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
index 4153681..de2a2bc 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
diff --git a/E2Manager/models/ric_service_update_ack_message.go b/E2Manager/models/ric_service_update_ack_message.go
new file mode 100644 (file)
index 0000000..1388f14
--- /dev/null
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 2020 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"
+)
+
+type RicServiceAckRANFunctionIDItem struct {
+       Text                string `xml:",chardata"`
+        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"`
+}
+
+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 {
+               Text   string `xml:",chardata"`
+               RANfunctionsIDList struct {
+                       Text   string `xml:",chardata"`
+                       ProtocolIESingleContainer []RICserviceUpdateAcknowledgeProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"`
+               } `xml:"RANfunctionsID-List"`
+       }`xml:"value"`
+}
+
+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"`
+       Value struct {
+               Text            string `xml:",chardata"`
+               RICserviceUpdateAcknowledge  RICserviceUpdateAcknowledge `xml:"RICserviceUpdateAcknowledge"`
+       } `xml:"value"`
+}
+
+type RICserviceUpdateAcknowledge struct {
+       Text        string `xml:",chardata"`
+       ProtocolIEs struct {
+               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{}
+}
+
+func NewServiceUpdateAck(ricServiceUpdate []RicServiceAckRANFunctionIDItem) RicServiceUpdateAckE2APPDU {
+       successfulOutcome := RicServiceUpdateAckSuccessfulOutcome{}
+       successfulOutcome.ProcedureCode = "7"
+       if len(ricServiceUpdate) == 0 {
+               return RicServiceUpdateAckE2APPDU{InitiatingMessage:successfulOutcome}
+       }
+
+       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"
+       }
+       ricServiceUpdateAcknowledgeIEs[0].Value.RANfunctionsIDList.ProtocolIESingleContainer = protocolIESingleContainer
+       successfulOutcome.Value.RICserviceUpdateAcknowledge.ProtocolIEs.RICserviceUpdateAcknowledgeIEs = ricServiceUpdateAcknowledgeIEs
+       return RicServiceUpdateAckE2APPDU{InitiatingMessage:successfulOutcome}
+}
+
diff --git a/E2Manager/models/ric_service_update_message.go b/E2Manager/models/ric_service_update_message.go
new file mode 100644 (file)
index 0000000..4fcbe0d
--- /dev/null
@@ -0,0 +1,131 @@
+//
+// Copyright (c) 2020 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 RANfunctionsItemProtocolIESingleContainer struct {
+               Text        string `xml:",chardata"`
+               Id          string `xml:"id"`
+               Criticality struct {
+                               Text   string `xml:",chardata"`
+                               Ignore string `xml:"ignore"`
+               } `xml:"criticality"`
+               Value struct {
+                               Text              string `xml:",chardata"`
+                               RANfunctionItem struct {
+                                               Text                string `xml:",chardata"`
+                                               RanFunctionID       uint32 `xml:"ranFunctionID"`
+                                               RanFunctionDefinition string `xml:"ranFunctionDefinition"`
+                                               RanFunctionRevision uint32 `xml:"ranFunctionRevision"`
+                               } `xml:"RANfunction-Item"`
+               } `xml:"value"`
+}
+
+type RANfunctionsItemIDProtocolIESingleContainer struct {
+               Text        string `xml:",chardata"`
+               Id          string `xml:"id"`
+               Criticality struct {
+                               Text   string `xml:",chardata"`
+                               Ignore string `xml:"ignore"`
+               } `xml:"criticality"`
+               Value struct {
+                               Text              string `xml:",chardata"`
+                               RANfunctionIDItem struct {
+                                               Text                string `xml:",chardata"`
+                                               RanFunctionID       uint32 `xml:"ranFunctionID"`
+                                               RanFunctionRevision uint32 `xml:"ranFunctionRevision"`
+                               } `xml:"RANfunctionID-Item"`
+               } `xml:"value"`
+}
+
+
+type RICServiceUpdateIEs struct {
+       Text        string `xml:",chardata"`
+        ID          int `xml:"id"`
+        Criticality struct {
+                Text   string `xml:",chardata"`
+                Reject string `xml:"reject"`
+        } `xml:"criticality"`
+        Value struct {
+               Text   string `xml:",chardata"`
+               RANfunctionsList struct {
+                       Text   string `xml:",chardata"`
+                       RANfunctionsItemProtocolIESingleContainer []RANfunctionsItemProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"`
+               } `xml:"RANfunctions-List"`
+               RANfunctionsIDList struct {
+                       Text   string `xml:",chardata"`
+                       RANfunctionsItemIDProtocolIESingleContainer []RANfunctionsItemIDProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"`
+               } `xml:"RANfunctionsID-List"`
+       }`xml:"value"`
+}
+
+type RICServiceUpdateInitiatingMessage 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"`
+               RICServiceUpdate struct {
+                       Text        string `xml:",chardata"`
+                        ProtocolIEs struct {
+                                Text               string `xml:",chardata"`
+                                RICServiceUpdateIEs []RICServiceUpdateIEs `xml:"RICserviceUpdate-IEs"`
+                        } `xml:"protocolIEs"`
+               } `xml:"RICserviceUpdate"`
+       } `xml:"value"`
+}
+
+type RICServiceUpdateE2APPDU struct {
+        XMLName xml.Name `xml:"E2AP-PDU"`
+        Text    string `xml:",chardata"`
+        InitiatingMessage  RICServiceUpdateInitiatingMessage `xml:"initiatingMessage"`
+}
+
+type RICServiceUpdateMessage struct{
+       XMLName xml.Name `xml:"RICserviceUpdateMessage"`
+       Text    string   `xml:",chardata"`
+       E2APPDU RICServiceUpdateE2APPDU  `xml:"E2AP-PDU"`
+}
+
+func (m *RICServiceUpdateE2APPDU) ExtractRanFunctionsList() []*entities.RanFunction {
+       serviceUpdateRequestIes := m.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs
+       if len(serviceUpdateRequestIes) < 2 {
+               return nil
+       }
+
+       ranFunctionsListContainer := serviceUpdateRequestIes[1].Value.RANfunctionsList.RANfunctionsItemProtocolIESingleContainer
+       funcs := make([]*entities.RanFunction, len(ranFunctionsListContainer))
+       for i := 0; i < len(funcs); i++ {
+               ranFunctionItem := ranFunctionsListContainer[i].Value.RANfunctionItem
+
+               funcs[i] = &entities.RanFunction{
+                       RanFunctionId:         ranFunctionItem.RanFunctionID,
+                       RanFunctionDefinition: ranFunctionItem.RanFunctionDefinition,
+                       RanFunctionRevision:   ranFunctionItem.RanFunctionRevision,
+               }
+       }
+       return funcs
+}
index f20de09..fba2b90 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
index a692db0..87cb8f3 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
index 4565070..463b230 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
@@ -92,6 +93,7 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config
        e2TermInitNotificationHandler := rmrmsghandlers.NewE2TermInitNotificationHandler(logger, ranReconnectionManager, e2tInstancesManager, routingManagerClient)
        e2TKeepAliveResponseHandler := rmrmsghandlers.NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManager)
        e2SetupRequestNotificationHandler := rmrmsghandlers.NewE2SetupRequestNotificationHandler(logger, config, e2tInstancesManager, rmrSender, rnibDataService, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager)
+       ricServiceUpdateHandler := rmrmsghandlers.NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManager)
 
        provider.Register(rmrCgo.RIC_X2_SETUP_RESP, x2SetupResponseHandler)
        provider.Register(rmrCgo.RIC_X2_SETUP_FAILURE, x2SetupFailureResponseHandler)
@@ -106,4 +108,5 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config
        provider.Register(rmrCgo.RIC_E2_TERM_INIT, e2TermInitNotificationHandler)
        provider.Register(rmrCgo.E2_TERM_KEEP_ALIVE_RESP, e2TKeepAliveResponseHandler)
        provider.Register(rmrCgo.RIC_E2_SETUP_REQ, e2SetupRequestNotificationHandler)
+       provider.Register(rmrCgo.RIC_SERVICE_UPDATE, ricServiceUpdateHandler)
 }
index d7410e8..28bff54 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
@@ -96,6 +97,7 @@ func TestGetNotificationHandlerSuccess(t *testing.T) {
                {rmrCgo.E2_TERM_KEEP_ALIVE_RESP, rmrmsghandlers.NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManager)},
                {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)},
        }
 
        for _, tc := range testCases {
index 941af4d..d3886b4 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
@@ -81,6 +82,9 @@ const (
        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
 )
 
 const (
index 359e29b..5bb181c 100644 (file)
@@ -1,6 +1,7 @@
 //
 // Copyright 2019 AT&T Intellectual Property
 // Copyright 2019 Nokia
+// Copyright (c) 2020 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.
diff --git a/E2Manager/tests/resources/serviceQuery/RICServiceQuery_Empty.xml b/E2Manager/tests/resources/serviceQuery/RICServiceQuery_Empty.xml
new file mode 100644 (file)
index 0000000..2fe79c3
--- /dev/null
@@ -0,0 +1,12 @@
+<E2AP-PDU>
+    <initiatingMessage>
+        <procedureCode>6</procedureCode>
+        <criticality><reject/></criticality>
+        <value>
+            <RICserviceQuery>
+                <protocolIEs>
+                </protocolIEs>
+            </RICserviceQuery>
+        </value>
+    </initiatingMessage>
+</E2AP-PDU>
diff --git a/E2Manager/tests/resources/serviceQuery/RICServiceQuery_Sample.xml b/E2Manager/tests/resources/serviceQuery/RICServiceQuery_Sample.xml
new file mode 100644 (file)
index 0000000..74b08eb
--- /dev/null
@@ -0,0 +1,60 @@
+<E2AP-PDU>
+    <initiatingMessage>
+        <procedureCode>6</procedureCode>
+        <criticality>
+            <ignore/>
+        </criticality>
+        <value>
+            <RICserviceQuery>
+                <protocolIEs>
+                    <RICserviceQuery-IEs>
+                        <id>9</id>
+                        <criticality>
+                            <reject/>
+                        </criticality>
+                        <value>
+                            <RANfunctionsID-List>
+                                <ProtocolIE-SingleContainer>
+                                    <id>6</id>
+                                    <criticality>
+                                        <reject/>
+                                    </criticality>
+                                    <value>
+                                        <RANfunctionID-Item>
+                                            <ranFunctionID>17</ranFunctionID>
+                                            <ranFunctionRevision>2</ranFunctionRevision>
+                                        </RANfunctionID-Item>
+                                    </value>
+                                </ProtocolIE-SingleContainer>
+                                <ProtocolIE-SingleContainer>
+                                    <id>6</id>
+                                    <criticality>
+                                        <reject/>
+                                    </criticality>
+                                    <value>
+                                        <RANfunctionID-Item>
+                                            <ranFunctionID>18</ranFunctionID>
+                                            <ranFunctionRevision>2</ranFunctionRevision>
+                                        </RANfunctionID-Item>
+                                    </value>
+                                </ProtocolIE-SingleContainer>
+                                <ProtocolIE-SingleContainer>
+                                    <id>6</id>
+                                    <criticality>
+                                        <reject/>
+                                    </criticality>
+                                    <value>
+                                        <RANfunctionID-Item>
+                                            <ranFunctionID>19</ranFunctionID>
+                                            <ranFunctionRevision>2</ranFunctionRevision>
+                                        </RANfunctionID-Item>
+                                    </value>
+                                </ProtocolIE-SingleContainer>
+                            </RANfunctionsID-List>
+                        </value>
+                    </RICserviceQuery-IEs>
+                </protocolIEs>
+            </RICserviceQuery>
+        </value>
+    </initiatingMessage>
+</E2AP-PDU>
diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_AddedFunction.xml
new file mode 100644 (file)
index 0000000..c8b246c
--- /dev/null
@@ -0,0 +1,112 @@
+<E2AP-PDU>\r
+    <initiatingMessage>\r
+        <procedureCode>7</procedureCode>\r
+        <criticality><reject/></criticality>\r
+        <value>\r
+            <RICserviceUpdate>\r
+                <protocolIEs>\r
+                    <RICserviceUpdate-IEs>\r
+                        <id>10</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <RANfunctions-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>18</ranFunctionID>\r
+                                            <ranFunctionDefinition>\r
+                                                20 63 6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F\r
+                                                20 6D 6F 6E 69 74 6F 72 01 01 60 00 01 01 07 00\r
+                                                50 65 72 69 6F 64 69 63 20 72 65 70 6F 72 74 01\r
+                                                05 14 01 01 1D 00 4F 2D 44 55 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 35 47 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01 00 01 02 1D 00 4F 2D 44 55 20 4D\r
+                                                65 61 73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61\r
+                                                69 6E 65 72 20 66 6F 72 20 74 68 65 20 45 50 43\r
+                                                20 63 6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F\r
+                                                79 6D 65 6E 74 01 01 01 01 00 01 03 1E 80 4F 2D\r
+                                                43 55 2D 43 50 20 4D 65 61 73 75 72 65 6D 65 6E\r
+                                                74 20 43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20\r
+                                                74 68 65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65\r
+                                                64 20 64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01\r
+                                                00 01 04 1E 80 4F 2D 43 55 2D 43 50 20 4D 65 61\r
+                                                73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E\r
+                                                65 72 20 66 6F 72 20 74 68 65 20 45 50 43 20 63\r
+                                                6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D\r
+                                                65 6E 74 01 01 01 01 00 01 05 1E 80 4F 2D 43 55\r
+                                                2D 55 50 20 4D 65 61 73 75 72 65 6D 65 6E 74 20\r
+                                                43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20 74 68\r
+                                                65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65 64 20\r
+                                                64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01 00 01\r
+                                                06 1E 80 4F 2D 43 55 2D 55 50 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 45 50 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01\r
+                                            </ranFunctionDefinition>\r
+                                            <ranFunctionRevision>5</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctions-List>\r
+                        </value>\r
+                    </RICserviceUpdate-IEs>\r
+                    <RICserviceUpdate-IEs>\r
+                        <id>10</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <RANfunctions-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>20</ranFunctionID>\r
+                                            <ranFunctionDefinition>\r
+                                                50 65 72 69 6F 64 69 63 20 72 65 70 6F 72 74 01\r
+                                                20 6D 6F 6E 69 74 6F 72 01 01 60 00 01 01 07 00\r
+                                                50 65 72 69 6F 64 69 63 20 72 65 70 6F 72 74 01\r
+                                                05 14 01 01 1D 00 4F 2D 44 55 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 35 47 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01 00 01 02 1D 00 4F 2D 44 55 20 4D\r
+                                                65 61 73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61\r
+                                                69 6E 65 72 20 66 6F 72 20 74 68 65 20 45 50 43\r
+                                                20 63 6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F\r
+                                                79 6D 65 6E 74 01 01 01 01 00 01 03 1E 80 4F 2D\r
+                                                43 55 2D 43 50 20 4D 65 61 73 75 72 65 6D 65 6E\r
+                                                74 20 43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20\r
+                                                74 68 65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65\r
+                                                64 20 64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01\r
+                                                00 01 04 1E 80 4F 2D 43 55 2D 43 50 20 4D 65 61\r
+                                                73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E\r
+                                                65 72 20 66 6F 72 20 74 68 65 20 45 50 43 20 63\r
+                                                6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D\r
+                                                65 6E 74 01 01 01 01 00 01 05 1E 80 4F 2D 43 55\r
+                                                2D 55 50 20 4D 65 61 73 75 72 65 6D 65 6E 74 20\r
+                                                43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20 74 68\r
+                                                65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65 64 20\r
+                                                64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01 00 01\r
+                                                06 1E 80 4F 2D 43 55 2D 55 50 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 45 50 43 20 63 6F 6E\r
+                                                65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65 64 20\r
+                                                74 01 01 01 01\r
+                                            </ranFunctionDefinition>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctions-List>\r
+                        </value>\r
+                    </RICserviceUpdate-IEs>\r
+                </protocolIEs>\r
+            </RICserviceUpdate>\r
+        </value>\r
+    </initiatingMessage>\r
+</E2AP-PDU>\r
diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_DeleteFunction.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_DeleteFunction.xml
new file mode 100644 (file)
index 0000000..af0d259
--- /dev/null
@@ -0,0 +1,48 @@
+<E2AP-PDU>\r
+    <initiatingMessage>\r
+        <procedureCode>7</procedureCode>\r
+        <criticality><reject/></criticality>\r
+        <value>\r
+            <RICserviceUpdate>\r
+                <protocolIEs>\r
+                    <RICserviceUpdate-IEs>\r
+                        <id>11</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <RANfunctionsID-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>6</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunctionID-Item>\r
+                                            <ranFunctionID>18</ranFunctionID>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunctionID-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctionsID-List>\r
+                        </value>\r
+                    </RICserviceUpdate-IEs>\r
+                    <RICserviceUpdate-IEs>\r
+                        <id>11</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <RANfunctionsID-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>6</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunctionID-Item>\r
+                                            <ranFunctionID>15</ranFunctionID>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunctionID-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctionsID-List>\r
+                        </value>\r
+                    </RICserviceUpdate-IEs>\r
+                </protocolIEs>\r
+            </RICserviceUpdate>\r
+        </value>\r
+    </initiatingMessage>\r
+</E2AP-PDU>\r
diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_Empty.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_Empty.xml
new file mode 100644 (file)
index 0000000..1a7b23b
--- /dev/null
@@ -0,0 +1,12 @@
+<E2AP-PDU>\r
+    <initiatingMessage>\r
+        <procedureCode>7</procedureCode>\r
+        <criticality><reject/></criticality>\r
+        <value>\r
+            <RICserviceUpdate>\r
+                <protocolIEs>\r
+                </protocolIEs>\r
+            </RICserviceUpdate>\r
+        </value>\r
+    </initiatingMessage>\r
+</E2AP-PDU>\r
diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_ModifiedFunction.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_ModifiedFunction.xml
new file mode 100644 (file)
index 0000000..30311e1
--- /dev/null
@@ -0,0 +1,112 @@
+<E2AP-PDU>\r
+    <initiatingMessage>\r
+        <procedureCode>7</procedureCode>\r
+        <criticality><reject/></criticality>\r
+        <value>\r
+            <RICserviceUpdate>\r
+                <protocolIEs>\r
+                    <RICserviceUpdate-IEs>\r
+                        <id>12</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <RANfunctions-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>19</ranFunctionID>\r
+                                            <ranFunctionDefinition>\r
+                                                30 00 00 00 05 4F 49 44 31 32 33 05 00 4B 50 4D\r
+                                                20 6D 6F 6E 69 74 6F 72 01 01 60 00 01 01 07 00\r
+                                                50 65 72 69 6F 64 69 63 20 72 65 70 6F 72 74 01\r
+                                                05 14 01 01 1D 00 4F 2D 44 55 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 35 47 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01 00 01 02 1D 00 4F 2D 44 55 20 4D\r
+                                                65 61 73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61\r
+                                                69 6E 65 72 20 66 6F 72 20 74 68 65 20 45 50 43\r
+                                                20 63 6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F\r
+                                                79 6D 65 6E 74 01 01 01 01 00 01 03 1E 80 4F 2D\r
+                                                43 55 2D 43 50 20 4D 65 61 73 75 72 65 6D 65 6E\r
+                                                74 20 43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20\r
+                                                74 68 65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65\r
+                                                64 20 64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01\r
+                                                00 01 04 1E 80 4F 2D 43 55 2D 43 50 20 4D 65 61\r
+                                                73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E\r
+                                                65 72 20 66 6F 72 20 74 68 65 20 45 50 43 20 63\r
+                                                6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D\r
+                                                65 6E 74 01 01 01 01 00 01 05 1E 80 4F 2D 43 55\r
+                                                2D 55 50 20 4D 65 61 73 75 72 65 6D 65 6E 74 20\r
+                                                43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20 74 68\r
+                                                65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65 64 20\r
+                                                64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01 00 01\r
+                                                06 1E 80 4F 2D 43 55 2D 55 50 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 45 50 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01\r
+                                            </ranFunctionDefinition>\r
+                                            <ranFunctionRevision>5</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctions-List>\r
+                        </value>\r
+                    </RICserviceUpdate-IEs>\r
+                    <RICserviceUpdate-IEs>\r
+                        <id>12</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <RANfunctions-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>20</ranFunctionID>\r
+                                            <ranFunctionDefinition>\r
+                                                20 63 6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F\r
+                                                20 6D 6F 6E 69 74 6F 72 01 01 60 00 01 01 07 00\r
+                                                50 65 72 69 6F 64 69 63 20 72 65 70 6F 72 74 01\r
+                                                05 14 01 01 1D 00 4F 2D 44 55 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 35 47 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01 00 01 02 1D 00 4F 2D 44 55 20 4D\r
+                                                65 61 73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61\r
+                                                69 6E 65 72 20 66 6F 72 20 74 68 65 20 45 50 43\r
+                                                20 63 6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F\r
+                                                79 6D 65 6E 74 01 01 01 01 00 01 03 1E 80 4F 2D\r
+                                                43 55 2D 43 50 20 4D 65 61 73 75 72 65 6D 65 6E\r
+                                                74 20 43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20\r
+                                                74 68 65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65\r
+                                                64 20 64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01\r
+                                                00 01 04 1E 80 4F 2D 43 55 2D 43 50 20 4D 65 61\r
+                                                73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E\r
+                                                65 72 20 66 6F 72 20 74 68 65 20 45 50 43 20 63\r
+                                                6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D\r
+                                                65 6E 74 01 01 01 01 00 01 05 1E 80 4F 2D 43 55\r
+                                                2D 55 50 20 4D 65 61 73 75 72 65 6D 65 6E 74 20\r
+                                                43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20 74 68\r
+                                                65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65 64 20\r
+                                                64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01 00 01\r
+                                                06 1E 80 4F 2D 43 55 2D 55 50 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 45 50 43 20 63 6F 6E\r
+                                                65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65 64 20\r
+                                                74 01 01 01 01\r
+                                            </ranFunctionDefinition>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctions-List>\r
+                        </value>\r
+                    </RICserviceUpdate-IEs>\r
+                </protocolIEs>\r
+            </RICserviceUpdate>\r
+        </value>\r
+    </initiatingMessage>\r
+</E2AP-PDU>\r
diff --git a/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_SetupRequest.xml b/E2Manager/tests/resources/serviceUpdate/RicServiceUpdate_SetupRequest.xml
new file mode 100644 (file)
index 0000000..d210242
--- /dev/null
@@ -0,0 +1,164 @@
+<E2AP-PDU>\r
+    <initiatingMessage>\r
+        <procedureCode>1</procedureCode>\r
+        <criticality><reject/></criticality>\r
+        <value>\r
+            <E2setupRequest>\r
+                <protocolIEs>\r
+                    <E2setupRequestIEs>\r
+                        <id>3</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <GlobalE2node-ID>\r
+                                <gNB>\r
+                                    <global-gNB-ID>\r
+                                        <plmn-id>37 34 37</plmn-id>\r
+                                        <gnb-id>\r
+                                            <gnb-ID>\r
+                                                10110101110001100111011110001\r
+                                            </gnb-ID>\r
+                                        </gnb-id>\r
+                                    </global-gNB-ID>\r
+                                </gNB>\r
+                            </GlobalE2node-ID>\r
+                        </value>\r
+                    </E2setupRequestIEs>\r
+                    <E2setupRequestIEs>\r
+                        <id>10</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <RANfunctions-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>17</ranFunctionID>\r
+                                            <ranFunctionDefinition>\r
+                                                64 20 64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01\r
+                                                20 6D 6F 6E 69 74 6F 72 01 01 60 00 01 01 07 00\r
+                                                50 65 72 69 6F 64 69 63 20 72 65 70 6F 72 74 01\r
+                                                05 14 01 01 1D 00 4F 2D 44 55 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 35 47 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01 00 01 02 1D 00 4F 2D 44 55 20 4D\r
+                                                65 61 73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61\r
+                                                69 6E 65 72 20 66 6F 72 20 74 68 65 20 45 50 43\r
+                                                20 63 6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F\r
+                                                79 6D 65 6E 74 01 01 01 01 00 01 03 1E 80 4F 2D\r
+                                                43 55 2D 43 50 20 4D 65 61 73 75 72 65 6D 65 6E\r
+                                                74 20 43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20\r
+                                                74 68 65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65\r
+                                                64 20 64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01\r
+                                                00 01 04 1E 80 4F 2D 43 55 2D 43 50 20 4D 65 61\r
+                                                73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E\r
+                                                65 72 20 66 6F 72 20 74 68 65 20 45 50 43 20 63\r
+                                                6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D\r
+                                                65 6E 74 01 01 01 01 00 01 05 1E 80 4F 2D 43 55\r
+                                                2D 55 50 20 4D 65 61 73 75 72 65 6D 65 6E 74 20\r
+                                                43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20 74 68\r
+                                                65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65 64 20\r
+                                                64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01 00 01\r
+                                                06 1E 80 4F 2D 43 55 2D 55 50 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 45 50 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01\r
+                                            </ranFunctionDefinition>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>18</ranFunctionID>\r
+                                            <ranFunctionDefinition>\r
+                                                63 6F 6E 6E 65 63 74 65 64 20 32 33 05 00 4B 50\r
+                                                20 6D 6F 6E 69 74 6F 72 01 01 60 00 01 01 07 00\r
+                                                50 65 72 69 6F 64 69 63 20 72 65 70 6F 72 74 01\r
+                                                05 14 01 01 1D 00 4F 2D 44 55 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 35 47 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01 00 01 02 1D 00 4F 2D 44 55 20 4D\r
+                                                65 61 73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61\r
+                                                69 6E 65 72 20 66 6F 72 20 74 68 65 20 45 50 43\r
+                                                20 63 6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F\r
+                                                79 6D 65 6E 74 01 01 01 01 00 01 03 1E 80 4F 2D\r
+                                                43 55 2D 43 50 20 4D 65 61 73 75 72 65 6D 65 6E\r
+                                                74 20 43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20\r
+                                                74 68 65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65\r
+                                                64 20 64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01\r
+                                                00 01 04 1E 80 4F 2D 43 55 2D 43 50 20 4D 65 61\r
+                                                73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E\r
+                                                65 72 20 66 6F 72 20 74 68 65 20 45 50 43 20 63\r
+                                                6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D\r
+                                                65 6E 74 01 01 01 01 00 01 05 1E 80 4F 2D 43 55\r
+                                                2D 55 50 20 4D 65 61 73 75 72 65 6D 65 6E 74 20\r
+                                                43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20 74 68\r
+                                                65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65 64 20\r
+                                                64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01 00 01\r
+                                                06 1E 80 4F 2D 43 55 2D 55 50 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 45 50 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 04 1E 80 4F 2D 43\r
+                                                74 01 01 01 01\r
+                                            </ranFunctionDefinition>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>19</ranFunctionID>\r
+                                            <ranFunctionDefinition>\r
+                                                00 01 04 1E 80 4F 2D 43 55 2D 43 50 20 4D 65 61\r
+                                                20 6D 6F 6E 69 74 6F 72 01 01 60 00 01 01 07 00\r
+                                                50 65 72 69 6F 64 69 63 20 72 65 70 6F 72 74 01\r
+                                                05 14 01 01 1D 00 4F 2D 44 55 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 35 47 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01 00 01 02 1D 00 4F 2D 44 55 20 4D\r
+                                                65 61 73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61\r
+                                                69 6E 65 72 20 66 6F 72 20 74 68 65 20 45 50 43\r
+                                                20 63 6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F\r
+                                                79 6D 65 6E 74 01 01 01 01 00 01 03 1E 80 4F 2D\r
+                                                43 55 2D 43 50 20 4D 65 61 73 75 72 65 6D 65 6E\r
+                                                74 20 43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20\r
+                                                74 68 65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65\r
+                                                64 20 64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01\r
+                                                00 01 04 1E 80 4F 2D 43 55 2D 43 50 20 4D 65 61\r
+                                                73 75 72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E\r
+                                                65 72 20 66 6F 72 20 74 68 65 20 45 50 43 20 63\r
+                                                6F 6E 6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D\r
+                                                65 6E 74 01 01 01 01 00 01 05 1E 80 4F 2D 43 55\r
+                                                2D 55 50 20 4D 65 61 73 75 72 65 6D 65 6E 74 20\r
+                                                43 6F 6E 74 61 69 6E 65 72 20 66 6F 72 20 74 68\r
+                                                65 20 35 47 43 20 63 6F 6E 6E 65 63 74 65 64 20\r
+                                                64 65 70 6C 6F 79 6D 65 6E 74 01 01 01 01 00 01\r
+                                                06 1E 80 4F 2D 43 55 2D 55 50 20 4D 65 61 73 75\r
+                                                72 65 6D 65 6E 74 20 43 6F 6E 74 61 69 6E 65 72\r
+                                                20 66 6F 72 20 74 68 65 20 45 50 43 20 63 6F 6E\r
+                                                6E 65 63 74 65 64 20 64 65 70 6C 6F 79 6D 65 6E\r
+                                                74 01 01 01 01\r
+                                            </ranFunctionDefinition>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctions-List>\r
+                        </value>\r
+                    </E2setupRequestIEs>\r
+                </protocolIEs>\r
+            </E2setupRequest>\r
+        </value>\r
+    </initiatingMessage>\r
+</E2AP-PDU>\r
diff --git a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_AddedFunction.xml b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_AddedFunction.xml
new file mode 100644 (file)
index 0000000..1e6caf0
--- /dev/null
@@ -0,0 +1,48 @@
+<E2AP-PDU>\r
+    <successfulOutcome>\r
+        <procedureCode>7</procedureCode>\r
+        <criticality>\r
+            <reject/>\r
+        </criticality>\r
+        <value>\r
+            <RICserviceUpdateAcknowledge>\r
+                <protocolIEs>\r
+                    <RICserviceUpdateAcknowledge-IEs>\r
+                        <id>9</id>\r
+                        <criticality>\r
+                            <reject/>\r
+                        </criticality>\r
+                        <value>\r
+                            <RANfunctionsID-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>6</id>\r
+                                    <criticality>\r
+                                        <reject/>\r
+                                    </criticality>\r
+                                    <value>\r
+                                        <RANfunctionID-Item>\r
+                                            <ranFunctionID>18</ranFunctionID>\r
+                                            <ranFunctionRevision>5</ranFunctionRevision>\r
+                                        </RANfunctionID-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>6</id>\r
+                                    <criticality>\r
+                                        <reject/>\r
+                                    </criticality>\r
+                                    <value>\r
+                                        <RANfunctionID-Item>\r
+                                            <ranFunctionID>20</ranFunctionID>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunctionID-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctionsID-List>\r
+                        </value>\r
+                    </RICserviceUpdateAcknowledge-IEs>\r
+                </protocolIEs>\r
+            </RICserviceUpdateAcknowledge>\r
+        </value>\r
+    </successfulOutcome>\r
+</E2AP-PDU>\r
diff --git a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_DeleteFunction.xml b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_DeleteFunction.xml
new file mode 100644 (file)
index 0000000..f418f7b
--- /dev/null
@@ -0,0 +1,48 @@
+<E2AP-PDU>\r
+    <successfulOutcome>\r
+        <procedureCode>7</procedureCode>\r
+        <criticality>\r
+            <reject/>\r
+        </criticality>\r
+        <value>\r
+            <RICserviceUpdateAcknowledge>\r
+                <protocolIEs>\r
+                    <RICserviceUpdateAcknowledge-IEs>\r
+                        <id>9</id>\r
+                        <criticality>\r
+                            <reject/>\r
+                        </criticality>\r
+                        <value>\r
+                            <RANfunctionsID-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>6</id>\r
+                                    <criticality>\r
+                                        <reject/>\r
+                                    </criticality>\r
+                                    <value>\r
+                                        <RANfunctionID-Item>\r
+                                            <ranFunctionID>18</ranFunctionID>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunctionID-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>6</id>\r
+                                    <criticality>\r
+                                        <reject/>\r
+                                    </criticality>\r
+                                    <value>\r
+                                        <RANfunctionID-Item>\r
+                                            <ranFunctionID>15</ranFunctionID>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunctionID-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctionsID-List>\r
+                        </value>\r
+                    </RICserviceUpdateAcknowledge-IEs>\r
+                </protocolIEs>\r
+            </RICserviceUpdateAcknowledge>\r
+        </value>\r
+    </successfulOutcome>\r
+</E2AP-PDU>\r
diff --git a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_Empty.xml b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_Empty.xml
new file mode 100644 (file)
index 0000000..3aaa58a
--- /dev/null
@@ -0,0 +1,12 @@
+<E2AP-PDU>\r
+    <successfulOutcome>\r
+        <procedureCode>7</procedureCode>\r
+        <criticality><reject/></criticality>\r
+        <value>\r
+            <RICserviceUpdateAcknowledge>\r
+                <protocolIEs>\r
+                </protocolIEs>\r
+            </RICserviceUpdateAcknowledge>\r
+        </value>\r
+    </successfulOutcome>\r
+</E2AP-PDU>\r
diff --git a/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_ModifiedFunction.xml b/E2Manager/tests/resources/serviceUpdateAck/RicServiceUpdateAck_ModifiedFunction.xml
new file mode 100644 (file)
index 0000000..f90d78c
--- /dev/null
@@ -0,0 +1,48 @@
+<E2AP-PDU>\r
+    <successfulOutcome>\r
+        <procedureCode>7</procedureCode>\r
+        <criticality>\r
+            <reject/>\r
+        </criticality>\r
+        <value>\r
+            <RICserviceUpdateAcknowledge>\r
+                <protocolIEs>\r
+                    <RICserviceUpdateAcknowledge-IEs>\r
+                        <id>9</id>\r
+                        <criticality>\r
+                            <reject/>\r
+                        </criticality>\r
+                        <value>\r
+                            <RANfunctionsID-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>6</id>\r
+                                    <criticality>\r
+                                        <reject/>\r
+                                    </criticality>\r
+                                    <value>\r
+                                        <RANfunctionID-Item>\r
+                                            <ranFunctionID>19</ranFunctionID>\r
+                                            <ranFunctionRevision>5</ranFunctionRevision>\r
+                                        </RANfunctionID-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>6</id>\r
+                                    <criticality>\r
+                                        <reject/>\r
+                                    </criticality>\r
+                                    <value>\r
+                                        <RANfunctionID-Item>\r
+                                            <ranFunctionID>20</ranFunctionID>\r
+                                            <ranFunctionRevision>2</ranFunctionRevision>\r
+                                        </RANfunctionID-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctionsID-List>\r
+                        </value>\r
+                    </RICserviceUpdateAcknowledge-IEs>\r
+                </protocolIEs>\r
+            </RICserviceUpdateAcknowledge>\r
+        </value>\r
+    </successfulOutcome>\r
+</E2AP-PDU>\r
@@ -65,4 +65,4 @@
             </E2setupRequest>\r
         </value>\r
     </initiatingMessage>\r
-</E2AP-PDU>
\ No newline at end of file
+</E2AP-PDU>\r
diff --git a/E2Manager/utils/xml_utils.go b/E2Manager/utils/xml_utils.go
new file mode 100644 (file)
index 0000000..5486673
--- /dev/null
@@ -0,0 +1,80 @@
+//
+// Copyright (c) 2020 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 utils
+
+import (
+       "fmt"
+       "io/ioutil"
+       "path/filepath"
+       "strings"
+       "testing"
+)
+
+func CleanXML(payload []byte) []byte {
+       xmlStr := string(payload)
+       normalized := strings.NewReplacer("\r","","\n",""," ","").Replace(xmlStr)
+
+       return []byte(normalized)
+}
+
+func ReadXmlFile(t *testing.T, xmlPath string) []byte {
+       path, err := filepath.Abs(xmlPath)
+       if err != nil {
+               t.Fatal(err)
+       }
+       xmlAsBytes, err := ioutil.ReadFile(path)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       return xmlAsBytes
+}
+
+func ReadXmlFileNoTest(xmlPath string) ([]byte, error) {
+       path, err := filepath.Abs(xmlPath)
+       if err != nil {
+               return nil,err
+       }
+       xmlAsBytes, err := ioutil.ReadFile(path)
+       if err != nil {
+               return nil,err
+       }
+
+       return xmlAsBytes,nil
+}
+
+func NormalizeXml(payload []byte) []byte {
+       xmlStr := string(payload)
+       normalized := strings.NewReplacer("&lt;", "<", "&gt;", ">").Replace(xmlStr)
+
+       return []byte(normalized)
+}
+
+func ReplaceEmptyTagsWithSelfClosing(responsePayload []byte, emptyTagsToReplace []string) []byte {
+       emptyTagVsSelfClosingTagPairs := make([]string, len(emptyTagsToReplace)*2)
+       j := 0
+
+       for i := 0; i < len(emptyTagsToReplace); i++ {
+               emptyTagVsSelfClosingTagPairs[j] = fmt.Sprintf("<%[1]s></%[1]s>", emptyTagsToReplace[i])
+               emptyTagVsSelfClosingTagPairs[j+1] = fmt.Sprintf("<%s/>", emptyTagsToReplace[i])
+               j += 2
+       }
+       responseString := strings.NewReplacer(emptyTagVsSelfClosingTagPairs...).Replace(string(responsePayload))
+       return []byte(responseString)
+}