Merge "Automation of nodeb health check"
authorShuky Har-Noy <shuky.har-noy@intl.att.com>
Thu, 12 Nov 2020 13:51:26 +0000 (13:51 +0000)
committerGerrit Code Review <gerrit@o-ran-sc.org>
Thu, 12 Nov 2020 13:51:26 +0000 (13:51 +0000)
53 files changed:
Automation/Tests/Get_NodeB_State/Get_NodeB_State.robot [new file with mode: 0644]
Automation/Tests/Get_NodeB_State/__init__.robot [new file with mode: 0644]
Automation/Tests/Resource/Keywords.robot
Automation/Tests/Resource/resource.robot
E2Manager/app/main.go
E2Manager/container-tag.yaml
E2Manager/controllers/nodeb_controller.go
E2Manager/controllers/nodeb_controller_test.go
E2Manager/go.sum
E2Manager/handlers/httpmsghandlers/get_nodeb_id_request_handler.go [new file with mode: 0644]
E2Manager/handlers/httpmsghandlers/get_nodeb_id_request_handler_test.go [new file with mode: 0644]
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/get_nodeb_id_request.go [new file with mode: 0644]
E2Manager/models/get_nodeb_id_response.go [new file with mode: 0644]
E2Manager/models/health_check_response.go [new file with mode: 0644]
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]
Swagger/E2Manager_API.yaml
releases/container-release-ric-plt-e2mgr.yaml

diff --git a/Automation/Tests/Get_NodeB_State/Get_NodeB_State.robot b/Automation/Tests/Get_NodeB_State/Get_NodeB_State.robot
new file mode 100644 (file)
index 0000000..6a3662e
--- /dev/null
@@ -0,0 +1,63 @@
+##############################################################################
+#
+#   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).
+#
+
+
+*** Settings ***
+Variables  ../Scripts/variables.py
+Resource   ../Resource/resource.robot
+Resource   ../Resource/Keywords.robot
+Library     OperatingSystem
+Library     ../Scripts/log_scripts.py
+Library     REST        ${url}
+
+
+*** Variables ***
+${url}  ${e2mgr_address}
+
+
+*** Test Cases ***
+
+Get NodeB state
+    Sleep    2s
+    Add eNb Request
+    Sleep    2s
+    Get NodeB state request
+    Integer  response status                     200
+    String   response body inventoryName         ${enb_ran_name}
+    String   response body connectionStatus      DISCONNECTED
+    String   response body globalNbId plmnId     def
+    String   response body globalNbId nbId       abc
+
+prepare logs for tests
+    Remove log files
+    Save logs
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Automation/Tests/Get_NodeB_State/__init__.robot b/Automation/Tests/Get_NodeB_State/__init__.robot
new file mode 100644 (file)
index 0000000..8edaad6
--- /dev/null
@@ -0,0 +1,24 @@
+##############################################################################
+#
+#   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).
+#
+
+*** Settings ***
+Documentation    Get_NodeB_State
index 2057ca7..f252af8 100644 (file)
@@ -52,6 +52,11 @@ Add eNb Request
     Sleep  1s
     POST    ${enb_url}   ${request}
 
+Get NodeB state request
+    [Arguments]     ${request}=${nodeb_state_url}
+    Sleep  1s
+    GET    ${request}
+
 Delete eNb Request
     Sleep  1s
     DELETE    ${enb_url}/${enb_ran_name}
index 03e15d4..4973bf1 100644 (file)
@@ -37,6 +37,7 @@ ${set_general_configuration}   /v1/nodeb/parameters
 ${set_general_configuration_body}   {"enableRic":false}
 ${update_gnb_url}   /v1/nodeb/gnb/${ranName}
 ${enb_url}    /v1/nodeb/enb
+${nodeb_state_url}    /v1/nodeb/states/${enb_ran_name}
 ${update_gnb_body}  {"servedNrCells":[{"servedNrCellInformation":{"cellId":"abcd","choiceNrMode":{"fdd":{}},"nrMode":1,"nrPci":1,"servedPlmns":["whatever"]},"nrNeighbourInfos":[{"nrCgi":"one","choiceNrMode":{"fdd":{}},"nrMode":1,"nrPci":1}]}]}
 ${update_gnb_body_notvalid}  {"servedNrCells":[{"servedNrCellInformation":{"choiceNrMode":{"fdd":{}},"nrMode":1,"nrPci":1,"servedPlmns":["whatever"]},"nrNeighbourInfos":[{"nrCgi":"whatever","choiceNrMode":{"fdd":{}},"nrMode":1,"nrPci":1}]}]}
 ${add_enb_request_body}    {"ranName":"${enb_ran_name}","globalNbId":{"nbId":"abc","plmnId":"def"},"port":1234,"enb":{"enbType":3,"guGroupIds":["ghi"],"servedCells":[{"broadcastPlmns":["jkl"],"cellId":"mnop","choiceEutraMode":{"fdd":{"dlearFcn":1,"ulearFcn":1},"tdd":{"additionalSpecialSubframeExtensionInfo":{"additionalSpecialSubframePatternsExtension":1,"cyclicPrefixDl":1,"cyclicPrefixUl":1},"additionalSpecialSubframeInfo":{"additionalSpecialSubframePatterns":1,"cyclicPrefixDl":1,"cyclicPrefixUl":1},"earFcn":4,"specialSubframeInfo":{"specialSubframePatterns":1,"cyclicPrefixDl":1,"cyclicPrefixUl":1}}},"eutraMode":1,"csgId":"string","mbmsServiceAreaIdentities":["sds"],"mbsfnSubframeInfos":[{"radioframeAllocationOffset":3,"subframeAllocation":"jhg"}],"multibandInfos":[4],"neighbourInfos":[{"earFcn":4,"ecgi":"klj","pci":5,"tac":"wew"}],"pci":2,"prachConfiguration":{"highSpeedFlag":true,"prachConfigurationIndex":5,"prachFrequencyOffset":6,"rootSequenceIndex":7,"zeroCorrelationZoneConfiguration":6},"tac":"asd","additionalCellInformation":{"cellLatitude":1,"cellLongitude":1,"antennaHeight":1,"antennaAzimuthDirection":2,"antennaTiltAngle":3,"antennaMaxTransmit":4,"antennaMaxGain":5,"sectorId":6}},{"broadcastPlmns":["jkl"],"cellId":"qrst","choiceEutraMode":{"fdd":{"dlearFcn":4,"ulearFcn":2},"tdd":{"additionalSpecialSubframeExtensionInfo":{"additionalSpecialSubframePatternsExtension":1,"cyclicPrefixDl":1,"cyclicPrefixUl":1},"additionalSpecialSubframeInfo":{"additionalSpecialSubframePatterns":1,"cyclicPrefixDl":1,"cyclicPrefixUl":1},"earFcn":4,"specialSubframeInfo":{"specialSubframePatterns":1,"cyclicPrefixDl":1,"cyclicPrefixUl":1}}},"eutraMode":1,"csgId":"string","mbmsServiceAreaIdentities":["sds"],"mbsfnSubframeInfos":[{"radioframeAllocationOffset":5,"subframeAllocation":"jhg"}],"multibandInfos":[4],"neighbourInfos":[{"earFcn":2,"ecgi":"klj","pci":4,"tac":"wew"}],"pci":3,"prachConfiguration":{"highSpeedFlag":true,"prachConfigurationIndex":4,"prachFrequencyOffset":3,"rootSequenceIndex":3,"zeroCorrelationZoneConfiguration":2},"tac":"asd","additionalCellInformation":{"cellLatitude":3,"cellLongitude":3,"antennaHeight":3,"antennaAzimuthDirection":3,"antennaTiltAngle":4,"antennaMaxTransmit":4,"antennaMaxGain":5,"sectorId":5}}]}}
index 59444a3..fa71c78 100644 (file)
@@ -41,6 +41,29 @@ import (
        "strconv"
 )
 
+const (
+       GeneralKey             = "GENERAL"
+       GeneralKeyDefaultValue = "{\"enableRic\":true}"
+)
+
+func initKeys(logger *logger.Logger, sdl *sdlgo.SdlInstance) error {
+       ok, err := sdl.SetIfNotExists(GeneralKey, GeneralKeyDefaultValue)
+
+       if err != nil {
+               logger.Errorf("#app.main - Failed setting GENERAL key")
+               return err
+       }
+
+       if ok {
+               logger.Infof("#app.main - Successfully set GENERAL key")
+       } else {
+               logger.Infof("#app.main - GENERAL key exists, no need to set")
+       }
+
+       return nil
+
+}
+
 func main() {
        config := configuration.ParseConfiguration()
        logLevel, _ := logger.LogLevelTokenToLevel(config.Logging.LogLevel)
@@ -52,6 +75,12 @@ func main() {
        logger.Infof("#app.main - Configuration %s", config)
        db := sdlgo.NewDatabase()
        sdl := sdlgo.NewSdlInstance("e2Manager", db)
+       err = initKeys(logger, sdl)
+
+       if err != nil {
+               os.Exit(1)
+       }
+
        defer sdl.Close()
        rnibDataService := services.NewRnibDataService(logger, config, reader.GetRNibReader(sdl), rNibWriter.GetRNibWriter(sdl, config.RnibWriter))
 
index cfda56b..35c6d9b 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.13
index f2efd65..ece6941 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.
@@ -50,6 +51,7 @@ type INodebController interface {
        UpdateGnb(writer http.ResponseWriter, r *http.Request)
        UpdateEnb(writer http.ResponseWriter, r *http.Request)
        GetNodebIdList(writer http.ResponseWriter, r *http.Request)
+       GetNodebId(writer http.ResponseWriter, r *http.Request)
        SetGeneralConfiguration(writer http.ResponseWriter, r *http.Request)
        AddEnb(writer http.ResponseWriter, r *http.Request)
        DeleteEnb(writer http.ResponseWriter, r *http.Request)
@@ -74,6 +76,15 @@ func (c *NodebController) GetNodebIdList(writer http.ResponseWriter, r *http.Req
        c.handleRequest(writer, &r.Header, httpmsghandlerprovider.GetNodebIdListRequest, nil, false, http.StatusOK)
 }
 
+func (c *NodebController) GetNodebId(writer http.ResponseWriter, r *http.Request) {
+       c.logger.Infof("[Client -> E2 Manager] #NodebController.GetNodebId - request: %v", c.prettifyRequest(r))
+       vars := mux.Vars(r)
+       ranName := vars["ranName"]
+       request := models.GetNodebIdRequest{RanName: ranName}
+
+       c.handleRequest(writer, &r.Header, httpmsghandlerprovider.GetNodebIdRequest, request, false, http.StatusOK)
+}
+
 func (c *NodebController) GetNodeb(writer http.ResponseWriter, r *http.Request) {
        c.logger.Infof("[Client -> E2 Manager] #NodebController.GetNodeb - request: %v", c.prettifyRequest(r))
        vars := mux.Vars(r)
@@ -201,7 +212,7 @@ func (c *NodebController) HealthCheckRequest(writer http.ResponseWriter, r *http
                return
        }
 
-       c.handleRequest(writer, &r.Header, httpmsghandlerprovider.HealthCheckRequest, request, true, http.StatusNoContent)
+       c.handleRequest(writer, &r.Header, httpmsghandlerprovider.HealthCheckRequest, request, true, http.StatusAccepted)
 }
 
 func (c *NodebController) extractRequestBodyToProto(r *http.Request, pb proto.Message, writer http.ResponseWriter) bool {
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 b117c2a..a84491a 100644 (file)
@@ -37,8 +37,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
-github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-redis/redis v6.15.3+incompatible h1:NZ0O90AhLSvSrvLZ/S9h7D4kl1mW2PrKyxL7MyBKO2g=
+github.com/go-redis/redis v6.15.3+incompatible/go.mod h1:W2YCLaZryXHirdd9QqwkiVUxCQsrx8SbLq9Uqk7JS7A=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
@@ -99,9 +99,11 @@ github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
 github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
diff --git a/E2Manager/handlers/httpmsghandlers/get_nodeb_id_request_handler.go b/E2Manager/handlers/httpmsghandlers/get_nodeb_id_request_handler.go
new file mode 100644 (file)
index 0000000..1c84969
--- /dev/null
@@ -0,0 +1,50 @@
+//
+// 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 httpmsghandlers
+
+import (
+       "e2mgr/logger"
+       "e2mgr/managers"
+       "e2mgr/models"
+)
+
+type GetNodebIdRequestHandler struct {
+       logger          *logger.Logger
+       ranListManager  managers.RanListManager
+}
+
+func NewGetNodebIdRequestHandler(logger *logger.Logger, ranListManager managers.RanListManager) *GetNodebIdRequestHandler {
+       return &GetNodebIdRequestHandler{
+               logger:          logger,
+               ranListManager:  ranListManager,
+       }
+}
+
+func (h *GetNodebIdRequestHandler) Handle(request models.Request) (models.IResponse, error) {
+       getNodebIdRequest := request.(models.GetNodebIdRequest)
+       ranName := getNodebIdRequest.RanName
+
+       nodebId, err := h.ranListManager.GetNbIdentity(ranName)
+       if err != nil {
+               return nil, err
+       }
+
+       return models.NewNodebIdResponse(nodebId), nil
+}
diff --git a/E2Manager/handlers/httpmsghandlers/get_nodeb_id_request_handler_test.go b/E2Manager/handlers/httpmsghandlers/get_nodeb_id_request_handler_test.go
new file mode 100644 (file)
index 0000000..337212d
--- /dev/null
@@ -0,0 +1,66 @@
+//
+// 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 httpmsghandlers
+
+import (
+       "e2mgr/mocks"
+       "e2mgr/models"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/stretchr/testify/assert"
+       "e2mgr/e2managererrors"
+       "testing"
+)
+
+func setupGetNodebIdRequestHandlerTest(t *testing.T) (*GetNodebIdRequestHandler, *mocks.RanListManagerMock) {
+       log := initLog(t)
+       ranListManagerMock := &mocks.RanListManagerMock{}
+
+       handler := NewGetNodebIdRequestHandler(log, ranListManagerMock)
+       return handler, ranListManagerMock
+}
+
+func TestHandleGetNodebIdSuccess(t *testing.T) {
+       handler, ranListManagerMock := setupGetNodebIdRequestHandlerTest(t)
+       nbIdentity := &entities.NbIdentity{
+               InventoryName:    "test",
+               ConnectionStatus: entities.ConnectionStatus_CONNECTED,
+               HealthCheckTimestampSent: 12345678,
+               HealthCheckTimestampReceived: 12346548,
+       }
+       ranListManagerMock.On("GetNbIdentity",nbIdentity.InventoryName).Return(nbIdentity, nil)
+       response, err := handler.Handle(models.GetNodebIdRequest{RanName: nbIdentity.InventoryName})
+
+       assert.Nil(t, err)
+       assert.NotNil(t, response)
+       assert.IsType(t, &models.NodebIdResponse{}, response)
+}
+
+func TestHandleGetNodebIdNotFoundFailure(t *testing.T) {
+       handler, ranListManagerMock := setupGetNodebIdRequestHandlerTest(t)
+       nbIdentity := &entities.NbIdentity{
+               InventoryName:    "test",
+       }
+
+       ranListManagerMock.On("GetNbIdentity",nbIdentity.InventoryName).Return(nbIdentity, e2managererrors.NewResourceNotFoundError())
+       _, err := handler.Handle(models.GetNodebIdRequest{RanName: nbIdentity.InventoryName})
+
+       assert.NotNil(t, err)
+       assert.IsType(t, &e2managererrors.ResourceNotFoundError{}, err)
+}
\ No newline at end of file
index 718a49b..785fa49 100644 (file)
@@ -26,16 +26,16 @@ 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"}
+       healthCheckSuccessResponse          = "Request Accepted"
+       healthCheckEmptyTagsToReplaceToSelfClosingTags = []string{"reject", "ignore", "protocolIEs", "procedureCode"}
 )
 
 type HealthCheckRequestHandler struct {
@@ -99,7 +99,7 @@ func (h *HealthCheckRequestHandler) Handle(request models.Request) (models.IResp
 
        h.logger.Infof("#HealthcheckRequest.Handle - HealthcheckTimeStampSent Update completed to RedisDB")
 
-       return nil, nil
+       return models.NewHealthCheckSuccessResponse(healthCheckSuccessResponse), nil
 }
 
 func (h *HealthCheckRequestHandler) sendRICServiceQuery(nodebInfo *entities.NodebInfo) error {
@@ -111,7 +111,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 +148,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..4bce41f 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) {
@@ -76,8 +75,9 @@ func TestHealthCheckRequestHandlerArguementHasRanNameSuccess(t *testing.T) {
        ranListManagerMock.On("UpdateHealthcheckTimeStampSent",nb1.RanName).Return(oldnbIdentity, newnbIdentity)
        ranListManagerMock.On("UpdateNbIdentities",nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, []*entities.NbIdentity{newnbIdentity}).Return(nil)
 
-       _, err := handler.Handle(models.HealthCheckRequest{ranNames})
+       resp, err := handler.Handle(models.HealthCheckRequest{ranNames})
 
+       assert.IsType(t, &models.HealthCheckSuccessResponse{}, resp)
        assert.Nil(t, err)
        readerMock.AssertExpectations(t)
 }
@@ -104,9 +104,10 @@ func TestHealthCheckRequestHandlerArguementHasNoRanNameSuccess(t *testing.T) {
        nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}
        readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
 
-       _, err := handler.Handle(models.HealthCheckRequest{[]string{}})
+       resp, err := handler.Handle(models.HealthCheckRequest{[]string{}})
 
        assert.Nil(t, err)
+       assert.IsType(t, &models.HealthCheckSuccessResponse{}, resp)
 
 }
 
@@ -150,7 +151,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 +167,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 +203,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..1109f6e 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.
@@ -46,6 +47,7 @@ func initializeRoutes(router *mux.Router, rootController controllers.IRootContro
 
        rr := r.PathPrefix("/nodeb").Subrouter()
        rr.HandleFunc("/states", nodebController.GetNodebIdList).Methods(http.MethodGet)
+       rr.HandleFunc("/states/{ranName}", nodebController.GetNodebId).Methods(http.MethodGet)
        rr.HandleFunc("/{ranName}", nodebController.GetNodeb).Methods(http.MethodGet)
        rr.HandleFunc("/enb", nodebController.AddEnb).Methods(http.MethodPost)
        rr.HandleFunc("/enb/{ranName}", nodebController.DeleteEnb).Methods(http.MethodDelete)
index b798186..f39a259 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.
@@ -38,6 +39,7 @@ func setupRouterAndMocks() (*mux.Router, *mocks.RootControllerMock, *mocks.Nodeb
        nodebControllerMock.On("Shutdown").Return(nil)
        nodebControllerMock.On("GetNodeb").Return(nil)
        nodebControllerMock.On("GetNodebIdList").Return(nil)
+       nodebControllerMock.On("GetNodebId").Return(nil)
        nodebControllerMock.On("SetGeneralConfiguration").Return(nil)
        nodebControllerMock.On("DeleteEnb").Return(nil)
        nodebControllerMock.On("AddEnb").Return(nil)
@@ -53,7 +55,7 @@ func setupRouterAndMocks() (*mux.Router, *mocks.RootControllerMock, *mocks.Nodeb
        return router, rootControllerMock, nodebControllerMock, e2tControllerMock
 }
 
-func TestRouteGetNodebIds(t *testing.T) {
+func TestRouteGetNodebIdList(t *testing.T) {
        router, _, nodebControllerMock, _ := setupRouterAndMocks()
 
        req, err := http.NewRequest("GET", "/v1/nodeb/states", nil)
@@ -66,6 +68,20 @@ func TestRouteGetNodebIds(t *testing.T) {
        nodebControllerMock.AssertNumberOfCalls(t, "GetNodebIdList", 1)
 }
 
+func TestRouteGetNodebId(t *testing.T) {
+       router, _, nodebControllerMock, _ := setupRouterAndMocks()
+
+       req, err := http.NewRequest("GET", "/v1/nodeb/states/ran1", nil)
+       if err != nil {
+               t.Fatal(err)
+       }
+       rr := httptest.NewRecorder()
+       router.ServeHTTP(rr, req)
+
+       assert.Equal(t, http.StatusOK, rr.Code, "handler returned wrong status code")
+       nodebControllerMock.AssertNumberOfCalls(t, "GetNodebId", 1)
+}
+
 func TestRouteGetNodebRanName(t *testing.T) {
        router, _, nodebControllerMock, _ := setupRouterAndMocks()
 
@@ -117,6 +133,7 @@ func TestHealthCheckRequest(t *testing.T) {
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
+       assert.Equal(t, http.StatusAccepted, rr.Code, "handler returned wrong status code")
        nodebControllerMock.AssertNumberOfCalls(t, "HealthCheckRequest", 1)
 }
 
index 060d3ea..b6dcbcb 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.
@@ -41,6 +42,7 @@ type RanListManager interface {
        UpdateNbIdentityConnectionStatus(nodeType entities.Node_Type, ranName string, connectionStatus entities.ConnectionStatus) error
        RemoveNbIdentity(nodeType entities.Node_Type, ranName string) error
        GetNbIdentityList() []*entities.NbIdentity
+       GetNbIdentity(ranName string) (*entities.NbIdentity, error)
        UpdateHealthcheckTimeStampReceived(oldRRanName string) (*entities.NbIdentity, *entities.NbIdentity)
        UpdateHealthcheckTimeStampSent(oldRRanName string) (*entities.NbIdentity, *entities.NbIdentity)
        UpdateNbIdentities(nodeType entities.Node_Type, oldNbIdentities []*entities.NbIdentity, newNbIdentities []*entities.NbIdentity) error
@@ -154,6 +156,18 @@ func (m *ranListManagerInstance) GetNbIdentityList() []*entities.NbIdentity {
        return nbIds
 }
 
+func (m *ranListManagerInstance) GetNbIdentity(ranName string) (*entities.NbIdentity, error) {
+       nbIdentity, ok := m.nbIdentityMap[ranName]
+       if !ok {
+               m.logger.Infof("#ranListManagerInstance.GetNbIdentity - RAN name: %s - nodeb identity not found", ranName)
+               return nil , e2managererrors.NewResourceNotFoundError()
+       }
+
+       m.logger.Infof("#ranListManagerInstance.GetNbIdentity - RAN name: %s - nodeb identity returned", ranName)
+
+       return nbIdentity, nil
+}
+
 func (m *ranListManagerInstance) UpdateHealthcheckTimeStampSent(oldRRanName string) (*entities.NbIdentity, *entities.NbIdentity){
        currentTimeStamp := time.Now().UnixNano()
        oldNbIdentity := m.nbIdentityMap[oldRRanName]
index 8308fc1..923955a 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.
@@ -45,6 +46,17 @@ func (c *NodebControllerMock) GetNodebIdList(writer http.ResponseWriter, r *http
        c.Called()
 }
 
+func (c *NodebControllerMock) GetNodebId(writer http.ResponseWriter, r *http.Request) {
+       writer.Header().Set("Content-Type", "application/json")
+       writer.WriteHeader(http.StatusOK)
+
+       vars := mux.Vars(r)
+       ranName := vars["ranName"]
+
+       writer.Write([]byte(ranName))
+       c.Called()
+}
+
 func (c *NodebControllerMock) Shutdown(writer http.ResponseWriter, r *http.Request) {
        c.Called()
 }
@@ -96,7 +108,7 @@ func (c *NodebControllerMock) SetGeneralConfiguration(writer http.ResponseWriter
 
 func (c *NodebControllerMock) HealthCheckRequest(writer http.ResponseWriter, r *http.Request) {
        writer.Header().Set("Content-Type", "application/json")
-       writer.WriteHeader(http.StatusOK)
+       writer.WriteHeader(http.StatusAccepted)
 
        c.Called()
 }
index 4153681..11c8305 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.
@@ -60,6 +61,11 @@ func (m *RanListManagerMock) GetNbIdentityList() []*entities.NbIdentity {
        return args.Get(0).([]*entities.NbIdentity)
 }
 
+func (m *RanListManagerMock) GetNbIdentity(ranName string) (*entities.NbIdentity, error) {
+       args := m.Called(ranName)
+       return args.Get(0).(*entities.NbIdentity), args.Error(1)
+}
+
 func (m *RanListManagerMock) UpdateHealthcheckTimeStampSent(oldRRanName string) (*entities.NbIdentity, *entities.NbIdentity){
        args := m.Called(oldRRanName)
        return args.Get(0).(*entities.NbIdentity), args.Get(1).(*entities.NbIdentity)
diff --git a/E2Manager/models/get_nodeb_id_request.go b/E2Manager/models/get_nodeb_id_request.go
new file mode 100644 (file)
index 0000000..cb0453f
--- /dev/null
@@ -0,0 +1,24 @@
+//
+// 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
+
+type GetNodebIdRequest struct {
+       RanName string
+}
diff --git a/E2Manager/models/get_nodeb_id_response.go b/E2Manager/models/get_nodeb_id_response.go
new file mode 100644 (file)
index 0000000..515ee0b
--- /dev/null
@@ -0,0 +1,48 @@
+//
+// 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 (
+       "e2mgr/e2managererrors"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/golang/protobuf/jsonpb"
+)
+
+type NodebIdResponse struct {
+       nbIdentity *entities.NbIdentity
+}
+
+func NewNodebIdResponse(nbIdentity *entities.NbIdentity) *NodebIdResponse {
+       return &NodebIdResponse{
+               nbIdentity: nbIdentity,
+       }
+}
+
+func (response *NodebIdResponse) Marshal() ([]byte, error) {
+       m := jsonpb.Marshaler{}
+       result, err := m.MarshalToString(response.nbIdentity)
+
+       if err != nil {
+               return nil, e2managererrors.NewInternalError()
+       }
+
+       return []byte(result), nil
+}
+
diff --git a/E2Manager/models/health_check_response.go b/E2Manager/models/health_check_response.go
new file mode 100644 (file)
index 0000000..87dab64
--- /dev/null
@@ -0,0 +1,47 @@
+//
+// 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 (
+       "e2mgr/e2managererrors"
+       "encoding/json"
+)
+
+type HealthCheckSuccessResponse struct {
+       Message string   `json:"message"`
+}
+
+func NewHealthCheckSuccessResponse(message string) *HealthCheckSuccessResponse {
+       return &HealthCheckSuccessResponse{
+               Message: message,
+       }
+}
+
+func (response HealthCheckSuccessResponse) Marshal() ([]byte, error) {
+
+       data, err := json.Marshal(response)
+
+       if err != nil {
+               return nil, e2managererrors.NewInternalError()
+       }
+
+       return data, nil
+
+}
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..a3a8a64 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.
@@ -38,6 +39,7 @@ const (
        ResetRequest                   IncomingRequest = "Reset"
        GetNodebRequest                IncomingRequest = "GetNodebRequest"
        GetNodebIdListRequest          IncomingRequest = "GetNodebIdListRequest"
+       GetNodebIdRequest                  IncomingRequest = "GetNodebIdRequest"
        GetE2TInstancesRequest         IncomingRequest = "GetE2TInstancesRequest"
        UpdateGnbRequest               IncomingRequest = "UpdateGnbRequest"
        UpdateEnbRequest               IncomingRequest = "UpdateEnbRequest"
@@ -69,6 +71,7 @@ func initRequestHandlerMap(logger *logger.Logger, rmrSender *rmrsender.RmrSender
                SetGeneralConfigurationRequest: httpmsghandlers.NewSetGeneralConfigurationHandler(logger, rNibDataService),
                GetNodebRequest:                httpmsghandlers.NewGetNodebRequestHandler(logger, rNibDataService),
                GetNodebIdListRequest:          httpmsghandlers.NewGetNodebIdListRequestHandler(logger, rNibDataService, ranListManager),
+               GetNodebIdRequest:              httpmsghandlers.NewGetNodebIdRequestHandler(logger, ranListManager),
                GetE2TInstancesRequest:         httpmsghandlers.NewGetE2TInstancesRequestHandler(logger, e2tInstancesManager),
                UpdateGnbRequest:               httpmsghandlers.NewUpdateNodebRequestHandler(logger, rNibDataService, updateGnbManager),
                UpdateEnbRequest:               httpmsghandlers.NewUpdateNodebRequestHandler(logger, rNibDataService, updateEnbManager),
index a692db0..db1915a 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,18 @@ func TestShutdownRequestHandler(t *testing.T) {
        assert.True(t, ok)
 }
 
+func TestGetNodebIdRequestHandler(t *testing.T) {
+       provider := setupTest(t)
+       handler, err := provider.GetHandler(GetNodebIdRequest)
+
+       assert.NotNil(t, provider)
+       assert.Nil(t, err)
+
+       _, ok := handler.(*httpmsghandlers.GetNodebIdRequestHandler)
+
+       assert.True(t, ok)
+}
+
 func TestSetGeneralConfigurationHandler(t *testing.T) {
        provider := setupTest(t)
        handler, err := provider.GetHandler(SetGeneralConfigurationRequest)
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)
+}
index 7ee4a30..317a72a 100644 (file)
@@ -1,3 +1,20 @@
+# ==================================================================================
+#       Copyright (c) 2019-2020 Nokia
+#       Copyright (c) 2018-2020 AT&T Intellectual Property.
+#       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.
+# ==================================================================================
 openapi: 3.0.0
 info:
   title: E2 Manager Service
@@ -192,6 +209,37 @@ paths:
             application/problem+json:
               schema:
                 $ref: '#/components/schemas/ErrorResponse'
+  /nodeb/health:
+    put:
+      tags:
+        - nodeb
+      summary: E2 manager is requested to check connectivity with all E2 nodes or a list of E2 nodes
+      requestBody:
+        content:
+          application/json:
+            schema:
+              type: object
+              properties:
+                ranList:
+                  type: array
+                  items:
+                    type: string
+        required: false
+      responses:
+        '202':
+          description: 'Request accepted'
+        '404':
+          description: RAN not found
+          content:
+            application/problem+json:
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
+        '500':
+          description: Internal Error
+          content:
+            application/problem+json:
+              schema:
+                $ref: '#/components/schemas/ErrorResponse' 
   /nodeb/shutdown:
     put:
       tags:
@@ -233,6 +281,37 @@ paths:
             application/problem+json:
               schema:
                 $ref: '#/components/schemas/ErrorResponse'
+  '/nodeb/states/{ranName}':
+    get:
+      summary: E2 manager is requested to report the health status of the connection to the E2 node
+      tags:
+        - nodeb
+      parameters:
+        - name: ranName
+          in: path
+          required: true
+          description: Name of RAN to get Health check
+          schema:
+            type: string
+      responses:
+        '200':
+          description: Successful operation
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/NodebIdentity'
+        '400':
+          description: Invalid input
+          content:
+            application/problem+json:
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
+        '500':
+          description: Internal error
+          content:
+            application/problem+json:
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
   /nodeb/parameters:
     put:
       summary: Update e2mgr configuration
@@ -331,6 +410,10 @@ components:
           type: string
         connectionStatus:
           type: string
+        healthCheckTimestampSent:
+          type: integer
+        healthCheckTimestampReceived:
+          type: integer
       type: object
     ErrorResponse:
       type: object
index 2463903..f1e8b73 100644 (file)
@@ -1,10 +1,10 @@
 ---
 distribution_type: container
-container_release_tag: 5.4.7
+container_release_tag: 5.4.13
 container_pull_registry: nexus3.o-ran-sc.org:10004
 container_push_registry: nexus3.o-ran-sc.org:10002
 project: ric-plt/e2mgr
 ref: bc966a778e96ab13590722c140489e8ef053a6f0
 containers:
     - name: ric-plt-e2mgr
-      version: 5.4.7
+      version: 5.4.13