Copy latest code 01/2101/1
authorss412g <shuky.har-noy@intl.att.com>
Mon, 2 Dec 2019 14:59:19 +0000 (16:59 +0200)
committerss412g <shuky.har-noy@intl.att.com>
Mon, 23 Dec 2019 22:16:34 +0000 (00:16 +0200)
Change-Id: Ibfcfce723adc532458911ec1df798fcd511fddaa
Signed-off-by: ss412g <shuky.har-noy@intl.att.com>
203 files changed:
.gitignore
Automation/Dockerfile
Automation/Tests/ConfigurationUpdate/ConfigurationUpdate_Verify_logs.robot [deleted file]
Automation/Tests/ConfigurationUpdate/ConfigurationUpdate_prepartations_tests.robot
Automation/Tests/E2Term_Initialization/E2Term_Init_Message_Test.robot [new file with mode: 0644]
Automation/Tests/E2Term_Initialization/__init__.robot [new file with mode: 0755]
Automation/Tests/ENDC-Setup/ENDC_Setup_request_test.robot
Automation/Tests/ENDC_Reset_RAN_TO_RIC/Reset_RAN_Found.robot
Automation/Tests/ENDC_Reset_RAN_TO_RIC/Reset_Verify_logs.robot [deleted file]
Automation/Tests/ENDC_Reset_RIC_TO_RAN/Reset_Happy_no_cause.robot
Automation/Tests/ENDC_Reset_RIC_TO_RAN/Reset_Happy_with_cause.robot
Automation/Tests/KeepAlive/__init__.robot [new file with mode: 0755]
Automation/Tests/KeepAlive/keep_alive_test.robot [new file with mode: 0644]
Automation/Tests/LoadInfomation/Loadinformation_adding_data_and_overwrite.robot
Automation/Tests/Lost_Connection/Lost_Connetion_CONNECTING_TO_DISCONNECTED.robot
Automation/Tests/RSM_Resource_Status/__init__.robot [new file with mode: 0755]
Automation/Tests/RSM_Resource_Status/resource_status_false_start.robot [new file with mode: 0644]
Automation/Tests/RSM_Resource_Status/resource_status_false_stop.robot [new file with mode: 0644]
Automation/Tests/RSM_Resource_Status/resource_status_keywords.robot [new file with mode: 0644]
Automation/Tests/RSM_Resource_Status/resource_status_true_start.robot [new file with mode: 0644]
Automation/Tests/RSM_Resource_Status/resource_status_true_stop.robot [new file with mode: 0644]
Automation/Tests/RedButton/RedButton_CONNECTED_SHUTDOWN_CONNECTED.robot
Automation/Tests/RedButton/RedButton_DISCONNECTED.robot
Automation/Tests/Resource/Keywords.robot
Automation/Tests/Resource/resource.robot
Automation/Tests/Resource/scripts_variables.robot
Automation/Tests/Scripts/cleanup_db.py
Automation/Tests/Scripts/e2mdbscripts.py [new file with mode: 0644]
Automation/Tests/Scripts/e2t_db_script.py [new file with mode: 0644]
Automation/Tests/Scripts/find_rmr_message.py
Automation/Tests/Scripts/getnodes.py
Automation/Tests/Scripts/loadscripts.py
Automation/Tests/Scripts/rsmscripts.py [new file with mode: 0644]
Automation/Tests/Unhappy/Reset_HttpResponse400_wrongstate.robot
Automation/Tests/X2-Setup/X2_Setup_reuqest_test.robot
Automation/Tests/X2-Setup/x2_setup_existing_assoc_test.robot [moved from Automation/Tests/X2_Reset_RAN_TO_RIC/Reset_Verify_logs.robot with 55% similarity]
Automation/Tests/X2-Setup/x2_setup_existing_not_assoc_test.robot [new file with mode: 0644]
Automation/Tests/X2_Reset_RAN_TO_RIC/Reset_RAN_Found.robot
Automation/Tests/X2_Reset_RAN_TO_RIC_Unhappy/Reset_RNIB.robot
Automation/Tests/X2_Reset_RAN_TO_RIC_Unhappy/Reset_Verify_logs.robot [deleted file]
Automation/Tests/X2_Reset_RIC_TO_RAN/Reset_Happy_no_cause.robot
Automation/Tests/X2_Reset_RIC_TO_RAN/Reset_Happy_with_cause.robot
E2Manager/Dockerfile
E2Manager/app/main.go
E2Manager/clients/http_client.go [new file with mode: 0644]
E2Manager/clients/routing_manager_client.go [new file with mode: 0644]
E2Manager/clients/routing_manager_client_test.go [new file with mode: 0644]
E2Manager/configuration/configuration.go
E2Manager/configuration/configuration_test.go
E2Manager/container-tag.yaml
E2Manager/controllers/e2t_controller.go [new file with mode: 0644]
E2Manager/controllers/nodeb_controller.go
E2Manager/controllers/nodeb_controller_test.go
E2Manager/controllers/root_controller_test.go
E2Manager/converters/endc_setup_failure_response_converter.go [moved from E2Manager/converters/endc_x2setupFailureResponseToProtobuf.go with 82% similarity]
E2Manager/converters/endc_setup_failure_response_converter_test.go [moved from E2Manager/converters/endc_x2setupFailureResponseToProtobuf_test.go with 93% similarity]
E2Manager/converters/endc_setup_response_converter.go [moved from E2Manager/converters/endc_x2setupResponseToProtobuf.go with 93% similarity]
E2Manager/converters/endc_setup_response_converter_test.go [moved from E2Manager/converters/endc_x2setupResponseToProtobuf_test.go with 99% similarity]
E2Manager/e2managererrors/e2t_instance_absence_error.go [new file with mode: 0644]
E2Manager/e2managererrors/routing_manager_error.go [new file with mode: 0644]
E2Manager/e2mgr-sonar-scanner.properties [new file with mode: 0644]
E2Manager/e2pdus/configuration_update.go [new file with mode: 0644]
E2Manager/e2pdus/configuration_update_test.go [new file with mode: 0644]
E2Manager/e2pdus/x2_setup_requests_test.go
E2Manager/go.mod
E2Manager/go.sum
E2Manager/handlers/httpmsghandlers/delete_all_request_handler_test.go
E2Manager/handlers/httpmsghandlers/get_e2t_instances_request_handler.go [new file with mode: 0644]
E2Manager/handlers/httpmsghandlers/get_e2t_instances_request_handler_test.go [new file with mode: 0644]
E2Manager/handlers/httpmsghandlers/get_nodeb_id_list_request_handler_test.go
E2Manager/handlers/httpmsghandlers/get_nodeb_request_handler_test.go
E2Manager/handlers/httpmsghandlers/setup_request_handler.go
E2Manager/handlers/httpmsghandlers/setup_request_handler_test.go
E2Manager/handlers/httpmsghandlers/x2_reset_request_handler.go
E2Manager/handlers/httpmsghandlers/x2_reset_request_handler_test.go
E2Manager/handlers/rmrmsghandlers/e2_term_init_notification_handler.go
E2Manager/handlers/rmrmsghandlers/e2_term_init_notification_handler_test.go
E2Manager/handlers/rmrmsghandlers/e2t_keep_alive_response_handler.go [new file with mode: 0644]
E2Manager/handlers/rmrmsghandlers/e2t_keep_alive_response_handler_test.go [new file with mode: 0644]
E2Manager/handlers/rmrmsghandlers/enb_load_information_notification_handler.go
E2Manager/handlers/rmrmsghandlers/enb_load_information_notification_handler_test.go
E2Manager/handlers/rmrmsghandlers/endc_configuration_update_handler.go
E2Manager/handlers/rmrmsghandlers/endc_configuration_update_handler_test.go
E2Manager/handlers/rmrmsghandlers/notification_handler.go
E2Manager/handlers/rmrmsghandlers/setup_response_notification_handler_test.go
E2Manager/handlers/rmrmsghandlers/x2_reset_request_notification_handler.go
E2Manager/handlers/rmrmsghandlers/x2_reset_request_notification_handler_test.go
E2Manager/handlers/rmrmsghandlers/x2_reset_response_handler.go
E2Manager/handlers/rmrmsghandlers/x2_reset_response_handler_test.go
E2Manager/handlers/rmrmsghandlers/x2enb_configuration_update_handler.go
E2Manager/handlers/rmrmsghandlers/x2enb_configuration_update_handler_test.go
E2Manager/httpserver/http_server.go
E2Manager/httpserver/http_server_test.go
E2Manager/logger/logger_test.go
E2Manager/managers/e2t_instances_manager.go [new file with mode: 0644]
E2Manager/managers/e2t_instances_manager_test.go [new file with mode: 0644]
E2Manager/managers/e2t_keep_alive_worker.go [new file with mode: 0644]
E2Manager/managers/e2t_keep_alive_worker_test.go [new file with mode: 0644]
E2Manager/managers/e2t_shutdown_manager.go [new file with mode: 0644]
E2Manager/managers/endc_setup_failure_response_manager.go
E2Manager/managers/endc_setup_failure_response_manager_test.go [new file with mode: 0644]
E2Manager/managers/endc_setup_response_manager.go
E2Manager/managers/endc_setup_response_manager_test.go [new file with mode: 0644]
E2Manager/managers/notificationmanager/notification_manager.go
E2Manager/managers/notificationmanager/notification_manager_test.go
E2Manager/managers/ran_reconnection_manager.go
E2Manager/managers/ran_reconnection_manager_test.go
E2Manager/managers/ran_setup_manager.go
E2Manager/managers/ran_setup_manager_test.go
E2Manager/managers/ran_status_change_manager.go
E2Manager/managers/ran_status_change_manager_test.go
E2Manager/managers/x2_setup_failure_response_manager_test.go [new file with mode: 0644]
E2Manager/mocks/controllerMock.go [deleted file]
E2Manager/mocks/e2t_controller_mock.go [new file with mode: 0644]
E2Manager/mocks/e2t_instances_manager_mock.go [new file with mode: 0644]
E2Manager/mocks/e2t_shutdown_manager_mock.go [moved from E2Manager/rnibBuilders/node_info_builder.go with 56% similarity]
E2Manager/mocks/http_client_mock.go [new file with mode: 0644]
E2Manager/mocks/nodebControllerMock.go [deleted file]
E2Manager/mocks/nodeb_controller_mock.go [new file with mode: 0644]
E2Manager/mocks/ran_setup_manager_mock.go [new file with mode: 0644]
E2Manager/mocks/rmrMessengerMock.go
E2Manager/mocks/rnibReaderMock.go
E2Manager/mocks/rnibWriterMock.go
E2Manager/mocks/root_controller_mock.go [new file with mode: 0644]
E2Manager/mocks/routing_manager_client_mock.go [new file with mode: 0644]
E2Manager/models/e2_request_message_test.go
E2Manager/models/e2_term_init_payload.go [new file with mode: 0644]
E2Manager/models/e2t_keep_alive_payload.go [new file with mode: 0644]
E2Manager/models/get_e2t_instances_response.go [new file with mode: 0644]
E2Manager/models/get_nodeb_id_list_response.go
E2Manager/models/get_nodeb_response.go
E2Manager/models/i_response.go
E2Manager/models/notification_request.go
E2Manager/models/rmr_message.go
E2Manager/models/routing_manager_e2t_data.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/rNibWriter/rNibWriter.go
E2Manager/rNibWriter/rNibWriter_test.go
E2Manager/resources/configuration.yaml
E2Manager/rmrCgo/rmrCgoApi.go
E2Manager/rmrCgo/rmrCgoApi_test.go
E2Manager/rmrCgo/rmrCgoTypes.go
E2Manager/rnibBuilders/node_info_builder_test.go [deleted file]
E2Manager/router.txt
E2Manager/router_test.txt [new file with mode: 0644]
E2Manager/services/rmrreceiver/rmr_receiver.go
E2Manager/services/rmrreceiver/rmr_receiver_test.go
E2Manager/services/rmrsender/rmr_sender.go
E2Manager/services/rmrsender/rmr_sender_test.go
E2Manager/services/rnib_data_service.go
E2Manager/services/rnib_data_service_test.go
E2Manager/tests/dataProvider.go
E2Manager/tests/utils.go [new file with mode: 0644]
Swagger/E2Manager_API.yaml
docs/release-notes.rst
tools/RoutingManagerSimulator/Dockerfile [new file with mode: 0644]
tools/RoutingManagerSimulator/api/swagger.yaml [new file with mode: 0755]
tools/RoutingManagerSimulator/configuration/configuration.go [new file with mode: 0644]
tools/RoutingManagerSimulator/configuration/configuration_test.go [new file with mode: 0644]
tools/RoutingManagerSimulator/go.mod [new file with mode: 0644]
tools/RoutingManagerSimulator/go.sum [new file with mode: 0644]
tools/RoutingManagerSimulator/go/api_handle.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/api_health.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/logger.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/model_e2t_data.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/model_e2t_delete_data.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/model_health_status.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/model_ran_e2t_element.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/model_ran_e2t_map.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/model_ran_namelist.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/model_xapp_callback_data.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/model_xapp_element.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/model_xapp_list.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/model_xapp_subscription_data.go [new file with mode: 0755]
tools/RoutingManagerSimulator/go/routers.go [new file with mode: 0755]
tools/RoutingManagerSimulator/main.go [new file with mode: 0755]
tools/RoutingManagerSimulator/resources/configuration.yaml [new file with mode: 0644]
tools/xapp_mock/configuration.json [deleted file]
tools/xapp_mock/main/xapp_mock.go [deleted file]
tools/xapp_mock/resources/router.txt [deleted file]
tools/xappmock/Dockerfile [moved from tools/xapp_mock/Dockerfile with 68% similarity]
tools/xappmock/dispatcher/dispatcher.go [new file with mode: 0644]
tools/xappmock/enums/command_action.go [new file with mode: 0644]
tools/xappmock/frontend/configfile.go [moved from tools/xapp_mock/frontend/configfile.go with 92% similarity]
tools/xappmock/frontend/jsonDecoder.go [moved from tools/xapp_mock/frontend/jsonDecoder.go with 60% similarity]
tools/xappmock/go.mod [new file with mode: 0644]
tools/xappmock/go.sum [new file with mode: 0644]
tools/xappmock/logger/logger.go [new file with mode: 0644]
tools/xappmock/main/xappmock.go [new file with mode: 0644]
tools/xappmock/models/json_command.go [new file with mode: 0644]
tools/xappmock/models/message_info.go [new file with mode: 0644]
tools/xappmock/models/process_result.go [new file with mode: 0644]
tools/xappmock/resources/conf/configuration.json [new file with mode: 0644]
tools/xappmock/resources/router.txt [new file with mode: 0644]
tools/xappmock/resp [moved from tools/xapp_mock/resp with 100% similarity]
tools/xappmock/rmr/rmrCgoApi.go [moved from tools/xapp_mock/rmr/rmrCgoApi.go with 92% similarity]
tools/xappmock/rmr/rmrCgoTypes.go [moved from tools/xapp_mock/rmr/rmrCgoTypes.go with 97% similarity]
tools/xappmock/rmr/rmrCgoUtils.go [moved from tools/xapp_mock/rmr/rmrCgoUtils.go with 83% similarity]
tools/xappmock/rmr/rmrEndPoint.go [moved from tools/xapp_mock/rmr/rmrEndPoint.go with 65% similarity]
tools/xappmock/sender/jsonSender.go [moved from tools/xapp_mock/sender/jsonSender.go with 69% similarity]

index 53691a3..0baa305 100644 (file)
@@ -11,3 +11,4 @@ __pycache__/
 # documentation
 .tox
 docs/_build/
 # documentation
 .tox
 docs/_build/
+/.gitreview
index 6733a6b..e981b44 100755 (executable)
@@ -3,6 +3,7 @@ FROM python:3.6
 RUN python3 -m pip install robotframework \
     && pip install --upgrade RESTinstance \
     && pip install docker \
 RUN python3 -m pip install robotframework \
     && pip install --upgrade RESTinstance \
     && pip install docker \
+    && pip install -U robotframework-requests\
     && apt-get update 
 
 WORKDIR /opt
     && apt-get update 
 
 WORKDIR /opt
diff --git a/Automation/Tests/ConfigurationUpdate/ConfigurationUpdate_Verify_logs.robot b/Automation/Tests/ConfigurationUpdate/ConfigurationUpdate_Verify_logs.robot
deleted file mode 100644 (file)
index 5e2933e..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-##############################################################################
-#
-#   Copyright (c) 2019 AT&T Intellectual Property.
-#
-#   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 ***
-Resource   ../Resource/resource.robot
-Resource    ../Resource/scripts_variables.robot
-Library     String
-Library     OperatingSystem
-Library     Process
-Library     ../Scripts/find_rmr_message.py
-
-
-
-*** Test Cases ***
-Verify logs - Confiugration update - Begin Tag Get
-    ${Configuration}=   Grep File  ./gnb.log  <ENDCConfigurationUpdate>
-    ${ConfigurationAfterStrip}=     Strip String    ${Configuration}
-    Should Be Equal     ${ConfigurationAfterStrip}        <ENDCConfigurationUpdate>
-
-Verify logs - Confiugration update - End Tag Get
-    ${ConfigurationEnd}=   Grep File  ./gnb.log  </ENDCConfigurationUpdate>
-    ${ConfigurationEndAfterStrip}=     Strip String    ${ConfigurationEnd}
-    Should Be Equal     ${ConfigurationEndAfterStrip}        </ENDCConfigurationUpdate>
-
-Verify logs - Confiugration update - Ack Tag Begin
-    ${ConfigurationAck}=   Grep File  ./gnb.log   <ENDCConfigurationUpdateAcknowledge>
-    ${ConfigurationAckAfter}=     Strip String    ${ConfigurationAck}
-    Should Be Equal     ${ConfigurationAckAfter}        <ENDCConfigurationUpdateAcknowledge>
-
-Verify logs - Confiugration update - Ack Tag End
-    ${ConfigurationAckEnd}=   Grep File  ./gnb.log  </ENDCConfigurationUpdateAcknowledge>
-    ${ConfigurationAckEndAfterStrip}=     Strip String    ${ConfigurationAckEnd}
-    Should Be Equal     ${ConfigurationAckEndAfterStrip}        </ENDCConfigurationUpdateAcknowledge>
-
-Verify logs - find RIC_ENDC_CONF_UPDATE
-   ${result}   find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${configurationupdate_message_type}  ${Meid_test1}
-   Should Be Equal As Strings    ${result}      True
-Verify logs - find RIC_ENDC_CONF_UPDATE_ACK
-   ${result1}  find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${configurationupdate_ack_message_type}  ${Meid_test1}
-   Should Be Equal As Strings    ${result1}      True
index a2b741a..f833a3e 100644 (file)
@@ -27,7 +27,10 @@ Resource   ../Resource/resource.robot
 Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     REST      ${url}
 Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     REST      ${url}
-
+Resource    ../Resource/scripts_variables.robot
+Library     String
+Library     Process
+Library     ../Scripts/find_rmr_message.py
 
 
 *** Test Cases ***
 
 
 *** Test Cases ***
@@ -45,8 +48,32 @@ Prepare logs for tests
     Remove log files
     Save logs
 
     Remove log files
     Save logs
 
-
-
+Verify logs - Confiugration update - Begin Tag Get
+    ${Configuration}=   Grep File  ./${gnb_log_filename}  <ENDCConfigurationUpdate>
+    ${ConfigurationAfterStrip}=     Strip String    ${Configuration}
+    Should Be Equal     ${ConfigurationAfterStrip}        <ENDCConfigurationUpdate>
+
+Verify logs - Confiugration update - End Tag Get
+    ${ConfigurationEnd}=   Grep File  ./${gnb_log_filename}  </ENDCConfigurationUpdate>
+    ${ConfigurationEndAfterStrip}=     Strip String    ${ConfigurationEnd}
+    Should Be Equal     ${ConfigurationEndAfterStrip}        </ENDCConfigurationUpdate>
+
+Verify logs - Confiugration update - Ack Tag Begin
+    ${ConfigurationAck}=   Grep File  ./${gnb_log_filename}   <ENDCConfigurationUpdateAcknowledge>
+    ${ConfigurationAckAfter}=     Strip String    ${ConfigurationAck}
+    Should Be Equal     ${ConfigurationAckAfter}        <ENDCConfigurationUpdateAcknowledge>
+
+Verify logs - Confiugration update - Ack Tag End
+    ${ConfigurationAckEnd}=   Grep File  ./${gnb_log_filename}  </ENDCConfigurationUpdateAcknowledge>
+    ${ConfigurationAckEndAfterStrip}=     Strip String    ${ConfigurationAckEnd}
+    Should Be Equal     ${ConfigurationAckEndAfterStrip}        </ENDCConfigurationUpdateAcknowledge>
+
+Verify logs - find RIC_ENDC_CONF_UPDATE
+   ${result}   find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${configurationupdate_message_type}  ${Meid_test1}
+   Should Be Equal As Strings    ${result}      True
+Verify logs - find RIC_ENDC_CONF_UPDATE_ACK
+   ${result1}  find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${configurationupdate_ack_message_type}  ${Meid_test1}
+   Should Be Equal As Strings    ${result1}      True
 
 
 
 
 
 
diff --git a/Automation/Tests/E2Term_Initialization/E2Term_Init_Message_Test.robot b/Automation/Tests/E2Term_Initialization/E2Term_Init_Message_Test.robot
new file mode 100644 (file)
index 0000000..3ce8a50
--- /dev/null
@@ -0,0 +1,37 @@
+*** Settings ***
+Suite Setup   Prepare Enviorment
+Resource   ../Resource/resource.robot
+Resource   ../Resource/Keywords.robot
+Resource    ../Resource/scripts_variables.robot
+Library     OperatingSystem
+Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/cleanup_db.py
+Library     ../Scripts/e2t_db_script.py
+
+*** Test Cases ***
+
+Test New E2T Send Init
+    Stop E2
+
+    ${result}=    cleanup_db.flush_and_restore_without_e2t_keys
+    Should Be Equal As Strings  ${result}    True
+
+    Start E2
+
+prepare logs for tests
+    Remove log files
+    Save logs
+
+E2M Logs - Verify RMR Message
+    ${result}    find_rmr_message.verify_logs   ${EXECDIR}   ${e2mgr_log_filename}  ${E2_INIT_message_type}    ${None}
+    Should Be Equal As Strings    ${result}      True
+
+Verify E2T keys in DB
+    ${result}=    e2t_db_script.verify_e2t_addresses_key
+    Should Be Equal As Strings  ${result}    True
+
+    ${result}=    e2t_db_script.verify_e2t_instance_key
+    Should Be Equal As Strings  ${result}    True
+
+
+
diff --git a/Automation/Tests/E2Term_Initialization/__init__.robot b/Automation/Tests/E2Term_Initialization/__init__.robot
new file mode 100755 (executable)
index 0000000..7112a73
--- /dev/null
@@ -0,0 +1,20 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+*** Settings ***
+Documentation    E2Term-Initialization
index 1c75542..13ef989 100644 (file)
@@ -27,6 +27,7 @@ Resource   ../Resource/Keywords.robot
 Resource    ../Resource/scripts_variables.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
 Resource    ../Resource/scripts_variables.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/rsmscripts.py
 Library     REST        ${url}
 
 
 Library     REST        ${url}
 
 
@@ -70,5 +71,7 @@ RSM RESOURCE STATUS REQUEST message not sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test2}
     Should Be Equal As Strings    ${result}      False
 
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test2}
     Should Be Equal As Strings    ${result}      False
 
-
+Verify RSM RAN info doesn't exist in redis
+   ${result}=   rsmscripts.verify_rsm_ran_info_start_false
+   Should Be Equal As Strings  ${result}    False
 
 
index 089c1a7..9215ebc 100644 (file)
@@ -27,19 +27,26 @@ Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     Collections
 Library     REST      ${url}
 Library     OperatingSystem
 Library     Collections
 Library     REST      ${url}
-
-
-
+Resource    ../Resource/scripts_variables.robot
+Library     String
+Library     Process
+Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/find_error_script.py
+Library     ../Scripts/rsmscripts.py
 
 *** Test Cases ***
 
 Prepare Ran in Connected connectionStatus
 
 *** Test Cases ***
 
 Prepare Ran in Connected connectionStatus
-    Post Request setup node b endc-setup
+#    Post Request setup node b endc-setup
+    Set Headers     ${header}
+    POST        /v1/nodeb/endc-setup    ${json}
     Integer     response status       204
     Sleep  1s
     Integer     response status       204
     Sleep  1s
-    GET      /v1/nodeb/test2
+#    GET      /v1/nodeb/test2
+    GET      /v1/nodeb/test1
     Integer  response status  200
     Integer  response status  200
-    String   response body ranName    test2
+#    String   response body ranName    test2
+    String   response body ranName    test1
     String   response body connectionStatus    CONNECTED
 
 Run Reset from RAN
     String   response body connectionStatus    CONNECTED
 
 Run Reset from RAN
@@ -50,3 +57,30 @@ Prepare logs for tests
     Remove log files
     Save logs
 
     Remove log files
     Save logs
 
+#Verify logs - Reset Sent by e2adapter
+#    ${result}    find_error_script.find_error  ${EXECDIR}  ${e2adapter_log_filename}  ${E2ADAPTER_Setup_Resp}
+#    Should Be Equal As Strings    ${result}      True
+
+Verify logs - Reset Sent by simulator
+    ${Reset}=   Grep File  ./${gnb_log_filename}  ResetRequest has been sent
+    Should Be Equal     ${Reset}     gnbe2_simu: ResetRequest has been sent
+
+Verify logs - e2mgr logs - messege sent
+    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RIC_X2_RESET_REQ_message_type}  ${Meid_test1}
+    Should Be Equal As Strings    ${result}      True
+
+Verify logs - e2mgr logs - messege received
+    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RIC_X2_RESET_RESP_message_type}  ${Meid_test1}
+    Should Be Equal As Strings    ${result}      True
+
+RAN Restarted messege sent
+    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RAN_RESTARTED_message_type}  ${Meid_test1}
+    Should Be Equal As Strings    ${result}      True
+
+RSM RESOURCE STATUS REQUEST message not sent
+    ${result}    find_rmr_message.verify_logs  ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test2}
+    Should Be Equal As Strings    ${result}      False
+
+Verify RSM RAN info doesn't exist in redis
+   ${result}=   rsmscripts.verify_rsm_ran_info_start_false
+   Should Be Equal As Strings  ${result}    False
\ No newline at end of file
diff --git a/Automation/Tests/ENDC_Reset_RAN_TO_RIC/Reset_Verify_logs.robot b/Automation/Tests/ENDC_Reset_RAN_TO_RIC/Reset_Verify_logs.robot
deleted file mode 100644 (file)
index 6aeb109..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-##############################################################################
-#
-#   Copyright (c) 2019 AT&T Intellectual Property.
-#
-#   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 ***
-Resource    ../Resource/scripts_variables.robot
-Resource   ../Resource/Keywords.robot
-Library     String
-Library     OperatingSystem
-Library     Process
-Library     ../Scripts/find_rmr_message.py
-Library     ../Scripts/find_error_script.py
-
-
-
-*** Test Cases ***
-Verify logs - Reset Sent by e2adapter
-    ${result}    find_error_script.find_error  ${EXECDIR}  ${e2adapter_log_filename}  ${E2ADAPTER_Setup_Resp}
-    Should Be Equal As Strings    ${result}      True
-
-Verify logs - e2mgr logs - messege sent
-    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RIC_X2_RESET_REQ_message_type}  ${Meid_test1}
-    Should Be Equal As Strings    ${result}      True
-
-Verify logs - e2mgr logs - messege received
-    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RIC_X2_RESET_RESP_message_type}  ${Meid_test1}
-    Should Be Equal As Strings    ${result}      True
-
-RAN Restarted messege sent
-    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RAN_RESTARTED_message_type}  ${Meid_test1}
-    Should Be Equal As Strings    ${result}      True
-
-RSM RESOURCE STATUS REQUEST message not sent
-    ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test2}
-    Should Be Equal As Strings    ${result}      False
\ No newline at end of file
index 9010a68..a3ecabe 100644 (file)
@@ -27,6 +27,7 @@ Resource   ../Resource/resource.robot
 Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
 Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/rsmscripts.py
 Library     REST      ${url}
 
 
 Library     REST      ${url}
 
 
@@ -57,4 +58,8 @@ RAN Restarted messege sent
 
 RSM RESOURCE STATUS REQUEST message not sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test2}
 
 RSM RESOURCE STATUS REQUEST message not sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test2}
-    Should Be Equal As Strings    ${result}      False
\ No newline at end of file
+    Should Be Equal As Strings    ${result}      False
+
+Verify RSM RAN info doesn't exist in redis
+   ${result}=   rsmscripts.verify_rsm_ran_info_start_false
+   Should Be Equal As Strings  ${result}    False
index e6b2492..2e5a003 100644 (file)
@@ -27,6 +27,7 @@ Resource   ../Resource/resource.robot
 Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
 Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/rsmscripts.py
 Library     REST      ${url}
 
 
 Library     REST      ${url}
 
 
@@ -58,4 +59,8 @@ RAN Restarted messege sent
 
 RSM RESOURCE STATUS REQUEST message not sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test2}
 
 RSM RESOURCE STATUS REQUEST message not sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test2}
-    Should Be Equal As Strings    ${result}      False
\ No newline at end of file
+    Should Be Equal As Strings    ${result}      False
+
+Verify RSM RAN info doesn't exist in redis
+   ${result}=   rsmscripts.verify_rsm_ran_info_start_false
+   Should Be Equal As Strings  ${result}    False
\ No newline at end of file
diff --git a/Automation/Tests/KeepAlive/__init__.robot b/Automation/Tests/KeepAlive/__init__.robot
new file mode 100755 (executable)
index 0000000..6826893
--- /dev/null
@@ -0,0 +1,20 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+*** Settings ***
+Documentation    Keep Alive
diff --git a/Automation/Tests/KeepAlive/keep_alive_test.robot b/Automation/Tests/KeepAlive/keep_alive_test.robot
new file mode 100644 (file)
index 0000000..ac226a2
--- /dev/null
@@ -0,0 +1,43 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+*** Settings ***
+Suite Setup   Prepare Enviorment
+Resource   ../Resource/resource.robot
+Resource   ../Resource/Keywords.robot
+Resource   ../Resource/scripts_variables.robot
+Library    ../Scripts/find_error_script.py
+Library    OperatingSystem
+Library    Collections
+
+
+*** Test Cases ***
+
+Stop E2T
+    stop_e2
+    Sleep  1s
+
+Prepare logs for tests
+    Remove log files
+    Save logs
+
+Verify Is Dead Message Printed
+    ${result}    find_error_script.find_error     ${EXECDIR}    ${e2mgr_log_filename}  ${e2_is_dead_message_printed}
+    Should Be Equal As Strings    ${result}      True
+
+Start E2T
+    start_e2
\ No newline at end of file
index f2e589c..32e81b9 100644 (file)
@@ -50,7 +50,7 @@ Trigger X-2 Setup for load information
     String   response body connectionStatus    CONNECTED
 
 
     String   response body connectionStatus    CONNECTED
 
 
-Verify Load information does exist in redis
+Verify Load information exists in redis
    ${result}=   loadscripts.verify_value
    Should Be Equal As Strings  ${result}    True
 
    ${result}=   loadscripts.verify_value
    Should Be Equal As Strings  ${result}    True
 
index 805d648..90002eb 100644 (file)
@@ -52,7 +52,7 @@ Prepare Ran in Connecting connectionStatus
 
 
 Verfiy Disconnected ConnectionStatus
 
 
 Verfiy Disconnected ConnectionStatus
-    Sleep    1s
+    Sleep    10s
     GET      /v1/nodeb/test1
     Integer  response status  200
     String   response body ranName    test1
     GET      /v1/nodeb/test1
     Integer  response status  200
     String   response body ranName    test1
diff --git a/Automation/Tests/RSM_Resource_Status/__init__.robot b/Automation/Tests/RSM_Resource_Status/__init__.robot
new file mode 100755 (executable)
index 0000000..4a008d9
--- /dev/null
@@ -0,0 +1,20 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+*** Settings ***
+Documentation    Resource status
diff --git a/Automation/Tests/RSM_Resource_Status/resource_status_false_start.robot b/Automation/Tests/RSM_Resource_Status/resource_status_false_start.robot
new file mode 100644 (file)
index 0000000..e6b969a
--- /dev/null
@@ -0,0 +1,56 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+*** Settings ***
+Suite Setup   Prepare Enviorment
+Resource   ../Resource/resource.robot
+Resource   ../Resource/Keywords.robot
+Resource   ../Resource/scripts_variables.robot
+Resource   resource_status_keywords.robot
+Library    ../Scripts/rsmscripts.py
+Library     ../Scripts/find_rmr_message.py
+Library    OperatingSystem
+Library    REST      ${url_rsm}
+Suite Teardown  Delete All Sessions
+
+
+*** Test Cases ***
+Run setup
+    rsmscripts.set_general_config_resource_status_false
+
+    Prepare Ran In Connected Status
+
+Put Http Start Request To RSM
+    Put Request Resource Status Start
+    Integer  response status  204
+
+Verify RSM RAN Info Status Is Start And True In Redis
+    ${result}=   rsmscripts.verify_rsm_ran_info_start_true
+    Should Be Equal As Strings  ${result}    True
+
+Verify RSM Enable Resource Status Is True In General Configuration In Redis
+    ${result}=   rsmscripts.verify_general_config_enable_resource_status_true
+    Should Be Equal As Strings  ${result}    True
+    
+prepare logs for tests
+    Remove log files
+    Save logs
+
+Verify RSM Resource Status Request Message Sent
+    ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
+    Should Be Equal As Strings    ${result}      True
\ No newline at end of file
diff --git a/Automation/Tests/RSM_Resource_Status/resource_status_false_stop.robot b/Automation/Tests/RSM_Resource_Status/resource_status_false_stop.robot
new file mode 100644 (file)
index 0000000..9864e3e
--- /dev/null
@@ -0,0 +1,56 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+*** Settings ***
+Suite Setup   Prepare Enviorment
+Resource   ../Resource/resource.robot
+Resource   ../Resource/Keywords.robot
+Resource   ../Resource/scripts_variables.robot
+Resource   resource_status_keywords.robot
+Library    ../Scripts/rsmscripts.py
+Library     ../Scripts/find_rmr_message.py
+Library    OperatingSystem
+Library    REST      ${url_rsm}
+Suite Teardown  Delete All Sessions
+
+
+*** Test Cases ***
+Run setup
+    rsmscripts.set_general_config_resource_status_false
+
+    Prepare Ran In Connected Status
+
+Put Http Stop Request To RSM
+    Put Request Resource Status Stop
+    Integer  response status  204
+
+Verify RSM RAN Info Status Is Stop And True In Redis
+    ${result}=   rsmscripts.verify_rsm_ran_info_stop_true
+    Should Be Equal As Strings  ${result}    True
+
+Verify RSM Enable Resource Status Is False In General Configuration In Redis
+    ${result}=   rsmscripts.verify_general_config_enable_resource_status_false
+    Should Be Equal As Strings  ${result}    True
+    
+prepare logs for tests
+    Remove log files
+    Save logs
+
+Verify RSM Resource Status Request Message Not Sent
+    ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
+    Should Be Equal As Strings    ${result}      False
\ No newline at end of file
diff --git a/Automation/Tests/RSM_Resource_Status/resource_status_keywords.robot b/Automation/Tests/RSM_Resource_Status/resource_status_keywords.robot
new file mode 100644 (file)
index 0000000..2dc0ec2
--- /dev/null
@@ -0,0 +1,36 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+*** Settings ***
+Documentation   Keywords file
+Library     ../Scripts/cleanup_db.py
+Resource   ../Resource/resource.robot
+Library    Collections
+Library    OperatingSystem
+Library    json
+Library    RequestsLibrary
+
+
+
+*** Keywords ***
+Prepare Ran In Connected Status
+    Create Session  x2setup  ${url}
+    ${headers}=  Create Dictionary    Accept=application/json    Content-Type=application/json
+    ${resp}=    Post Request   x2setup    /v1/nodeb/x2-setup    data=${json_setup_rsm_tests}    headers=${headers}
+    Should Be Equal As Strings    ${resp.status_code}    204
+
diff --git a/Automation/Tests/RSM_Resource_Status/resource_status_true_start.robot b/Automation/Tests/RSM_Resource_Status/resource_status_true_start.robot
new file mode 100644 (file)
index 0000000..21f9217
--- /dev/null
@@ -0,0 +1,54 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+*** Settings ***
+Suite Setup   Prepare Enviorment
+Resource   ../Resource/resource.robot
+Resource   ../Resource/Keywords.robot
+Resource   ../Resource/scripts_variables.robot
+Resource   resource_status_keywords.robot
+Library    ../Scripts/rsmscripts.py
+Library     ../Scripts/find_rmr_message.py
+Library    OperatingSystem
+Library    REST      ${url_rsm}
+Suite Teardown  Delete All Sessions
+
+
+*** Test Cases ***
+Run setup
+    Prepare Ran In Connected Status
+
+Put Http Start Request To RSM
+    Put Request Resource Status Start
+    Integer  response status  204
+
+Verify RSM RAN Info Status Is Start And True In Redis
+    ${result}=   rsmscripts.verify_rsm_ran_info_start_true
+    Should Be Equal As Strings  ${result}    True
+
+Verify RSM Enable Resource Status Is True In General Configuration In Redis
+    ${result}=   rsmscripts.verify_general_config_enable_resource_status_true
+    Should Be Equal As Strings  ${result}    True
+    
+prepare logs for RSM tests
+    Remove log files
+    Save logs
+
+Verify RSM Resource Status Request Message Sent
+    ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
+    Should Be Equal As Strings    ${result}      True
\ No newline at end of file
diff --git a/Automation/Tests/RSM_Resource_Status/resource_status_true_stop.robot b/Automation/Tests/RSM_Resource_Status/resource_status_true_stop.robot
new file mode 100644 (file)
index 0000000..32cab38
--- /dev/null
@@ -0,0 +1,54 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+*** Settings ***
+Suite Setup   Prepare Enviorment
+Resource   ../Resource/resource.robot
+Resource   ../Resource/Keywords.robot
+Resource   ../Resource/scripts_variables.robot
+Resource   resource_status_keywords.robot
+Library    ../Scripts/rsmscripts.py
+Library     ../Scripts/find_rmr_message.py
+Library    OperatingSystem
+Library    REST      ${url_rsm}
+Suite Teardown  Delete All Sessions
+
+
+*** Test Cases ***
+Run setup
+    Prepare Ran In Connected Status
+
+Put Http Stop Request To RSM
+    Put Request Resource Status Stop
+    Integer  response status  204
+
+#Verify RSM RAN Info Status Is Stop And False In Redis
+#${result}=   rsmscripts.verify_rsm_ran_info_stop_false
+#Should Be Equal As Strings  ${result}    True
+
+Verify RSM Enable Resource Status Is False In General Configuration In Redis
+    ${result}=   rsmscripts.verify_general_config_enable_resource_status_false
+    Should Be Equal As Strings  ${result}    True
+
+prepare logs for tests
+    Remove log files
+    Save logs
+
+Verify RSM Resource Status Request Message Sent
+    ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
+    Should Be Equal As Strings    ${result}      True
\ No newline at end of file
index 77bfb52..04dee6d 100644 (file)
@@ -29,9 +29,6 @@ Library     Collections
 Library     REST      ${url}
 
 
 Library     REST      ${url}
 
 
-*** Variables ***
-${restart_docker_sim}      docker restart gnbe2_simu
-
 
 *** Test Cases ***
 
 
 *** Test Cases ***
 
@@ -59,11 +56,7 @@ Verfiy Shutdown ConnectionStatus
     String   response body connectionStatus    SHUT_DOWN
 
 Restart simualtor
     String   response body connectionStatus    SHUT_DOWN
 
 Restart simualtor
-
-    Run And Return Rc And Output    ${restart_docker_sim}
-    ${result}=  Run And Return Rc And Output     ${docker_command}
-    Should Be Equal As Integers    ${result[1]}    ${docker_number}
-
+    Restart simulator
 
 repare Ran in Connected connectionStatus
     Post Request setup node b x-2
 
 repare Ran in Connected connectionStatus
     Post Request setup node b x-2
index c6bf324..547d14b 100644 (file)
@@ -43,7 +43,7 @@ Pre Condition for Connecting - no E2ADAPTER
 Prepare Ran in Connecting connectionStatus
     Post Request setup node b endc-setup
     Integer     response status       204
 Prepare Ran in Connecting connectionStatus
     Post Request setup node b endc-setup
     Integer     response status       204
-    Sleep  1s
+    Sleep  10s
     GET      /v1/nodeb/test2
     Integer  response status  200
     String   response body ranName    test2
     GET      /v1/nodeb/test2
     Integer  response status  200
     String   response body ranName    test2
index 6ed5617..2593c5f 100644 (file)
@@ -36,6 +36,14 @@ Post Request setup node b x-2
     POST        /v1/nodeb/x2-setup    ${json}
 
 
     POST        /v1/nodeb/x2-setup    ${json}
 
 
+Put Request Resource Status Start
+    Set Headers     ${header}
+    PUT        /v1/general/resourcestatus  ${resource_status_start_json}
+
+
+Put Request Resource Status Stop
+    Set Headers     ${header}
+    PUT        /v1/general/resourcestatus  ${resource_status_stop_json}
 
 Get Request node b enb test1
     Sleep    1s
 
 Get Request node b enb test1
     Sleep    1s
@@ -50,14 +58,20 @@ Get Request node b enb test2
 Remove log files
     Remove File  ${EXECDIR}/${gnb_log_filename}
     Remove File  ${EXECDIR}/${e2mgr_log_filename}
 Remove log files
     Remove File  ${EXECDIR}/${gnb_log_filename}
     Remove File  ${EXECDIR}/${e2mgr_log_filename}
+    Remove File  ${EXECDIR}/${e2t_log_filename}
     Remove File  ${EXECDIR}/${rsm_log_filename}
     Remove File  ${EXECDIR}/${rsm_log_filename}
+    Remove File  ${EXECDIR}/${e2e_simu_log_filename}
+    Remove File  ${EXECDIR}/${rm_sim_log_filename}
     Remove File  ${EXECDIR}/${e2adapter_log_filename}
 
 Save logs
     Sleep   1s
     Run     ${Save_sim_log}
     Run     ${Save_e2mgr_log}
     Remove File  ${EXECDIR}/${e2adapter_log_filename}
 
 Save logs
     Sleep   1s
     Run     ${Save_sim_log}
     Run     ${Save_e2mgr_log}
+    Run     ${Save_e2t_log}
     Run     ${Save_rsm_log}
     Run     ${Save_rsm_log}
+    Run     ${Save_e2e_simu_log}
+    Run     ${Save_rm_sim_log}
     Run     ${Save_e2adapter_log}
 
 
     Run     ${Save_e2adapter_log}
 
 
@@ -69,6 +83,7 @@ Stop Simulator
     Run And Return Rc And Output    ${stop_simu}
 
 
     Run And Return Rc And Output    ${stop_simu}
 
 
+
 Prepare Simulator For Load Information
      Run And Return Rc And Output    ${stop_simu}
      Run And Return Rc And Output    ${docker_Remove}
 Prepare Simulator For Load Information
      Run And Return Rc And Output    ${stop_simu}
      Run And Return Rc And Output    ${docker_Remove}
@@ -79,11 +94,44 @@ Prepare Simulator For Load Information
      Should Be Equal As Integers    ${result[1]}    ${docker_number}
 
 Prepare Enviorment
      Should Be Equal As Integers    ${result[1]}    ${docker_number}
 
 Prepare Enviorment
+     ${starting_timestamp}    Evaluate   datetime.datetime.now(datetime.timezone.utc).isoformat("T")   modules=datetime 
+     ${e2t_log_filename}      Evaluate      "e2t.${SUITE NAME}.log".replace(" ","-")
+     ${e2mgr_log_filename}    Evaluate      "e2mgr.${SUITE NAME}.log".replace(" ","-")
+     ${gnb_log_filename}      Evaluate      "gnb.${SUITE NAME}.log".replace(" ","-")
+     ${rsm_log_filename}      Evaluate      "rsm.${SUITE NAME}.log".replace(" ","-")
+     ${e2e_simu_log_filename}      Evaluate      "e2e_simu.${SUITE NAME}.log".replace(" ","-")
+     ${rm_sim_log_filename}   Evaluate      "rm_sim.${SUITE NAME}.log".replace(" ","-")
+     ${e2adapter_log_filename}    Evaluate  "e2adapter.${SUITE NAME}.log".replace(" ","-")
+     ${Save_sim_log}          Evaluate   'docker logs --since ${starting_timestamp} gnbe2_simu > ${gnb_log_filename}'
+     ${Save_e2mgr_log}        Evaluate   'docker logs --since ${starting_timestamp} e2mgr > ${e2mgr_log_filename}'
+     ${Save_e2t_log}          Evaluate   'docker logs --since ${starting_timestamp} e2 > ${e2t_log_filename}'
+     ${Save_rsm_log}          Evaluate   'docker logs --since ${starting_timestamp} rsm > ${rsm_log_filename}'
+     ${Save_e2e_simu_log}     Evaluate   'docker logs --since ${starting_timestamp} e2e_simu > ${e2e_simu_log_filename}'
+     ${Save_rm_sim_log}       Evaluate   'docker logs --since ${starting_timestamp} rm_sim > ${rm_sim_log_filename}'
+     ${Save_e2adapter_log}    Evaluate   'docker logs --since ${starting_timestamp} e2adapter > ${e2adapter_log_filename}'
+     Set Suite Variable  ${e2t_log_filename}  
+     Set Suite Variable  ${e2mgr_log_filename}  
+     Set Suite Variable  ${gnb_log_filename}   
+     Set Suite Variable  ${rsm_log_filename}  
+     Set Suite Variable  ${e2e_simu_log_filename}
+     Set Suite Variable  ${rm_sim_log_filename}
+     Set Suite Variable  ${e2adapter_log_filename} 
+     Set Suite Variable  ${Save_sim_log}
+     Set Suite Variable  ${Save_e2mgr_log}
+     Set Suite Variable  ${Save_e2t_log}
+     Set Suite Variable  ${Save_rsm_log}
+     Set Suite Variable  ${Save_e2e_simu_log}
+     Set Suite Variable  ${Save_rm_sim_log}
+     Set Suite Variable  ${Save_e2adapter_log}
+       
      ${flush}  cleanup_db.flush
      Should Be Equal As Strings  ${flush}  True
      Run And Return Rc And Output    ${stop_simu}
      ${flush}  cleanup_db.flush
      Should Be Equal As Strings  ${flush}  True
      Run And Return Rc And Output    ${stop_simu}
+     Run And Return Rc And Output    ${stop_e2e_simu}
      Run And Return Rc And Output    ${docker_Remove}
      Run And Return Rc And Output    ${docker_Remove}
+     Run And Return Rc And Output    ${docker_remove_e2e_simu}
      Run And Return Rc And Output    ${run_simu_regular}
      Run And Return Rc And Output    ${run_simu_regular}
+     Run And Return Rc And Output    ${run_e2e_simu_regular}
      Run And Return Rc And Output    ${restart_e2adapter}
      Sleep  2s
      ${result}=  Run And Return Rc And Output     ${docker_command}
      Run And Return Rc And Output    ${restart_e2adapter}
      Sleep  2s
      ${result}=  Run And Return Rc And Output     ${docker_command}
@@ -95,6 +143,12 @@ Start E2
      Should Be Equal As Integers    ${result[1]}    ${docker_number}
      Sleep  2s
 
      Should Be Equal As Integers    ${result[1]}    ${docker_number}
      Sleep  2s
 
+Stop E2
+     Run And Return Rc And Output    ${stop_e2}
+     ${result}=  Run And Return Rc And Output     ${docker_command}
+     Should Be Equal As Integers    ${result[1]}    ${docker_number-1}
+     Sleep  2s
+
 Start Dbass
      Run And Return Rc And Output    ${dbass_remove}
      Run And Return Rc And Output    ${dbass_start}
 Start Dbass
      Run And Return Rc And Output    ${dbass_remove}
      Run And Return Rc And Output    ${dbass_start}
@@ -106,6 +160,12 @@ Stop Dbass
      ${result}=  Run And Return Rc And Output     ${docker_command}
      Should Be Equal As Integers    ${result[1]}    ${docker_number-1}
 
      ${result}=  Run And Return Rc And Output     ${docker_command}
      Should Be Equal As Integers    ${result[1]}    ${docker_number-1}
 
+Restart simulator
+
+    Run And Return Rc And Output    ${restart_docker_sim}
+    ${result}=  Run And Return Rc And Output     ${docker_command}
+    Should Be Equal As Integers    ${result[1]}    ${docker_number}
+
 
 
 
 
 
 
index 4b6bcb3..90c79b2 100644 (file)
@@ -25,46 +25,45 @@ Documentation    Resource file
 
 
 *** Variables ***
 
 
 *** Variables ***
-${docker_number}    6
-${docker_number-1}    5
+${docker_number}    8
+${docker_number-1}    7
 ${ip_gnb_simu} 10.0.2.15
 ${ip_e2adapter}        10.0.2.15
 ${url}   http://localhost:3800
 ${ip_gnb_simu} 10.0.2.15
 ${ip_e2adapter}        10.0.2.15
 ${url}   http://localhost:3800
+${url_rsm}   http://localhost:4800
+${json_setup_rsm_tests}    {"ranIp": "10.0.2.15","ranPort": 36422,"ranName":"test1"}
 ${json}    {"ranIp": "10.0.2.15","ranPort": 5577,"ranName":"test1"}
 ${endcbadjson}    {"ranIp": "a","ranPort": 49999,"ranName":"test2"}
 ${endcjson}    {"ranIp": "10.0.2.15","ranPort": 49999,"ranName":"test2"}
 ${resetcausejson}   {"cause": "misc:not-enough-user-plane-processing-resources"}
 ${resetbadcausejson}   {"cause": "bla" }
 ${resetbad1causejson}   {"cause":  }
 ${json}    {"ranIp": "10.0.2.15","ranPort": 5577,"ranName":"test1"}
 ${endcbadjson}    {"ranIp": "a","ranPort": 49999,"ranName":"test2"}
 ${endcjson}    {"ranIp": "10.0.2.15","ranPort": 49999,"ranName":"test2"}
 ${resetcausejson}   {"cause": "misc:not-enough-user-plane-processing-resources"}
 ${resetbadcausejson}   {"cause": "bla" }
 ${resetbad1causejson}   {"cause":  }
+${resource_status_start_json}   {"enableResourceStatus":true}
+${resource_status_stop_json}    {"enableResourceStatus":false}
 ${header}  {"Content-Type": "application/json"}
 ${docker_command}  docker ps | grep Up | wc --lines
 ${run_simu_load}   docker run -d --name gnbe2_simu --env gNBipv4=localhost  --env gNBport=36422  --env duration=600000000000 --env indicationReportRate=1000000000 --env indicationInsertRate=0 -p 5577:36422/sctp snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001/gnbe2_simu:1.0.6
 ${header}  {"Content-Type": "application/json"}
 ${docker_command}  docker ps | grep Up | wc --lines
 ${run_simu_load}   docker run -d --name gnbe2_simu --env gNBipv4=localhost  --env gNBport=36422  --env duration=600000000000 --env indicationReportRate=1000000000 --env indicationInsertRate=0 -p 5577:36422/sctp snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001/gnbe2_simu:1.0.6
-#${run_simu_load}   docker run -d --name gnbe2_simu  -h gnb-sim --env gNBipv4=gnb-sim  --env gNBport=5577/sctp  --env duration=600000000000 --env indicationReportRate=1000000000 --env indicationInsertRate=0 snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001/gnbe2_simu:1.0.6
+${stop_e2e_simu}  docker stop e2e_simu
 ${stop_simu}  docker stop gnbe2_simu
 ${run_simu_regular}  docker run -d --name gnbe2_simu --env gNBipv4=localhost  --env gNBport=36422 --env duration=600000000000 --env indicationReportRate=0 --env indicationInsertRate=0 -p 5577:36422/sctp snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001/gnbe2_simu:1.0.6
 ${stop_simu}  docker stop gnbe2_simu
 ${run_simu_regular}  docker run -d --name gnbe2_simu --env gNBipv4=localhost  --env gNBport=36422 --env duration=600000000000 --env indicationReportRate=0 --env indicationInsertRate=0 -p 5577:36422/sctp snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001/gnbe2_simu:1.0.6
-#${run_simu_regular}  docker run -d --name gnbe2_simu  -h gnb-sim --env gNBipv4=gnb-sim  --env gNBport=5577/sctp --env duration=600000000000 --env indicationReportRate=0 --env indicationInsertRate=0  snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001/gnbe2_simu:1.0.6
+${run_e2e_simu_regular}  docker run -d --name e2e_simu -p 36422:36422 --net host -it snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001/e2sim:1.4.0 sh -c "./build/e2sim 10.0.2.15 36422"
 ${docker_Remove}    docker rm gnbe2_simu
 ${docker_Remove}    docker rm gnbe2_simu
+${docker_remove_e2e_simu}    docker rm e2e_simu
 ${docker_restart}   docker restart e2mgr
 ${restart_simu}  docker restart gnbe2_simu
 ${docker_restart}   docker restart e2mgr
 ${restart_simu}  docker restart gnbe2_simu
+${restart_e2e_simu}  docker restart e2e_simu
 ${restart_e2adapter}  docker restart e2adapter
 ${restart_e2adapter}  docker restart e2adapter
+${restart_rsm}  docker restart rsm
 ${start_e2}  docker start e2
 ${start_e2}  docker start e2
-${stop_docker_e2}      docker stop e2
+${stop_e2}      docker stop e2
 ${dbass_start}   docker run -d --name dbass -p 6379:6379 --env DBAAS_SERVICE_HOST=10.0.2.15  snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001/dbass:1.0.0
 ${dbass_remove}    docker rm dbass
 ${dbass_stop}      docker stop dbass
 ${restart_simu}  docker restart gnbe2_simu
 ${dbass_start}   docker run -d --name dbass -p 6379:6379 --env DBAAS_SERVICE_HOST=10.0.2.15  snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001/dbass:1.0.0
 ${dbass_remove}    docker rm dbass
 ${dbass_stop}      docker stop dbass
 ${restart_simu}  docker restart gnbe2_simu
-${start_e2}  docker start e2
 ${stop_docker_e2}      docker stop e2
 ${stop_docker_e2}      docker stop e2
+${restart_docker_sim}      docker restart gnbe2_simu
 ${Run_Config}       docker exec gnbe2_simu pkill gnbe2_simu -INT
 ${Run_Config}       docker exec gnbe2_simu pkill gnbe2_simu -INT
-${Save_sim_log}      docker logs gnbe2_simu > gnb.log
-${Save_e2mgr_log}   docker logs e2mgr > e2mgr.log
-${Save_rsm_log}   docker logs rsm > rsm.log
-${Save_e2adapter_log}   docker logs e2adapter > e2adapter.log
 ${403_reset_message}    "Activity X2_RESET rejected. RAN current state DISCONNECTED does not allow its execution "
 ${403_reset_message}    "Activity X2_RESET rejected. RAN current state DISCONNECTED does not allow its execution "
-${e2mgr_log_filename}    e2mgr.log
-${gnb_log_filename}    gnb.log
-${rsm_log_filename}    rsm.log
-${e2adapter_log_filename}    e2adapter.log
 
 
 
 
 
 
index 0c64f32..3d7e46a 100644 (file)
@@ -33,10 +33,15 @@ ${RAN_CONNECTED_message_type}     MType: 1200
 ${RAN_RESTARTED_message_type}     MType: 1210
 ${RIC_X2_RESET_REQ_message_type}    MType: 10070
 ${RIC_X2_RESET_RESP_message_type}    MType: 10070
 ${RAN_RESTARTED_message_type}     MType: 1210
 ${RIC_X2_RESET_REQ_message_type}    MType: 10070
 ${RIC_X2_RESET_RESP_message_type}    MType: 10070
-${failed_to_retrieve_nodeb_message}     failed to retrieve nodeB entity. RanName: test1.
+${E2_INIT_message_type}    MType: 1100
+#${failed_to_retrieve_nodeb_message}     failed to retrieve nodeB entity. RanName: test1.
+#{#RanReconnectionManager.ReconnectRan - RAN name: test1 - Failed fetching RAN from rNib. Error: dial tcp 172.17.0.2:637 #9: i/o timeout"
+${failed_to_retrieve_nodeb_message}     RAN name: test1 - Failed fetching RAN from rNib
 ${first_retry_to_retrieve_from_db}      RnibDataService.retry - retrying 1 GetNodeb
 ${third_retry_to_retrieve_from_db}      RnibDataService.retry - after 3 attempts of GetNodeb
 ${RIC_RES_STATUS_REQ_message_type_successfully_sent}     Message type: 10090 - Successfully sent RMR message
 ${first_retry_to_retrieve_from_db}      RnibDataService.retry - retrying 1 GetNodeb
 ${third_retry_to_retrieve_from_db}      RnibDataService.retry - after 3 attempts of GetNodeb
 ${RIC_RES_STATUS_REQ_message_type_successfully_sent}     Message type: 10090 - Successfully sent RMR message
+${E2_TERM_KEEP_ALIVE_REQ_message_type_successfully_sent}     Message type: 1101 - Successfully sent RMR message
+${e2_is_dead_message_printed}     E2TShutdownManager.Shutdown - E2T e2t.att.com:38000 is Dead, RIP
 ${RAN_NAME_test1}    RAN name: test1
 ${RAN_NAME_test2}    RAN name: test2
 ${E2ADAPTER_Setup_Resp}    Send dummy ENDCX2SetupResponse to RIC
 ${RAN_NAME_test1}    RAN name: test1
 ${RAN_NAME_test2}    RAN name: test2
 ${E2ADAPTER_Setup_Resp}    Send dummy ENDCX2SetupResponse to RIC
index 61aeffa..02c5f8f 100644 (file)
@@ -21,6 +21,7 @@
 #
 import config
 import redis
 #
 import config
 import redis
+import time
 
 
 def flush():
 
 
 def flush():
@@ -33,5 +34,25 @@ def flush():
 
     r.flushall()
 
 
     r.flushall()
 
+    r.set("{rsm},CFG:GENERAL:v1.0.0" , "{\"enableResourceStatus\":true,\"partialSuccessAllowed\":true,\"prbPeriodic\":true,\"tnlLoadIndPeriodic\":true,\"wwLoadIndPeriodic\":true,\"absStatusPeriodic\":true,\"rsrpMeasurementPeriodic\":true,\"csiPeriodic\":true,\"periodicityMs\":1,\"periodicityRsrpMeasurementMs\":3,\"periodicityCsiMs\":3}")
+
+    r.set("{e2Manager},E2TAddresses", "[\"e2t.att.com:38000\"]")
+
+    r.set("{e2Manager},E2TInstance:e2t.att.com:38000", "{\"address\":\"e2t.att.com:38000\",\"associatedRanList\":[],\"keepAliveTimestamp\":" + str(int(time.time())) + ",\"state\":\"ACTIVE\"}")
+
+    return True
+
+def flush_and_restore_without_e2t_keys():
+
+    c = config.redis_ip_address
+
+    p = config.redis_ip_port
+
+    r = redis.Redis(host=c, port=p, db=0)
+
+    r.flushall()
+
+    r.set("{rsm},CFG:GENERAL:v1.0.0" , "{\"enableResourceStatus\":true,\"partialSuccessAllowed\":true,\"prbPeriodic\":true,\"tnlLoadIndPeriodic\":true,\"wwLoadIndPeriodic\":true,\"absStatusPeriodic\":true,\"rsrpMeasurementPeriodic\":true,\"csiPeriodic\":true,\"periodicityMs\":1,\"periodicityRsrpMeasurementMs\":3,\"periodicityCsiMs\":3}")
+
     return True
 
     return True
 
diff --git a/Automation/Tests/Scripts/e2mdbscripts.py b/Automation/Tests/Scripts/e2mdbscripts.py
new file mode 100644 (file)
index 0000000..7b9475b
--- /dev/null
@@ -0,0 +1,49 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+import config
+import redis
+import cleanup_db
+import json
+
+def getRedisClientDecodeResponse():
+    c = config.redis_ip_address
+    p = config.redis_ip_port
+    return redis.Redis(host=c, port=p, db=0, decode_responses=True)
+
+def verify_ran_is_associated_with_e2t_instance(ranName, e2tAddress):
+    r = getRedisClientDecodeResponse()
+    e2tInstanceJson = r.get("{e2Manager},E2TInstance:"+e2tAddress)
+    e2tInstanceDic = json.loads(e2tInstanceJson)
+    assocRanList = e2tInstanceDic.get("associatedRanList")
+    return ranName in assocRanList
+
+# def dissociate_ran_from_e2tInstance(ranName, e2tAddress):
+#     r = getRedisClientDecodeResponse()
+#     e2tInstanceJson = r.get("{e2Manager},E2TInstance:"+e2tAddress)
+#     e2tInstanceDic = json.loads(e2tInstanceJson)
+#     assocRanList = e2tInstanceDic.get("associatedRanList")
+#     print(assocRanList)
+#     assocRanList.remove(ranName)
+#     updatedE2tInstanceJson = json.dumps(e2tInstanceDic)
+#     print(updatedE2tInstanceJson)
+#     r.set("{e2Manager},E2TInstance:"+e2tAddress, updatedE2tInstanceJson)
+#     nodebBytes = r.get("{e2Manager},RAN:"+ranName)
+#     encoded = nodebBytes.decode().replace(e2tAddress,"").encode()
+#     r.set("{e2Manager},RAN:"+ranName, encoded)
+
diff --git a/Automation/Tests/Scripts/e2t_db_script.py b/Automation/Tests/Scripts/e2t_db_script.py
new file mode 100644 (file)
index 0000000..add1a9b
--- /dev/null
@@ -0,0 +1,58 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+import config
+import redis
+
+
+def getRedisClientDecodeResponse():
+
+    c = config.redis_ip_address
+
+    p = config.redis_ip_port
+
+    return redis.Redis(host=c, port=p, db=0, decode_responses=True)
+
+
+def verify_e2t_addresses_key():
+
+    r = getRedisClientDecodeResponse()
+    
+    value = "[\"e2t.att.com:38000\"]"
+
+    return r.get("{e2Manager},E2TAddresses") == value
+
+
+def verify_e2t_instance_key():
+
+    r = getRedisClientDecodeResponse()
+
+    e2_address = "\"address\":\"e2t.att.com:38000\""
+    e2_associated_ran_list = "\"associatedRanList\":[]"
+    e2_state = "\"state\":\"ACTIVE\""
+
+    e2_db_instance = r.get("{e2Manager},E2TInstance:e2t.att.com:38000")
+
+    if e2_db_instance.find(e2_address) < 0:
+        return False
+    if e2_db_instance.find(e2_associated_ran_list) < 0:
+        return False
+    if e2_db_instance.find(e2_state) < 0:
+        return False
+
+    return True
\ No newline at end of file
index 0253ceb..e75d9c6 100644 (file)
@@ -31,8 +31,12 @@ def verify_logs(directory,filename,mtype,meid):
 
     for l in f:
 
 
     for l in f:
 
-        if l.find(mtype) > 0 and l.find(meid) > 0:
-            return True
+        if (meid is not None):
+            if l.find(mtype) > 0 and l.find(meid) > 0:
+                return True
+        else:
+            if l.find(mtype) > 0:
+                return True
 
     return False
 
 
     return False
 
index 5158265..2161094 100644 (file)
@@ -22,6 +22,7 @@
 
 import config
 import redis
 
 import config
 import redis
+import cleanup_db
 
 
 def add():
 
 
 def add():
@@ -32,7 +33,7 @@ def add():
 
     r = redis.Redis(host=c, port=p, db=0)
 
 
     r = redis.Redis(host=c, port=p, db=0)
 
-    r.flushall()
+    cleanup_db.flush()
 
     r.set("{e2Manager},ENB:02f829:007a80", "\n\x05test1\x12\t10.0.2.15\x18\xc9+ \x01*\x10\n\x0602f829\x12\x06007a800\x01:3\b\x01\x12/\bc\x12\x0f02f829:0007ab50\x1a\x040102\"\x0602f829*\n\n\b\b\x01\x10\x01\x18\x04 \x040\x01")
 
 
     r.set("{e2Manager},ENB:02f829:007a80", "\n\x05test1\x12\t10.0.2.15\x18\xc9+ \x01*\x10\n\x0602f829\x12\x06007a800\x01:3\b\x01\x12/\bc\x12\x0f02f829:0007ab50\x1a\x040102\"\x0602f829*\n\n\b\b\x01\x10\x01\x18\x04 \x040\x01")
 
index 5cc862b..aec4b59 100644 (file)
 import redis
 import config
 
 import redis
 import config
 
-
-def verify_value():
+def getRedisClient():
 
     c = config.redis_ip_address
 
     p = config.redis_ip_port
 
 
     c = config.redis_ip_address
 
     p = config.redis_ip_port
 
-    r = redis.Redis(host=c, port=p, db=0)
+    return redis.Redis(host=c, port=p, db=0)
+
+
+def verify_value():
+
+    r = getRedisClient()
 
     value = "\b\x98\xf7\xdd\xa3\xc7\xb4\x83\xde\x15\x12\x11\n\x0f02f829:0007ab00"
 
 
     value = "\b\x98\xf7\xdd\xa3\xc7\xb4\x83\xde\x15\x12\x11\n\x0f02f829:0007ab00"
 
@@ -43,11 +47,7 @@ def verify_value():
 
 def add():
 
 
 def add():
 
-    c = config.redis_ip_address
-
-    p = config.redis_ip_port
-
-    r = redis.Redis(host=c, port=p, db=0)
+    r = getRedisClient()
 
     r.set("{e2Manager},LOAD:test1", "\b\x98\xf7\xdd\xa3\xc7\xb4\x83\xde\x15\x12\x11\n\x0f02f829:0007ab00")
 
 
     r.set("{e2Manager},LOAD:test1", "\b\x98\xf7\xdd\xa3\xc7\xb4\x83\xde\x15\x12\x11\n\x0f02f829:0007ab00")
 
@@ -59,13 +59,10 @@ def add():
 
 def verify():
 
 
 def verify():
 
-    c = config.redis_ip_address
-
-    p = config.redis_ip_port
-
-    r = redis.Redis(host=c, port=p, db=0)
+    r = getRedisClient()
 
     if r.exists("{e2Manager},LOAD:test1"):
         return True
     else:
         return False
 
     if r.exists("{e2Manager},LOAD:test1"):
         return True
     else:
         return False
+
diff --git a/Automation/Tests/Scripts/rsmscripts.py b/Automation/Tests/Scripts/rsmscripts.py
new file mode 100644 (file)
index 0000000..db2a869
--- /dev/null
@@ -0,0 +1,97 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+import config
+import redis
+import json
+
+
+def getRedisClientDecodeResponse():
+
+    c = config.redis_ip_address
+
+    p = config.redis_ip_port
+
+    return redis.Redis(host=c, port=p, db=0, decode_responses=True)
+
+def set_general_config_resource_status_false():
+
+    r = getRedisClientDecodeResponse()
+    r.set("{rsm},CFG:GENERAL:v1.0.0" , "{\"enableResourceStatus\":false,\"partialSuccessAllowed\":true,\"prbPeriodic\":true,\"tnlLoadIndPeriodic\":true,\"wwLoadIndPeriodic\":true,\"absStatusPeriodic\":true,\"rsrpMeasurementPeriodic\":true,\"csiPeriodic\":true,\"periodicityMs\":1,\"periodicityRsrpMeasurementMs\":3,\"periodicityCsiMs\":3}")
+
+def verify_rsm_ran_info_start_false():
+
+    r = getRedisClientDecodeResponse()
+    
+    value = "{\"ranName\":\"test1\",\"enb1MeasurementId\":1,\"enb2MeasurementId\":0,\"action\":\"start\",\"actionStatus\":false}"
+
+    return r.get("{rsm},RAN:test1") == value
+
+
+def verify_rsm_ran_info_start_true():
+
+    r = getRedisClientDecodeResponse()
+
+    rsmInfoStr = r.get("{rsm},RAN:test1")
+    rsmInfoJson = json.loads(rsmInfoStr)
+
+    response = rsmInfoJson["ranName"] == "test1" and rsmInfoJson["enb1MeasurementId"] == 1 and rsmInfoJson["enb2MeasurementId"] != 1 and rsmInfoJson["action"] == "start" and rsmInfoJson["actionStatus"] == True
+
+    return response
+
+
+def verify_rsm_ran_info_stop_false():
+
+    r = getRedisClientDecodeResponse()
+
+    rsmInfoStr = r.get("{rsm},RAN:test1")
+    rsmInfoJson = json.loads(rsmInfoStr)
+
+    response = rsmInfoJson["ranName"] == "test1" and rsmInfoJson["enb1MeasurementId"] == 1 and rsmInfoJson["action"] == "stop" and rsmInfoJson["actionStatus"] == False
+
+    return response
+
+
+def verify_rsm_ran_info_stop_true():
+
+    r = getRedisClientDecodeResponse()
+
+    rsmInfoStr = r.get("{rsm},RAN:test1")
+    rsmInfoJson = json.loads(rsmInfoStr)
+
+    response = rsmInfoJson["ranName"] == "test1" and rsmInfoJson["action"] == "stop" and rsmInfoJson["actionStatus"] == True
+
+    return response
+
+def verify_general_config_enable_resource_status_true():
+
+    r = getRedisClientDecodeResponse()
+
+    configStr = r.get("{rsm},CFG:GENERAL:v1.0.0")
+    configJson = json.loads(configStr)
+
+    return configJson["enableResourceStatus"] == True
+
+def verify_general_config_enable_resource_status_false():
+
+    r = getRedisClientDecodeResponse()
+
+    configStr = r.get("{rsm},CFG:GENERAL:v1.0.0")
+    configJson = json.loads(configStr)
+
+    return configJson["enableResourceStatus"] == False
\ No newline at end of file
index bd87ad6..f0c36f7 100644 (file)
@@ -42,7 +42,7 @@ Pre Condition for Connecting - no simu
 Reset - 400 http - 403 wrong state
     Post Request setup node b x-2
     Integer     response status       204
 Reset - 400 http - 403 wrong state
     Post Request setup node b x-2
     Integer     response status       204
-    Sleep  1s
+    Sleep  10s
     GET      /v1/nodeb/test1
     String   response body connectionStatus    DISCONNECTED
     Set Headers     ${header}
     GET      /v1/nodeb/test1
     String   response body connectionStatus    DISCONNECTED
     Set Headers     ${header}
index b5dfdc8..337bf7a 100644 (file)
@@ -27,6 +27,8 @@ Resource   ../Resource/Keywords.robot
 Resource    ../Resource/scripts_variables.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
 Resource    ../Resource/scripts_variables.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/rsmscripts.py
+Library     ../Scripts/e2mdbscripts.py
 Library     REST      ${url}
 
 *** Test Cases ***
 Library     REST      ${url}
 
 *** Test Cases ***
@@ -42,6 +44,7 @@ X2 - Get Nodeb
     Integer  response body port     5577
     String   response body connectionStatus    CONNECTED
     String   response body nodeType     ENB
     Integer  response body port     5577
     String   response body connectionStatus    CONNECTED
     String   response body nodeType     ENB
+    String   response body associatedE2tInstanceAddress     e2t.att.com:38000  
     String   response body enb enbType     MACRO_ENB
     Integer  response body enb servedCells 0 pci  99
     String   response body enb servedCells 0 cellId   02f829:0007ab00
     String   response body enb enbType     MACRO_ENB
     Integer  response body enb servedCells 0 pci  99
     String   response body enb servedCells 0 cellId   02f829:0007ab00
@@ -66,3 +69,13 @@ RSM RESOURCE STATUS REQUEST message sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
     Should Be Equal As Strings    ${result}      True
 
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
     Should Be Equal As Strings    ${result}      True
 
+Verify RSM RAN info exists in redis
+   ${result}=   rsmscripts.verify_rsm_ran_info_start_false
+   Should Be Equal As Strings  ${result}    True
+
+Verify RAN is associated with E2T instance
+   ${result}    e2mdbscripts.verify_ran_is_associated_with_e2t_instance     test1    e2t.att.com:38000
+   Should Be True    ${result}
+
+
+
 #   platform project (RICP).
 #
 
 #   platform project (RICP).
 #
 
-
 *** Settings ***
 *** Settings ***
-Resource    ../Resource/scripts_variables.robot
+Suite Setup   Prepare Enviorment
+Resource   ../Resource/resource.robot
 Resource   ../Resource/Keywords.robot
 Resource   ../Resource/Keywords.robot
-Library     String
+Resource    ../Resource/scripts_variables.robot
 Library     OperatingSystem
 Library     OperatingSystem
-Library     Process
 Library     ../Scripts/find_rmr_message.py
 Library     ../Scripts/find_rmr_message.py
-
-
+Library     ../Scripts/rsmscripts.py
+Library     ../Scripts/e2mdbscripts.py
+Library     REST      ${url}
 
 *** Test Cases ***
 
 *** Test Cases ***
-Verify logs - Reset Sent by simulator
-    ${Reset}=   Grep File  ./gnb.log  ResetRequest has been sent
-    Should Be Equal     ${Reset}     gnbe2_simu: ResetRequest has been sent
+X2 - Setup Test 1
+    Post Request setup node b x-2
+    Integer     response status       204
 
 
-Verify logs - e2mgr logs - messege sent
-    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RIC_X2_RESET_REQ_message_type}  ${Meid_test1}
-    Should Be Equal As Strings    ${result}      True
+X2 - Setup Test 2
+    Post Request setup node b x-2
+    Integer     response status       204
 
 
-Verify logs - e2mgr logs - messege received
-    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RIC_X2_RESET_RESP_message_type}  ${Meid_test1}
-    Should Be Equal As Strings    ${result}      True
+X2 - Get Nodeb
+    Get Request Node B Enb test1
+    Integer  response status  200
+    String   response body ranName    test1
+    String   response body associatedE2tInstanceAddress     e2t.att.com:38000  
+
+prepare logs for tests
+    Remove log files
+    Save logs
 
 
-RAN Restarted messege sent
-    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RAN_RESTARTED_message_type}  ${Meid_test1}
+X2 - RAN Connected message going to be sent
+    ${result}    find_rmr_message.verify_logs     ${EXECDIR}   ${e2mgr_log_filename}  ${RAN_CONNECTED_message_type}    ${Meid_test1}
     Should Be Equal As Strings    ${result}      True
 
 RSM RESOURCE STATUS REQUEST message sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
     Should Be Equal As Strings    ${result}      True
 
 RSM RESOURCE STATUS REQUEST message sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
-    Should Be Equal As Strings    ${result}      True
\ No newline at end of file
+    Should Be Equal As Strings    ${result}      True
+
+Verify RSM RAN info exists in redis
+   ${result}=   rsmscripts.verify_rsm_ran_info_start_false
+   Should Be Equal As Strings  ${result}    True
+
+Verify RAN is associated with E2T instance
+   ${result}    e2mdbscripts.verify_ran_is_associated_with_e2t_instance     test1    e2t.att.com:38000
+   Should Be True    ${result}
diff --git a/Automation/Tests/X2-Setup/x2_setup_existing_not_assoc_test.robot b/Automation/Tests/X2-Setup/x2_setup_existing_not_assoc_test.robot
new file mode 100644 (file)
index 0000000..457ca9c
--- /dev/null
@@ -0,0 +1,71 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+*** Settings ***
+Suite Setup   Prepare Enviorment
+Resource   ../Resource/resource.robot
+Resource   ../Resource/Keywords.robot
+Resource    ../Resource/scripts_variables.robot
+Library     OperatingSystem
+Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/rsmscripts.py
+Library     ../Scripts/e2mdbscripts.py
+Library     REST      ${url}
+
+*** Test Cases ***
+X2 - Setup Test 1
+    Post Request setup node b x-2
+    Integer     response status       204
+
+Restart Simulator
+    Restart Simulator
+
+Verify RAN is NOT associated with E2T instance
+   ${result}    e2mdbscripts.verify_ran_is_associated_with_e2t_instance     test1    e2t.att.com:38000
+   Should Be True    ${result} == False
+
+
+X2 - Setup Test 2
+    Post Request setup node b x-2
+    Integer     response status       204
+
+X2 - Get Nodeb
+    Get Request Node B Enb test1
+    Integer  response status  200
+    String   response body ranName    test1
+    String   response body associatedE2tInstanceAddress     e2t.att.com:38000  
+
+prepare logs for tests
+    Remove log files
+    Save logs
+
+X2 - RAN Connected message going to be sent
+    ${result}    find_rmr_message.verify_logs     ${EXECDIR}   ${e2mgr_log_filename}  ${RAN_CONNECTED_message_type}    ${Meid_test1}
+    Should Be Equal As Strings    ${result}      True
+
+RSM RESOURCE STATUS REQUEST message sent
+    ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
+    Should Be Equal As Strings    ${result}      True
+
+Verify RSM RAN info exists in redis
+   ${result}=   rsmscripts.verify_rsm_ran_info_start_false
+   Should Be Equal As Strings  ${result}    True
+
+Verify RAN is associated with E2T instance
+   ${result}    e2mdbscripts.verify_ran_is_associated_with_e2t_instance     test1    e2t.att.com:38000
+   Should Be True    ${result}
index 780d966..6f50b7e 100644 (file)
@@ -27,7 +27,11 @@ Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     Collections
 Library     REST      ${url}
 Library     OperatingSystem
 Library     Collections
 Library     REST      ${url}
-
+Resource    ../Resource/scripts_variables.robot
+Library     String
+Library     Process
+Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/rsmscripts.py
 
 
 
 
 
 
@@ -50,3 +54,26 @@ Prepare logs for tests
     Remove log files
     Save logs
 
     Remove log files
     Save logs
 
+Verify logs - Reset Sent by simulator
+    ${Reset}=   Grep File  ./${gnb_log_filename}  ResetRequest has been sent
+    Should Be Equal     ${Reset}     gnbe2_simu: ResetRequest has been sent
+
+Verify logs - e2mgr logs - messege sent
+    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RIC_X2_RESET_REQ_message_type}  ${Meid_test1}
+    Should Be Equal As Strings    ${result}      True
+
+Verify logs - e2mgr logs - messege received
+    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RIC_X2_RESET_RESP_message_type}  ${Meid_test1}
+    Should Be Equal As Strings    ${result}      True
+
+RAN Restarted messege sent
+    ${result}    find_rmr_message.verify_logs  ${EXECDIR}  ${e2mgr_log_filename}  ${RAN_RESTARTED_message_type}  ${Meid_test1}
+    Should Be Equal As Strings    ${result}      True
+
+RSM RESOURCE STATUS REQUEST message sent
+    ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
+    Should Be Equal As Strings    ${result}      True
+
+Verify RSM RAN info exists in redis
+   ${result}=   rsmscripts.verify_rsm_ran_info_start_false
+   Should Be Equal As Strings  ${result}    True
\ No newline at end of file
index 02f69f1..8dc416b 100644 (file)
@@ -27,9 +27,12 @@ Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     Collections
 Library     REST      ${url}
 Library     OperatingSystem
 Library     Collections
 Library     REST      ${url}
-
-
-
+Resource    ../Resource/scripts_variables.robot
+Library     String
+Library     Process
+Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/find_error_script.py
+Suite Teardown  Start Dbass with 4 dockers
 
 
 *** Test Cases ***
 
 
 *** Test Cases ***
@@ -49,9 +52,30 @@ Stop RNIB
 
 Run Reset from RAN
     Run    ${Run_Config}
 
 Run Reset from RAN
     Run    ${Run_Config}
-    Sleep   1s
+    Sleep   60s
 
 Prepare logs for tests
     Remove log files
     Save logs
 
 
 Prepare logs for tests
     Remove log files
     Save logs
 
+Verify logs - Reset Sent by simulator
+    ${Reset}=   Grep File  ./${gnb_log_filename}  ResetRequest has been sent
+    Should Be Equal     ${Reset}     gnbe2_simu: ResetRequest has been sent
+
+Verify logs for restart received
+    ${result}    find_rmr_message.verify_logs     ${EXECDIR}  ${e2mgr_log_filename}  ${RIC_X2_RESET_REQ_message_type}    ${Meid_test1}
+    Should Be Equal As Strings    ${result}      True
+
+Verify for error on retrying
+    ${result}    find_error_script.find_error    ${EXECDIR}     ${e2mgr_log_filename}   ${failed_to_retrieve_nodeb_message}
+    Should Be Equal As Strings    ${result}      True
+
+
+*** Keywords ***
+Start Dbass with 4 dockers
+     Run And Return Rc And Output    ${dbass_remove}
+     Run And Return Rc And Output    ${dbass_start}
+     Sleep  5s
+     ${result}=  Run And Return Rc And Output     ${docker_command}
+     Should Be Equal As Integers    ${result[1]}    ${docker_number-1}
+
diff --git a/Automation/Tests/X2_Reset_RAN_TO_RIC_Unhappy/Reset_Verify_logs.robot b/Automation/Tests/X2_Reset_RAN_TO_RIC_Unhappy/Reset_Verify_logs.robot
deleted file mode 100644 (file)
index 1328660..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-##############################################################################
-#
-#   Copyright (c) 2019 AT&T Intellectual Property.
-#
-#   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 ***
-Resource    ../Resource/scripts_variables.robot
-Library     String
-Library     OperatingSystem
-Library     Process
-Resource   ../Resource/Keywords.robot
-Library     ../Scripts/find_rmr_message.py
-Library     ../Scripts/find_error_script.py
-Test Teardown  Start Dbass with 4 dockers
-
-
-
-*** Test Cases ***
-Verify logs - Reset Sent by simulator
-    ${Reset}=   Grep File  ./gnb.log  ResetRequest has been sent
-    Should Be Equal     ${Reset}     gnbe2_simu: ResetRequest has been sent
-
-Verify logs for restart received
-    ${result}    find_rmr_message.verify_logs     ${EXECDIR}  ${e2mgr_log_filename}  ${RIC_X2_RESET_REQ_message_type}    ${Meid_test1}
-    Should Be Equal As Strings    ${result}      True
-
-Verify for error on retrying
-    ${result}    find_error_script.find_error    ${EXECDIR}     ${e2mgr_log_filename}   ${failed_to_retrieve_nodeb_message}
-    Should Be Equal As Strings    ${result}      True
-
-
-*** Keywords ***
-Start Dbass with 4 dockers
-     Run And Return Rc And Output    ${dbass_remove}
-     Run And Return Rc And Output    ${dbass_start}
-     ${result}=  Run And Return Rc And Output     ${docker_command}
-     Should Be Equal As Integers    ${result[1]}    ${docker_number-1}
-     Sleep  5s
index 83a60cb..3227fe7 100644 (file)
@@ -27,6 +27,7 @@ Resource   ../Resource/resource.robot
 Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
 Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/rsmscripts.py
 Library     REST      ${url}
 
 
 Library     REST      ${url}
 
 
@@ -57,4 +58,8 @@ RAN Restarted messege sent
 
 RSM RESOURCE STATUS REQUEST message sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
 
 RSM RESOURCE STATUS REQUEST message sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
-    Should Be Equal As Strings    ${result}      True
\ No newline at end of file
+    Should Be Equal As Strings    ${result}      True
+
+Verify RSM RAN info exists in redis
+   ${result}=   rsmscripts.verify_rsm_ran_info_start_false
+   Should Be Equal As Strings  ${result}    True
\ No newline at end of file
index b0c1669..d4103e8 100644 (file)
@@ -27,6 +27,7 @@ Resource   ../Resource/resource.robot
 Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
 Resource   ../Resource/Keywords.robot
 Library     OperatingSystem
 Library     ../Scripts/find_rmr_message.py
+Library     ../Scripts/rsmscripts.py
 Library     REST      ${url}
 
 
 Library     REST      ${url}
 
 
@@ -58,4 +59,8 @@ RAN Restarted messege sent
 
 RSM RESOURCE STATUS REQUEST message sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
 
 RSM RESOURCE STATUS REQUEST message sent
     ${result}    find_rmr_message.verify_logs     ${EXECDIR}    ${rsm_log_filename}  ${RIC_RES_STATUS_REQ_message_type_successfully_sent}    ${RAN_NAME_test1}
-    Should Be Equal As Strings    ${result}      True
\ No newline at end of file
+    Should Be Equal As Strings    ${result}      True
+
+Verify RSM RAN info exists in redis
+   ${result}=   rsmscripts.verify_rsm_ran_info_start_false
+   Should Be Equal As Strings  ${result}    True
\ No newline at end of file
index 74db25b..4f9561b 100644 (file)
 #   platform project (RICP).
 #
 
 #   platform project (RICP).
 #
 
-FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu16-c-go:2-u16.04-nng as ubuntu
+FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu16-c-go:3-u16.04-nng as ubuntu
 
 WORKDIR /opt/E2Manager
 COPY . . 
 ENV PATH=$PATH:/usr/local/go/bin:/usr/lib/go-1.12/bin
 #RUN git clone https://gerrit.o-ran-sc.org/r/ric-plt/lib/rmr && cd rmr/; mkdir build; cd build; /opt/bin/cmake -DDEV_PKG=1 ..; make install
 # Install RMr library and dev files
 
 WORKDIR /opt/E2Manager
 COPY . . 
 ENV PATH=$PATH:/usr/local/go/bin:/usr/lib/go-1.12/bin
 #RUN git clone https://gerrit.o-ran-sc.org/r/ric-plt/lib/rmr && cd rmr/; mkdir build; cd build; /opt/bin/cmake -DDEV_PKG=1 ..; make install
 # Install RMr library and dev files
-RUN wget --content-disposition  https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.10.0_amd64.deb/download.deb
-RUN dpkg -i rmr_1.10.0_amd64.deb
-RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.10.0_amd64.deb/download.deb
-RUN dpkg -i rmr-dev_1.10.0_amd64.deb
+RUN wget --content-disposition  https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.13.0_amd64.deb/download.deb
+RUN dpkg -i rmr_1.13.0_amd64.deb
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.13.0_amd64.deb/download.deb
+RUN dpkg -i rmr-dev_1.13.0_amd64.deb
 
 RUN cd 3rdparty/asn1codec && make
 RUN go build app/main.go
 
 RUN cd 3rdparty/asn1codec && make
 RUN go build app/main.go
@@ -45,7 +45,8 @@ ENV LD_LIBRARY_PATH=/usr/local/lib
 # Setting allocfreetrace=1 causes every allocation to be profiled and a stack trace printed on each object's allocation and free.
 ENV GODEBUG=cgocheck=2,clobberfree=1,gcstoptheworld=2,allocfreetrace=0
 ENV RIC_ID="bbbccc-abcd0e/20"
 # Setting allocfreetrace=1 causes every allocation to be profiled and a stack trace printed on each object's allocation and free.
 ENV GODEBUG=cgocheck=2,clobberfree=1,gcstoptheworld=2,allocfreetrace=0
 ENV RIC_ID="bbbccc-abcd0e/20"
-RUN go test ./...
+ENV RMR_SEED_RT=/opt/E2Manager/router_test.txt
+RUN go-acc $(go list ./... | grep -v e2mgr/mocks | grep -v e2mgr/tests |grep -v e2mgr/e2managererrors| grep -v e2mgr/enums)
 
 FROM ubuntu:16.04
 
 
 FROM ubuntu:16.04
 
index dd0875d..443b7eb 100644 (file)
@@ -21,9 +21,9 @@
 package main
 
 import (
 package main
 
 import (
+       "e2mgr/clients"
        "e2mgr/configuration"
        "e2mgr/controllers"
        "e2mgr/configuration"
        "e2mgr/controllers"
-       "e2mgr/converters"
        "e2mgr/httpserver"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/httpserver"
        "e2mgr/logger"
        "e2mgr/managers"
@@ -37,12 +37,12 @@ import (
        "e2mgr/services/rmrsender"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "e2mgr/services/rmrsender"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
+       "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
+       "net/http"
        "os"
        "strconv"
 )
 
        "os"
        "strconv"
 )
 
-const MAX_RNIB_POOL_INSTANCES = 4
-
 func main() {
        config := configuration.ParseConfiguration()
        logLevel, _ := logger.LogLevelTokenToLevel(config.Logging.LogLevel)
 func main() {
        config := configuration.ParseConfiguration()
        logLevel, _ := logger.LogLevelTokenToLevel(config.Logging.LogLevel)
@@ -51,32 +51,34 @@ func main() {
                fmt.Printf("#app.main - failed to initialize logger, error: %s", err)
                os.Exit(1)
        }
                fmt.Printf("#app.main - failed to initialize logger, error: %s", err)
                os.Exit(1)
        }
-       rNibWriter.Init("e2Manager", MAX_RNIB_POOL_INSTANCES)
-       defer rNibWriter.Close()
-       reader.Init("e2Manager", MAX_RNIB_POOL_INSTANCES)
-       defer reader.Close()
-       rnibDataService := services.NewRnibDataService(logger, config, reader.GetRNibReader, rNibWriter.GetRNibWriter)
+       db := sdlgo.NewDatabase()
+       sdl := sdlgo.NewSdlInstance("e2Manager", db)
+       defer sdl.Close()
+       rnibDataService := services.NewRnibDataService(logger, config, reader.GetRNibReader(sdl), rNibWriter.GetRNibWriter( sdl))
        var msgImpl *rmrCgo.Context
        rmrMessenger := msgImpl.Init("tcp:"+strconv.Itoa(config.Rmr.Port), config.Rmr.MaxMsgSize, 0, logger)
        rmrSender := rmrsender.NewRmrSender(logger, rmrMessenger)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
        var msgImpl *rmrCgo.Context
        rmrMessenger := msgImpl.Init("tcp:"+strconv.Itoa(config.Rmr.Port), config.Rmr.MaxMsgSize, 0, logger)
        rmrSender := rmrsender.NewRmrSender(logger, rmrMessenger)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
-       ranReconnectionManager := managers.NewRanReconnectionManager(logger, config, rnibDataService, ranSetupManager)
-       ranStatusChangeManager := managers.NewRanStatusChangeManager(logger, rmrSender)
-       x2SetupResponseConverter := converters.NewX2SetupResponseConverter(logger)
-       x2SetupResponseManager := managers.NewX2SetupResponseManager(x2SetupResponseConverter)
-       x2SetupFailureResponseConverter := converters.NewX2SetupFailureResponseConverter(logger)
-       x2SetupFailureResponseManager := managers.NewX2SetupFailureResponseManager(x2SetupFailureResponseConverter)
-       rmrNotificationHandlerProvider := rmrmsghandlerprovider.NewNotificationHandlerProvider(logger, rnibDataService, ranReconnectionManager, ranStatusChangeManager, rmrSender, x2SetupResponseManager, x2SetupFailureResponseManager)
+       e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, logger)
+       e2tShutdownManager := managers.NewE2TShutdownManager(logger, rnibDataService, e2tInstancesManager)
+       e2tKeepAliveWorker := managers.NewE2TKeepAliveWorker(logger, rmrSender, e2tInstancesManager, e2tShutdownManager, config)
+       routingManagerClient := clients.NewRoutingManagerClient(logger, config, &http.Client{})
+       rmrNotificationHandlerProvider := rmrmsghandlerprovider.NewNotificationHandlerProvider()
+       rmrNotificationHandlerProvider.Init(logger, config, rnibDataService, rmrSender, ranSetupManager, e2tInstancesManager, routingManagerClient)
 
        notificationManager := notificationmanager.NewNotificationManager(logger, rmrNotificationHandlerProvider)
        rmrReceiver := rmrreceiver.NewRmrReceiver(logger, rmrMessenger, notificationManager)
 
 
        notificationManager := notificationmanager.NewNotificationManager(logger, rmrNotificationHandlerProvider)
        rmrReceiver := rmrreceiver.NewRmrReceiver(logger, rmrMessenger, notificationManager)
 
-       defer (*rmrMessenger).Close()
+       e2tInstancesManager.ResetKeepAliveTimestampsForAllE2TInstances()
+
+       defer rmrMessenger.Close()
 
        go rmrReceiver.ListenAndHandle()
 
        go rmrReceiver.ListenAndHandle()
+       go e2tKeepAliveWorker.Execute()
 
 
-       httpMsgHandlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(logger, rmrSender, config, rnibDataService, ranSetupManager)
+       httpMsgHandlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(logger, rmrSender, config, rnibDataService, ranSetupManager, e2tInstancesManager)
        rootController := controllers.NewRootController(rnibDataService)
        nodebController := controllers.NewNodebController(logger, httpMsgHandlerProvider)
        rootController := controllers.NewRootController(rnibDataService)
        nodebController := controllers.NewNodebController(logger, httpMsgHandlerProvider)
-       httpserver.Run(config.Http.Port, rootController, nodebController)
-}
+       e2tController := controllers.NewE2TController(logger, httpMsgHandlerProvider)
+       _ = httpserver.Run(logger, config.Http.Port, rootController, nodebController, e2tController)
+}
\ No newline at end of file
diff --git a/E2Manager/clients/http_client.go b/E2Manager/clients/http_client.go
new file mode 100644 (file)
index 0000000..e3692f5
--- /dev/null
@@ -0,0 +1,30 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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 clients
+
+import (
+       "io"
+       "net/http"
+)
+
+type HttpClient interface {
+       Post(url, contentType string, body io.Reader) (resp *http.Response, err error)
+}
\ No newline at end of file
diff --git a/E2Manager/clients/routing_manager_client.go b/E2Manager/clients/routing_manager_client.go
new file mode 100644 (file)
index 0000000..c584f5b
--- /dev/null
@@ -0,0 +1,108 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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 clients
+
+import (
+       "bytes"
+       "e2mgr/configuration"
+       "e2mgr/e2managererrors"
+       "e2mgr/logger"
+       "e2mgr/models"
+       "encoding/json"
+       "net/http"
+)
+
+const (
+       AddE2TInstanceApiSuffix            = "e2t"
+       AssociateRanToE2TInstanceApiSuffix = "associate-ran-to-e2t"
+       DissociateRanE2TInstanceApiSuffix  = "dissociate-ran"
+)
+
+type RoutingManagerClient struct {
+       logger     *logger.Logger
+       config     *configuration.Configuration
+       httpClient HttpClient
+}
+
+type IRoutingManagerClient interface {
+       AddE2TInstance(e2tAddress string) error
+       AssociateRanToE2TInstance(e2tAddress string, ranName string) error
+       DissociateRanE2TInstance(e2tAddress string, ranName string) error
+}
+
+func NewRoutingManagerClient(logger *logger.Logger, config *configuration.Configuration, httpClient HttpClient) *RoutingManagerClient {
+       return &RoutingManagerClient{
+               logger:     logger,
+               config:     config,
+               httpClient: httpClient,
+       }
+}
+
+func (c *RoutingManagerClient) AddE2TInstance(e2tAddress string) error {
+
+       data := models.NewRoutingManagerE2TData(e2tAddress)
+       url := c.config.RoutingManager.BaseUrl + AddE2TInstanceApiSuffix
+
+       return c.PostMessage(data, url)
+}
+
+func (c *RoutingManagerClient) AssociateRanToE2TInstance(e2tAddress string, ranName string) error {
+
+       data := models.NewRoutingManagerE2TData(e2tAddress, ranName)
+       url := c.config.RoutingManager.BaseUrl + AssociateRanToE2TInstanceApiSuffix
+
+       return c.PostMessage(data, url)
+}
+
+func (c *RoutingManagerClient) DissociateRanE2TInstance(e2tAddress string, ranName string) error {
+
+       data := models.NewRoutingManagerE2TData(e2tAddress, ranName)
+       url := c.config.RoutingManager.BaseUrl + DissociateRanE2TInstanceApiSuffix
+
+       return c.PostMessage(data, url)
+}
+
+func (c *RoutingManagerClient) PostMessage(data *models.RoutingManagerE2TData, url string) error {
+       marshaled, err := json.Marshal(data)
+
+       if err != nil {
+               return e2managererrors.NewRoutingManagerError()
+       }
+
+       body := bytes.NewBuffer(marshaled)
+       c.logger.Infof("[E2M -> Routing Manager] #RoutingManagerClient.PostMessage - url: %s, request body: %+v", url, body)
+
+       resp, err := c.httpClient.Post(url, "application/json", body)
+
+       if err != nil {
+               c.logger.Errorf("#RoutingManagerClient.PostMessage - failed sending request. error: %s", err)
+               return e2managererrors.NewRoutingManagerError()
+       }
+
+       defer resp.Body.Close()
+
+       if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices {
+               c.logger.Infof("[Routing Manager -> E2M] #RoutingManagerClient.PostMessage - success. http status code: %d", resp.StatusCode)
+               return nil
+       }
+
+       c.logger.Errorf("[Routing Manager -> E2M] #RoutingManagerClient.PostMessage - failure. http status code: %d", resp.StatusCode)
+       return e2managererrors.NewRoutingManagerError()
+}
\ No newline at end of file
diff --git a/E2Manager/clients/routing_manager_client_test.go b/E2Manager/clients/routing_manager_client_test.go
new file mode 100644 (file)
index 0000000..2d02cfd
--- /dev/null
@@ -0,0 +1,180 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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 clients
+
+import (
+       "bytes"
+       "e2mgr/configuration"
+       "e2mgr/logger"
+       "e2mgr/mocks"
+       "e2mgr/models"
+       "encoding/json"
+       "github.com/pkg/errors"
+       "github.com/stretchr/testify/assert"
+       "io/ioutil"
+       "net/http"
+       "testing"
+)
+
+const E2TAddress = "10.0.2.15:38000"
+const RanName = "test1"
+
+
+func initRoutingManagerClientTest(t *testing.T) (*RoutingManagerClient, *mocks.HttpClientMock, *configuration.Configuration) {
+       logger := initLog(t)
+       config := &configuration.Configuration{}
+       config.RoutingManager.BaseUrl = "http://iltlv740.intl.att.com:8080/ric/v1/handles/"
+       httpClientMock := &mocks.HttpClientMock{}
+       rmClient := NewRoutingManagerClient(logger, config, httpClientMock)
+       return rmClient, httpClientMock, config
+}
+
+func TestAddE2TInstanceSuccess(t *testing.T) {
+       rmClient, httpClientMock, config := initRoutingManagerClientTest(t)
+
+       data := models.NewRoutingManagerE2TData(E2TAddress)
+       marshaled, _ := json.Marshal(data)
+       body := bytes.NewBuffer(marshaled)
+       url := config.RoutingManager.BaseUrl + "e2t"
+       respBody := ioutil.NopCloser(bytes.NewBufferString(""))
+       httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
+       err := rmClient.AddE2TInstance(E2TAddress)
+       assert.Nil(t, err)
+}
+
+func TestAddE2TInstanceHttpPostFailure(t *testing.T) {
+       rmClient, httpClientMock, config := initRoutingManagerClientTest(t)
+
+       data := models.NewRoutingManagerE2TData(E2TAddress)
+       marshaled, _ := json.Marshal(data)
+       body := bytes.NewBuffer(marshaled)
+       url := config.RoutingManager.BaseUrl + "e2t"
+       httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{}, errors.New("error"))
+       err := rmClient.AddE2TInstance(E2TAddress)
+       assert.NotNil(t, err)
+}
+
+func TestAddE2TInstanceFailure(t *testing.T) {
+       rmClient, httpClientMock, config := initRoutingManagerClientTest(t)
+
+       data := models.NewRoutingManagerE2TData(E2TAddress)
+       marshaled, _ := json.Marshal(data)
+       body := bytes.NewBuffer(marshaled)
+       url := config.RoutingManager.BaseUrl + "e2t"
+       respBody := ioutil.NopCloser(bytes.NewBufferString(""))
+       httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{StatusCode: http.StatusBadRequest, Body:respBody}, nil)
+       err := rmClient.AddE2TInstance(E2TAddress)
+       assert.NotNil(t, err)
+}
+
+func TestAssociateRanToE2TInstance_Success(t *testing.T) {
+       rmClient, httpClientMock, config := initRoutingManagerClientTest(t)
+
+       data := models.NewRoutingManagerE2TData(E2TAddress,RanName)
+       marshaled, _ := json.Marshal(data)
+       body := bytes.NewBuffer(marshaled)
+       url := config.RoutingManager.BaseUrl + AssociateRanToE2TInstanceApiSuffix
+       respBody := ioutil.NopCloser(bytes.NewBufferString(""))
+       httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
+       err := rmClient.AssociateRanToE2TInstance(E2TAddress, RanName)
+       assert.Nil(t, err)
+}
+
+func TestAssociateRanToE2TInstance_RoutingManagerError(t *testing.T) {
+       rmClient, httpClientMock, config := initRoutingManagerClientTest(t)
+
+       data := models.NewRoutingManagerE2TData(E2TAddress,RanName)
+       marshaled, _ := json.Marshal(data)
+       body := bytes.NewBuffer(marshaled)
+       url := config.RoutingManager.BaseUrl + AssociateRanToE2TInstanceApiSuffix
+       httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{}, errors.New("error"))
+       err := rmClient.AssociateRanToE2TInstance(E2TAddress, RanName)
+       assert.NotNil(t, err)
+}
+
+func TestAssociateRanToE2TInstance_RoutingManager_400(t *testing.T) {
+       rmClient, httpClientMock, config := initRoutingManagerClientTest(t)
+
+       data := models.NewRoutingManagerE2TData(E2TAddress,RanName)
+       marshaled, _ := json.Marshal(data)
+       body := bytes.NewBuffer(marshaled)
+       url := config.RoutingManager.BaseUrl + AssociateRanToE2TInstanceApiSuffix
+       respBody := ioutil.NopCloser(bytes.NewBufferString(""))
+       httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{StatusCode: http.StatusBadRequest, Body:respBody}, nil)
+       err := rmClient.AssociateRanToE2TInstance(E2TAddress, RanName)
+       assert.NotNil(t, err)
+}
+
+func TestDissociateRanE2TInstance_Success(t *testing.T) {
+       rmClient, httpClientMock, config := initRoutingManagerClientTest(t)
+
+       data := models.NewRoutingManagerE2TData(E2TAddress,RanName)
+       marshaled, _ := json.Marshal(data)
+       body := bytes.NewBuffer(marshaled)
+       url := config.RoutingManager.BaseUrl + DissociateRanE2TInstanceApiSuffix
+       respBody := ioutil.NopCloser(bytes.NewBufferString(""))
+       httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
+       err := rmClient.DissociateRanE2TInstance(E2TAddress, RanName)
+       assert.Nil(t, err)
+}
+
+func TestDissociateRanE2TInstance_RoutingManagerError(t *testing.T) {
+       rmClient, httpClientMock, config := initRoutingManagerClientTest(t)
+
+       data := models.NewRoutingManagerE2TData(E2TAddress,RanName)
+       marshaled, _ := json.Marshal(data)
+       body := bytes.NewBuffer(marshaled)
+       url := config.RoutingManager.BaseUrl + DissociateRanE2TInstanceApiSuffix
+       httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{}, errors.New("error"))
+       err := rmClient.DissociateRanE2TInstance(E2TAddress, RanName)
+       assert.NotNil(t, err)
+}
+
+func TestDissociateRanE2TInstance_RoutingManager_400(t *testing.T) {
+       rmClient, httpClientMock, config := initRoutingManagerClientTest(t)
+
+       data := models.NewRoutingManagerE2TData(E2TAddress,RanName)
+       marshaled, _ := json.Marshal(data)
+       body := bytes.NewBuffer(marshaled)
+       url := config.RoutingManager.BaseUrl + DissociateRanE2TInstanceApiSuffix
+       respBody := ioutil.NopCloser(bytes.NewBufferString(""))
+       httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{StatusCode: http.StatusBadRequest, Body:respBody}, nil)
+       err := rmClient.DissociateRanE2TInstance(E2TAddress, RanName)
+       assert.NotNil(t, err)
+}
+
+// TODO: extract to test_utils
+func initLog(t *testing.T) *logger.Logger {
+       log, err := logger.InitLogger(logger.InfoLevel)
+       if err != nil {
+               t.Errorf("#delete_all_request_handler_test.TestHandleSuccessFlow - failed to initialize logger, error: %s", err)
+       }
+       return log
+}
+
+//func TestAddE2TInstanceInteg(t *testing.T) {
+//     logger := initLog(t)
+//     config := configuration.ParseConfiguration()
+//     httpClient := &http.Client{}
+//     rmClient := NewRoutingManagerClient(logger, config, httpClient)
+//     err := rmClient.AddE2TInstance(E2TAddress)
+//     assert.Nil(t, err)
+//}
index 43fbd71..d37c497 100644 (file)
@@ -36,19 +36,24 @@ type Configuration struct {
                Port       int
                MaxMsgSize int
        }
                Port       int
                MaxMsgSize int
        }
-       NotificationResponseBuffer int
-       BigRedButtonTimeoutSec     int
-       MaxConnectionAttempts      int
-       MaxRnibConnectionAttempts  int
-       RnibRetryIntervalMs                int
+       RoutingManager struct {
+               BaseUrl    string
+       }
+       NotificationResponseBuffer   int
+       BigRedButtonTimeoutSec       int
+       MaxConnectionAttempts        int
+       MaxRnibConnectionAttempts    int
+       RnibRetryIntervalMs          int
+       KeepAliveResponseTimeoutMs       int
+       KeepAliveDelayMs             int
 }
 
 }
 
-func ParseConfiguration() *Configuration{
+func ParseConfiguration() *Configuration {
        viper.SetConfigType("yaml")
        viper.SetConfigName("configuration")
        viper.AddConfigPath("E2Manager/resources/")
        viper.SetConfigType("yaml")
        viper.SetConfigName("configuration")
        viper.AddConfigPath("E2Manager/resources/")
-       viper.AddConfigPath("./resources/")  //For production
-       viper.AddConfigPath("../resources/") //For test under Docker
+       viper.AddConfigPath("./resources/")     //For production
+       viper.AddConfigPath("../resources/")    //For test under Docker
        viper.AddConfigPath("../../resources/") //For test under Docker
        err := viper.ReadInConfig()
        if err != nil {
        viper.AddConfigPath("../../resources/") //For test under Docker
        err := viper.ReadInConfig()
        if err != nil {
@@ -56,37 +61,45 @@ func ParseConfiguration() *Configuration{
        }
 
        config := Configuration{}
        }
 
        config := Configuration{}
-       config.fillRmrConfig(viper.Sub("rmr"))
-       config.fillHttpConfig(viper.Sub("http"))
-       config.fillLoggingConfig(viper.Sub("logging"))
-
+       config.populateRmrConfig(viper.Sub("rmr"))
+       config.populateHttpConfig(viper.Sub("http"))
+       config.populateLoggingConfig(viper.Sub("logging"))
+       config.populateRoutingManagerConfig(viper.Sub("routingManager"))
        config.NotificationResponseBuffer = viper.GetInt("notificationResponseBuffer")
        config.BigRedButtonTimeoutSec = viper.GetInt("bigRedButtonTimeoutSec")
        config.MaxConnectionAttempts = viper.GetInt("maxConnectionAttempts")
        config.MaxRnibConnectionAttempts = viper.GetInt("maxRnibConnectionAttempts")
        config.RnibRetryIntervalMs = viper.GetInt("rnibRetryIntervalMs")
        config.NotificationResponseBuffer = viper.GetInt("notificationResponseBuffer")
        config.BigRedButtonTimeoutSec = viper.GetInt("bigRedButtonTimeoutSec")
        config.MaxConnectionAttempts = viper.GetInt("maxConnectionAttempts")
        config.MaxRnibConnectionAttempts = viper.GetInt("maxRnibConnectionAttempts")
        config.RnibRetryIntervalMs = viper.GetInt("rnibRetryIntervalMs")
+       config.KeepAliveResponseTimeoutMs = viper.GetInt("keepAliveResponseTimeoutMs")
+       config.KeepAliveDelayMs = viper.GetInt("KeepAliveDelayMs")
        return &config
 }
 
        return &config
 }
 
-func (c *Configuration)fillLoggingConfig(logConfig *viper.Viper) {
+func (c *Configuration) populateLoggingConfig(logConfig *viper.Viper) {
        if logConfig == nil {
        if logConfig == nil {
-               panic(fmt.Sprintf("#configuration.fillLoggingConfig - failed to fill logging configuration: The entry 'logging' not found\n"))
+               panic(fmt.Sprintf("#configuration.populateLoggingConfig - failed to populate logging configuration: The entry 'logging' not found\n"))
        }
        c.Logging.LogLevel = logConfig.GetString("logLevel")
 }
 
        }
        c.Logging.LogLevel = logConfig.GetString("logLevel")
 }
 
-func (c *Configuration)fillHttpConfig(httpConfig *viper.Viper) {
+func (c *Configuration) populateHttpConfig(httpConfig *viper.Viper) {
        if httpConfig == nil {
        if httpConfig == nil {
-               panic(fmt.Sprintf("#configuration.fillHttpConfig - failed to fill HTTP configuration: The entry 'http' not found\n"))
+               panic(fmt.Sprintf("#configuration.populateHttpConfig - failed to populate HTTP configuration: The entry 'http' not found\n"))
        }
        c.Http.Port = httpConfig.GetInt("port")
 }
 
        }
        c.Http.Port = httpConfig.GetInt("port")
 }
 
-func (c *Configuration)fillRmrConfig(rmrConfig *viper.Viper) {
+func (c *Configuration) populateRmrConfig(rmrConfig *viper.Viper) {
        if rmrConfig == nil {
        if rmrConfig == nil {
-               panic(fmt.Sprintf("#configuration.fillRmrConfig - failed to fill RMR configuration: The entry 'rmr' not found\n"))
+               panic(fmt.Sprintf("#configuration.populateRmrConfig - failed to populate RMR configuration: The entry 'rmr' not found\n"))
        }
        c.Rmr.Port = rmrConfig.GetInt("port")
        c.Rmr.MaxMsgSize = rmrConfig.GetInt("maxMsgSize")
 }
 
        }
        c.Rmr.Port = rmrConfig.GetInt("port")
        c.Rmr.MaxMsgSize = rmrConfig.GetInt("maxMsgSize")
 }
 
+func (c *Configuration) populateRoutingManagerConfig(rmConfig *viper.Viper) {
+       if rmConfig == nil {
+               panic(fmt.Sprintf("#configuration.populateRoutingManagerConfig - failed to populate Routing Manager configuration: The entry 'routingManager' not found\n"))
+       }
+       c.RoutingManager.BaseUrl = rmConfig.GetString("baseUrl")
+}
index e1c5088..ec16c1f 100644 (file)
@@ -36,6 +36,8 @@ func TestParseConfigurationSuccess(t *testing.T) {
        assert.Equal(t, "info", config.Logging.LogLevel)
        assert.Equal(t, 100, config.NotificationResponseBuffer)
        assert.Equal(t, 5, config.BigRedButtonTimeoutSec)
        assert.Equal(t, "info", config.Logging.LogLevel)
        assert.Equal(t, 100, config.NotificationResponseBuffer)
        assert.Equal(t, 5, config.BigRedButtonTimeoutSec)
+       assert.Equal(t, 1500, config.KeepAliveResponseTimeoutMs)
+       assert.Equal(t, 500, config.KeepAliveDelayMs)
 }
 
 func TestParseConfigurationFileNotFoundFailure(t *testing.T) {
 }
 
 func TestParseConfigurationFileNotFoundFailure(t *testing.T) {
@@ -70,6 +72,7 @@ func TestRmrConfigNotFoundFailure(t *testing.T) {
        yamlMap := map[string]interface{}{
                "logging": map[string]interface{}{"logLevel": "info"},
                "http":    map[string]interface{}{"port": 3800},
        yamlMap := map[string]interface{}{
                "logging": map[string]interface{}{"logLevel": "info"},
                "http":    map[string]interface{}{"port": 3800},
+               "routingManager":    map[string]interface{}{"baseUrl": "http://iltlv740.intl.att.com:8080/ric/v1/handles/"},
        }
        buf, err := yaml.Marshal(yamlMap)
        if err != nil {
        }
        buf, err := yaml.Marshal(yamlMap)
        if err != nil {
@@ -79,7 +82,7 @@ func TestRmrConfigNotFoundFailure(t *testing.T) {
        if err != nil {
                t.Errorf("#TestRmrConfigNotFoundFailure - failed to write configuration file: %s\n", configPath)
        }
        if err != nil {
                t.Errorf("#TestRmrConfigNotFoundFailure - failed to write configuration file: %s\n", configPath)
        }
-       assert.PanicsWithValue(t, "#configuration.fillRmrConfig - failed to fill RMR configuration: The entry 'rmr' not found\n", func() { ParseConfiguration() })
+       assert.PanicsWithValue(t, "#configuration.populateRmrConfig - failed to populate RMR configuration: The entry 'rmr' not found\n", func() { ParseConfiguration() })
 }
 
 func TestLoggingConfigNotFoundFailure(t *testing.T) {
 }
 
 func TestLoggingConfigNotFoundFailure(t *testing.T) {
@@ -98,6 +101,7 @@ func TestLoggingConfigNotFoundFailure(t *testing.T) {
        yamlMap := map[string]interface{}{
                "rmr":  map[string]interface{}{"port": 3801, "maxMsgSize": 4096},
                "http": map[string]interface{}{"port": 3800},
        yamlMap := map[string]interface{}{
                "rmr":  map[string]interface{}{"port": 3801, "maxMsgSize": 4096},
                "http": map[string]interface{}{"port": 3800},
+               "routingManager":    map[string]interface{}{"baseUrl": "http://iltlv740.intl.att.com:8080/ric/v1/handles/"},
        }
        buf, err := yaml.Marshal(yamlMap)
        if err != nil {
        }
        buf, err := yaml.Marshal(yamlMap)
        if err != nil {
@@ -107,7 +111,7 @@ func TestLoggingConfigNotFoundFailure(t *testing.T) {
        if err != nil {
                t.Errorf("#TestRmrConfigNotFoundFailure - failed to write configuration file: %s\n", configPath)
        }
        if err != nil {
                t.Errorf("#TestRmrConfigNotFoundFailure - failed to write configuration file: %s\n", configPath)
        }
-       assert.PanicsWithValue(t, "#configuration.fillLoggingConfig - failed to fill logging configuration: The entry 'logging' not found\n",
+       assert.PanicsWithValue(t, "#configuration.populateLoggingConfig - failed to populate logging configuration: The entry 'logging' not found\n",
                func() { ParseConfiguration() })
 }
 
                func() { ParseConfiguration() })
 }
 
@@ -127,6 +131,7 @@ func TestHttpConfigNotFoundFailure(t *testing.T) {
        yamlMap := map[string]interface{}{
                "rmr":     map[string]interface{}{"port": 3801, "maxMsgSize": 4096},
                "logging": map[string]interface{}{"logLevel": "info"},
        yamlMap := map[string]interface{}{
                "rmr":     map[string]interface{}{"port": 3801, "maxMsgSize": 4096},
                "logging": map[string]interface{}{"logLevel": "info"},
+               "routingManager":    map[string]interface{}{"baseUrl": "http://iltlv740.intl.att.com:8080/ric/v1/handles/"},
        }
        buf, err := yaml.Marshal(yamlMap)
        if err != nil {
        }
        buf, err := yaml.Marshal(yamlMap)
        if err != nil {
@@ -136,6 +141,36 @@ func TestHttpConfigNotFoundFailure(t *testing.T) {
        if err != nil {
                t.Errorf("#TestHttpConfigNotFoundFailure - failed to write configuration file: %s\n", configPath)
        }
        if err != nil {
                t.Errorf("#TestHttpConfigNotFoundFailure - failed to write configuration file: %s\n", configPath)
        }
-       assert.PanicsWithValue(t, "#configuration.fillHttpConfig - failed to fill HTTP configuration: The entry 'http' not found\n",
+       assert.PanicsWithValue(t, "#configuration.populateHttpConfig - failed to populate HTTP configuration: The entry 'http' not found\n",
+               func() { ParseConfiguration() })
+}
+
+func TestRoutingManagerConfigNotFoundFailure(t *testing.T) {
+       configPath := "../resources/configuration.yaml"
+       configPathTmp := "../resources/configuration.yaml_tmp"
+       err := os.Rename(configPath, configPathTmp)
+       if err != nil {
+               t.Errorf("#TestRoutingManagerConfigNotFoundFailure - failed to rename configuration file: %s\n", configPath)
+       }
+       defer func() {
+               err = os.Rename(configPathTmp, configPath)
+               if err != nil {
+                       t.Errorf("#TestRoutingManagerConfigNotFoundFailure - failed to rename configuration file: %s\n", configPath)
+               }
+       }()
+       yamlMap := map[string]interface{}{
+               "rmr":     map[string]interface{}{"port": 3801, "maxMsgSize": 4096},
+               "logging": map[string]interface{}{"logLevel": "info"},
+               "http": map[string]interface{}{"port": 3800},
+       }
+       buf, err := yaml.Marshal(yamlMap)
+       if err != nil {
+               t.Errorf("#TestRoutingManagerConfigNotFoundFailure - failed to marshal configuration map\n")
+       }
+       err = ioutil.WriteFile("../resources/configuration.yaml", buf, 0644)
+       if err != nil {
+               t.Errorf("#TestRoutingManagerConfigNotFoundFailure - failed to write configuration file: %s\n", configPath)
+       }
+       assert.PanicsWithValue(t, "#configuration.populateRoutingManagerConfig - failed to populate Routing Manager configuration: The entry 'routingManager' not found\n",
                func() { ParseConfiguration() })
 }
                func() { ParseConfiguration() })
 }
index feb9ae0..d5f8e1e 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.
 ---
 # The Jenkins job requires a tag to build the Docker image.
 # Global-JJB script assumes this file is in the repo root.
 ---
-tag: 2.0.10
+tag: 3.0.3
diff --git a/E2Manager/controllers/e2t_controller.go b/E2Manager/controllers/e2t_controller.go
new file mode 100644 (file)
index 0000000..2d95542
--- /dev/null
@@ -0,0 +1,121 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package controllers
+
+import (
+       "e2mgr/e2managererrors"
+       "e2mgr/logger"
+       "e2mgr/models"
+       "e2mgr/providers/httpmsghandlerprovider"
+       "encoding/json"
+       "net/http"
+       "net/http/httputil"
+       "strings"
+)
+
+type IE2TController interface {
+       GetE2TInstances(writer http.ResponseWriter, r *http.Request)
+}
+
+type E2TController struct {
+       logger          *logger.Logger
+       handlerProvider *httpmsghandlerprovider.IncomingRequestHandlerProvider
+}
+
+func NewE2TController(logger *logger.Logger, handlerProvider *httpmsghandlerprovider.IncomingRequestHandlerProvider) *E2TController {
+       return &E2TController{
+               logger:          logger,
+               handlerProvider: handlerProvider,
+       }
+}
+
+func (c *E2TController) GetE2TInstances(writer http.ResponseWriter, r *http.Request) {
+       c.logger.Infof("[Client -> E2 Manager] #E2TController.GetE2TInstances - request: %v", c.prettifyRequest(r))
+       c.handleRequest(writer, &r.Header, httpmsghandlerprovider.GetE2TInstancesRequest, nil, false)
+}
+
+func (c *E2TController) handleRequest(writer http.ResponseWriter, header *http.Header, requestName httpmsghandlerprovider.IncomingRequest, request models.Request, validateHeader bool) {
+
+       handler, err := c.handlerProvider.GetHandler(requestName)
+
+       if err != nil {
+               c.handleErrorResponse(err, writer)
+               return
+       }
+
+       response, err := handler.Handle(request)
+
+       if err != nil {
+               c.handleErrorResponse(err, writer)
+               return
+       }
+
+       if response == nil {
+               writer.WriteHeader(http.StatusNoContent)
+               c.logger.Infof("[E2 Manager -> Client] #E2TController.handleRequest - status response: %v", http.StatusNoContent)
+               return
+       }
+
+       result, err := response.Marshal()
+
+       if err != nil {
+               c.handleErrorResponse(err, writer)
+               return
+       }
+
+       c.logger.Infof("[E2 Manager -> Client] #E2TController.handleRequest - response: %s", result)
+       writer.Header().Set("Content-Type", "application/json")
+       writer.Write(result)
+}
+
+func (c *E2TController) handleErrorResponse(err error, writer http.ResponseWriter) {
+
+       var errorResponseDetails models.ErrorResponse
+       var httpError int
+
+       if err != nil {
+               switch err.(type) {
+               case *e2managererrors.RnibDbError:
+                       e2Error, _ := err.(*e2managererrors.RnibDbError)
+                       errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
+                       httpError = http.StatusInternalServerError
+               default:
+                       e2Error := e2managererrors.NewInternalError()
+                       errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
+                       httpError = http.StatusInternalServerError
+               }
+       }
+
+       errorResponse, _ := json.Marshal(errorResponseDetails)
+
+       c.logger.Errorf("[E2 Manager -> Client] #E2TController.handleErrorResponse - http status: %d, error response: %+v", httpError, errorResponseDetails)
+
+       writer.Header().Set("Content-Type", "application/json")
+       writer.WriteHeader(httpError)
+       _, err = writer.Write(errorResponse)
+
+       if err != nil {
+               c.logger.Errorf("#E2TController.handleErrorResponse - Cannot send response. writer:%v", writer)
+       }
+}
+
+func (c *E2TController) prettifyRequest(request *http.Request) string {
+       dump, _ := httputil.DumpRequest(request, true)
+       requestPrettyPrint := strings.Replace(string(dump), "\r\n", " ", -1)
+       return strings.Replace(requestPrettyPrint, "\n", "", -1)
+}
index 912b4a9..cbfa7d6 100644 (file)
@@ -176,7 +176,7 @@ func (c *NodebController) handleRequest(writer http.ResponseWriter, header *http
 
        c.logger.Infof("[E2 Manager -> Client] #NodebController.handleRequest - response: %s", result)
        writer.Header().Set("Content-Type", "application/json")
 
        c.logger.Infof("[E2 Manager -> Client] #NodebController.handleRequest - response: %s", result)
        writer.Header().Set("Content-Type", "application/json")
-       writer.Write([]byte(result))
+       writer.Write(result)
 }
 
 func (c *NodebController) validateRequestHeader(header *http.Header) error {
 }
 
 func (c *NodebController) validateRequestHeader(header *http.Header) error {
@@ -228,7 +228,10 @@ func (c *NodebController) handleErrorResponse(err error, writer http.ResponseWri
                        e2Error, _ := err.(*e2managererrors.ResourceNotFoundError)
                        errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
                        httpError = http.StatusNotFound
                        e2Error, _ := err.(*e2managererrors.ResourceNotFoundError)
                        errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
                        httpError = http.StatusNotFound
-
+               case *e2managererrors.E2TInstanceAbsenceError:
+                       e2Error, _ := err.(*e2managererrors.E2TInstanceAbsenceError)
+                       errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
+                       httpError = http.StatusServiceUnavailable
                default:
                        e2Error := e2managererrors.NewInternalError()
                        errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
                default:
                        e2Error := e2managererrors.NewInternalError()
                        errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
index 47b217b..f819138 100644 (file)
@@ -30,7 +30,6 @@ import (
        "e2mgr/mocks"
        "e2mgr/models"
        "e2mgr/providers/httpmsghandlerprovider"
        "e2mgr/mocks"
        "e2mgr/models"
        "e2mgr/providers/httpmsghandlerprovider"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
@@ -39,7 +38,6 @@ import (
        "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"
        "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"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/gorilla/mux"
        "github.com/pkg/errors"
        "github.com/stretchr/testify/assert"
        "github.com/gorilla/mux"
        "github.com/pkg/errors"
        "github.com/stretchr/testify/assert"
@@ -67,30 +65,27 @@ type controllerGetNodebIdListTestContext struct {
        expectedJsonResponse string
 }
 
        expectedJsonResponse string
 }
 
-func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock) {
+func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock) {
        log := initLog(t)
        config := configuration.ParseConfiguration()
 
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        readerMock := &mocks.RnibReaderMock{}
        log := initLog(t)
        config := configuration.ParseConfiguration()
 
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        readerMock := &mocks.RnibReaderMock{}
-       readerProvider := func() reader.RNibReader {
-               return readerMock
-       }
+
        writerMock := &mocks.RnibWriterMock{}
        writerMock := &mocks.RnibWriterMock{}
-       writerProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
-       rnibDataService := services.NewRnibDataService(log, config, readerProvider, writerProvider)
+
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
        rmrSender := getRmrSender(rmrMessengerMock, log)
        ranSetupManager := managers.NewRanSetupManager(log, rmrSender, rnibDataService)
        rmrSender := getRmrSender(rmrMessengerMock, log)
        ranSetupManager := managers.NewRanSetupManager(log, rmrSender, rnibDataService)
-       handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, ranSetupManager)
+       e2tInstancesManager := &mocks.E2TInstancesManagerMock{}
+       handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, ranSetupManager, e2tInstancesManager)
        controller := NewNodebController(log, handlerProvider)
        controller := NewNodebController(log, handlerProvider)
-       return controller, readerMock, writerMock, rmrMessengerMock
+       return controller, readerMock, writerMock, rmrMessengerMock, e2tInstancesManager
 }
 
 func TestX2SetupInvalidBody(t *testing.T) {
 
 }
 
 func TestX2SetupInvalidBody(t *testing.T) {
 
-       controller, _, _, _ := setupControllerTest(t)
+       controller, _, _, _, _ := setupControllerTest(t)
 
        header := http.Header{}
        header.Set("Content-Type", "application/json")
 
        header := http.Header{}
        header.Set("Content-Type", "application/json")
@@ -108,20 +103,23 @@ func TestX2SetupInvalidBody(t *testing.T) {
 
 func TestX2SetupSuccess(t *testing.T) {
 
 
 func TestX2SetupSuccess(t *testing.T) {
 
-       controller, readerMock, writerMock, rmrMessengerMock := setupControllerTest(t)
+       controller, readerMock, writerMock, rmrMessengerMock, _ := setupControllerTest(t)
 
        ranName := "test"
 
        ranName := "test"
-       nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+       nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, AssociatedE2TInstanceAddress:"10.0.2.15:8989"}
        readerMock.On("GetNodeb", ranName).Return(nb, nil)
        readerMock.On("GetNodeb", ranName).Return(nb, nil)
+       var nbUpdated = *nb
+       nbUpdated.ConnectionAttempts = 0
+       writerMock.On("UpdateNodebInfo", &nbUpdated).Return(nil)
 
 
-       var nbUpdated = &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
-       writerMock.On("UpdateNodebInfo", nbUpdated).Return(nil)
+       var nbUpdated2 = &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1, AssociatedE2TInstanceAddress:"10.0.2.15:8989"}
+       writerMock.On("UpdateNodebInfo", nbUpdated2).Return(nil)
 
        payload := e2pdus.PackedX2setupRequest
 
        payload := e2pdus.PackedX2setupRequest
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
+       var xAction []byte
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xAction)
 
 
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
 
        header := http.Header{}
        header.Set("Content-Type", "application/json")
 
        header := http.Header{}
        header.Set("Content-Type", "application/json")
@@ -134,22 +132,26 @@ func TestX2SetupSuccess(t *testing.T) {
        assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
 }
 
        assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
 }
 
+
 func TestEndcSetupSuccess(t *testing.T) {
 
 func TestEndcSetupSuccess(t *testing.T) {
 
-       controller, readerMock, writerMock, rmrMessengerMock := setupControllerTest(t)
+       controller, readerMock, writerMock, rmrMessengerMock, _ := setupControllerTest(t)
 
        ranName := "test"
 
        ranName := "test"
-       nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST}
+       nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, AssociatedE2TInstanceAddress:"10.0.2.15:8989"}
        readerMock.On("GetNodeb", ranName).Return(nb, nil)
        readerMock.On("GetNodeb", ranName).Return(nb, nil)
+       var nbUpdated = *nb
+       nbUpdated.ConnectionAttempts = 0
+       writerMock.On("UpdateNodebInfo", &nbUpdated).Return(nil)
 
 
-       var nbUpdated = &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, ConnectionAttempts: 1}
-       writerMock.On("UpdateNodebInfo", nbUpdated).Return(nil)
+       var nbUpdated2 = &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, ConnectionAttempts: 1, AssociatedE2TInstanceAddress:"10.0.2.15:8989"}
+       writerMock.On("UpdateNodebInfo", nbUpdated2).Return(nil)
 
        payload := e2pdus.PackedEndcX2setupRequest
 
        payload := e2pdus.PackedEndcX2setupRequest
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
+       var xAction[]byte
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xAction)
 
 
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
 
        header := http.Header{}
        header.Set("Content-Type", "application/json")
 
        header := http.Header{}
        header.Set("Content-Type", "application/json")
@@ -163,7 +165,7 @@ func TestEndcSetupSuccess(t *testing.T) {
 }
 
 func TestShutdownHandlerRnibError(t *testing.T) {
 }
 
 func TestShutdownHandlerRnibError(t *testing.T) {
-       controller, readerMock, _, _ := setupControllerTest(t)
+       controller, readerMock, _, _, _ := setupControllerTest(t)
 
        rnibErr := &common.ResourceNotFoundError{}
        var nbIdentityList []*entities.NbIdentity
 
        rnibErr := &common.ResourceNotFoundError{}
        var nbIdentityList []*entities.NbIdentity
@@ -180,7 +182,7 @@ func TestShutdownHandlerRnibError(t *testing.T) {
 }
 
 func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTestContext) {
 }
 
 func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTestContext) {
-       controller, readerMock, _, _ := setupControllerTest(t)
+       controller, readerMock, _, _, _ := setupControllerTest(t)
        writer := httptest.NewRecorder()
        readerMock.On("GetNodeb", context.ranName).Return(context.nodebInfo, context.rnibError)
        req, _ := http.NewRequest("GET", "/nodeb", nil)
        writer := httptest.NewRecorder()
        readerMock.On("GetNodeb", context.ranName).Return(context.nodebInfo, context.rnibError)
        req, _ := http.NewRequest("GET", "/nodeb", nil)
@@ -192,7 +194,7 @@ func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTes
 }
 
 func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNodebIdListTestContext) {
 }
 
 func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNodebIdListTestContext) {
-       controller, readerMock, _, _ := setupControllerTest(t)
+       controller, readerMock, _, _, _ := setupControllerTest(t)
        writer := httptest.NewRecorder()
        readerMock.On("GetListNodebIds").Return(context.nodebIdList, context.rnibError)
        req, _ := http.NewRequest("GET", "/nodeb/ids", nil)
        writer := httptest.NewRecorder()
        readerMock.On("GetListNodebIds").Return(context.nodebIdList, context.rnibError)
        req, _ := http.NewRequest("GET", "/nodeb/ids", nil)
@@ -289,7 +291,7 @@ func TestControllerGetNodebIdListInternal(t *testing.T) {
 }
 
 func TestHeaderValidationFailed(t *testing.T) {
 }
 
 func TestHeaderValidationFailed(t *testing.T) {
-       controller, _, _, _ := setupControllerTest(t)
+       controller, _, _, _, _ := setupControllerTest(t)
 
        writer := httptest.NewRecorder()
 
 
        writer := httptest.NewRecorder()
 
@@ -306,7 +308,7 @@ func TestHeaderValidationFailed(t *testing.T) {
 }
 
 func TestShutdownStatusNoContent(t *testing.T) {
 }
 
 func TestShutdownStatusNoContent(t *testing.T) {
-       controller, readerMock, _, _ := setupControllerTest(t)
+       controller, readerMock, _, _, _ := setupControllerTest(t)
 
        var rnibError error
        nbIdentityList := []*entities.NbIdentity{}
 
        var rnibError error
        nbIdentityList := []*entities.NbIdentity{}
@@ -319,7 +321,7 @@ func TestShutdownStatusNoContent(t *testing.T) {
 }
 
 func TestHandleInternalError(t *testing.T) {
 }
 
 func TestHandleInternalError(t *testing.T) {
-       controller, _, _, _ := setupControllerTest(t)
+       controller, _, _, _, _ := setupControllerTest(t)
 
        writer := httptest.NewRecorder()
        err := e2managererrors.NewInternalError()
 
        writer := httptest.NewRecorder()
        err := e2managererrors.NewInternalError()
@@ -333,7 +335,7 @@ func TestHandleInternalError(t *testing.T) {
 }
 
 func TestHandleCommandAlreadyInProgressError(t *testing.T) {
 }
 
 func TestHandleCommandAlreadyInProgressError(t *testing.T) {
-       controller, _, _, _ := setupControllerTest(t)
+       controller, _, _, _, _ := setupControllerTest(t)
        writer := httptest.NewRecorder()
        err := e2managererrors.NewCommandAlreadyInProgressError()
 
        writer := httptest.NewRecorder()
        err := e2managererrors.NewCommandAlreadyInProgressError()
 
@@ -345,8 +347,22 @@ func TestHandleCommandAlreadyInProgressError(t *testing.T) {
        assert.Equal(t, errorResponse.Message, err.Message)
 }
 
        assert.Equal(t, errorResponse.Message, err.Message)
 }
 
+func TestHandleE2TInstanceAbsenceError(t *testing.T) {
+       controller, _, _, _, _ := setupControllerTest(t)
+
+       writer := httptest.NewRecorder()
+       err := e2managererrors.NewE2TInstanceAbsenceError()
+
+       controller.handleErrorResponse(err, writer)
+       var errorResponse = parseJsonRequest(t, writer.Body)
+
+       assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
+       assert.Equal(t, errorResponse.Code, err.Code)
+       assert.Equal(t, errorResponse.Message, err.Message)
+}
+
 func TestValidateHeaders(t *testing.T) {
 func TestValidateHeaders(t *testing.T) {
-       controller, _, _, _ := setupControllerTest(t)
+       controller, _, _, _, _ := setupControllerTest(t)
 
        header := http.Header{}
        header.Set("Content-Type", "application/json")
 
        header := http.Header{}
        header.Set("Content-Type", "application/json")
@@ -376,12 +392,12 @@ func initLog(t *testing.T) *logger.Logger {
 }
 
 func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
 }
 
 func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
-       controller, readerMock, _, rmrMessengerMock := setupControllerTest(t)
+       controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
 
        ranName := "test1"
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
 
        ranName := "test1"
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xaction)
+       var xAction []byte
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction)
        rmrMessengerMock.On("SendMsg", msg, mock.Anything).Return(msg, nil)
 
        writer := httptest.NewRecorder()
        rmrMessengerMock.On("SendMsg", msg, mock.Anything).Return(msg, nil)
 
        writer := httptest.NewRecorder()
@@ -401,14 +417,14 @@ func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
 }
 
 func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
 }
 
 func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
-       controller, readerMock, _, rmrMessengerMock := setupControllerTest(t)
+       controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
 
        ranName := "test1"
        // o&m intervention
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
 
        ranName := "test1"
        // o&m intervention
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", msg).Return(msg, nil)
+       var xAction []byte
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction)
+       rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
 
        writer := httptest.NewRecorder()
 
 
        writer := httptest.NewRecorder()
 
@@ -426,7 +442,7 @@ func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
 }
 
 func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
 }
 
 func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
-       controller, _, _, _ := setupControllerTest(t)
+       controller, _, _, _ , _:= setupControllerTest(t)
 
        ranName := "test1"
 
 
        ranName := "test1"
 
@@ -443,7 +459,7 @@ func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
 }
 
 func TestHandleErrorResponse(t *testing.T) {
 }
 
 func TestHandleErrorResponse(t *testing.T) {
-       controller, _, _, _ := setupControllerTest(t)
+       controller, _, _, _ , _:= setupControllerTest(t)
 
        writer := httptest.NewRecorder()
        controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer)
 
        writer := httptest.NewRecorder()
        controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer)
@@ -481,5 +497,5 @@ func TestHandleErrorResponse(t *testing.T) {
 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
-       return rmrsender.NewRmrSender(log, &rmrMessenger)
+       return rmrsender.NewRmrSender(log, rmrMessenger)
 }
 }
index 289e20b..42d0bdf 100644 (file)
@@ -24,12 +24,10 @@ import (
        "e2mgr/configuration"
        "e2mgr/logger"
        "e2mgr/mocks"
        "e2mgr/configuration"
        "e2mgr/logger"
        "e2mgr/mocks"
-       "e2mgr/rNibWriter"
        "e2mgr/services"
        "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"
        "e2mgr/services"
        "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"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/assert"
        "net"
        "net/http"
        "github.com/stretchr/testify/assert"
        "net"
        "net/http"
@@ -44,13 +42,10 @@ func setupNodebControllerTest(t *testing.T) (services.RNibDataService, *mocks.Rn
        }
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
        }
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return &mocks.RnibWriterMock{}
-       }
-       rnibDataService := services.NewRnibDataService(logger, config, rnibReaderProvider, rnibWriterProvider)
+
+       writerMock := &mocks.RnibWriterMock{}
+
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
        return rnibDataService, readerMock
 }
 
        return rnibDataService, readerMock
 }
 
@@ -26,11 +26,27 @@ package converters
 // #include <x2setup_response_wrapper.h>
 import "C"
 import (
 // #include <x2setup_response_wrapper.h>
 import "C"
 import (
+       "e2mgr/e2pdus"
        "e2mgr/logger"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "unsafe"
 )
 
        "e2mgr/logger"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "unsafe"
 )
 
+type EndcSetupFailureResponseConverter struct {
+       logger *logger.Logger
+}
+
+type IEndcSetupFailureResponseConverter interface {
+       UnpackEndcSetupFailureResponseAndExtract(packedBuf []byte) (*entities.SetupFailure, error)
+}
+
+func NewEndcSetupFailureResponseConverter(logger *logger.Logger) *EndcSetupFailureResponseConverter {
+       return &EndcSetupFailureResponseConverter{
+               logger: logger,
+       }
+}
+
+
 // Populate and return the EN-DC/X2 setup response failure structure with data from the pdu
 func endcX2SetupFailureResponseToProtobuf(pdu *C.E2AP_PDU_t) (*entities.SetupFailure, error) {
        setupFailure := entities.SetupFailure{}
 // Populate and return the EN-DC/X2 setup response failure structure with data from the pdu
 func endcX2SetupFailureResponseToProtobuf(pdu *C.E2AP_PDU_t) (*entities.SetupFailure, error) {
        setupFailure := entities.SetupFailure{}
@@ -71,8 +87,8 @@ func endcX2SetupFailureResponseToProtobuf(pdu *C.E2AP_PDU_t) (*entities.SetupFai
        return &setupFailure, nil
 }
 
        return &setupFailure, nil
 }
 
-func UnpackEndcX2SetupFailureResponseAndExtract(logger *logger.Logger, allocationBufferSize int, packedBufferSize int, packedBuf []byte, maxMessageBufferSize int) (*entities.SetupFailure, error) {
-       pdu, err := UnpackX2apPdu(logger, allocationBufferSize, packedBufferSize, packedBuf, maxMessageBufferSize)
+func (c *EndcSetupFailureResponseConverter) UnpackEndcSetupFailureResponseAndExtract(packedBuf []byte) (*entities.SetupFailure, error) {
+       pdu, err := UnpackX2apPdu(c.logger, e2pdus.MaxAsn1CodecAllocationBufferSize, len(packedBuf), packedBuf, e2pdus.MaxAsn1CodecMessageBufferSize)
        if err != nil {
                return nil, err
        }
        if err != nil {
                return nil, err
        }
@@ -22,7 +22,6 @@
 package converters
 
 import (
 package converters
 
 import (
-       "e2mgr/e2pdus"
        "e2mgr/logger"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "e2mgr/logger"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
@@ -78,6 +77,8 @@ func TestUnpackEndcX2SetupFailureResponseAndExtract(t *testing.T) {
                /**** shares the same code with x2setup failure response to protobuf ****/
        }
 
                /**** shares the same code with x2setup failure response to protobuf ****/
        }
 
+       converter := NewEndcSetupFailureResponseConverter(logger)
+
        for _, tc := range testCases {
                t.Run(tc.packedPdu, func(t *testing.T) {
 
        for _, tc := range testCases {
                t.Run(tc.packedPdu, func(t *testing.T) {
 
@@ -87,7 +88,7 @@ func TestUnpackEndcX2SetupFailureResponseAndExtract(t *testing.T) {
                                t.Errorf("convert inputPayloadAsStr to payloadAsByte. Error: %v\n", err)
                        }
 
                                t.Errorf("convert inputPayloadAsStr to payloadAsByte. Error: %v\n", err)
                        }
 
-                       response, err := UnpackEndcX2SetupFailureResponseAndExtract(logger, e2pdus.MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, len(payload), payload, e2pdus.MaxAsn1CodecMessageBufferSize /*message buffer*/)
+                       response, err := converter.UnpackEndcSetupFailureResponseAndExtract(payload)
 
                        if err != nil {
                                if tc.failure == nil {
 
                        if err != nil {
                                if tc.failure == nil {
@@ -26,10 +26,10 @@ package converters
 // #include <x2setup_response_wrapper.h>
 import "C"
 import (
 // #include <x2setup_response_wrapper.h>
 import "C"
 import (
+       "e2mgr/e2pdus"
        "e2mgr/logger"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "e2mgr/logger"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-//     "github.com/pkg/errors"
        "unsafe"
 )
 
        "unsafe"
 )
 
@@ -39,6 +39,20 @@ const (
        maxnoofNrCellBands = 32
 )
 
        maxnoofNrCellBands = 32
 )
 
+type EndcSetupResponseConverter struct {
+       logger *logger.Logger
+}
+
+type IEndcSetupResponseConverter interface {
+       UnpackEndcSetupResponseAndExtract(packedBuf []byte) (*entities.GlobalNbId, *entities.Gnb, error)
+}
+
+func NewEndcSetupResponseConverter(logger *logger.Logger) *EndcSetupResponseConverter {
+       return &EndcSetupResponseConverter{
+               logger: logger,
+       }
+}
+
 func getNRFreqInfo(freqInfo C.NRFreqInfo_t) (*entities.NrFrequencyInfo, error) {
        var info *entities.NrFrequencyInfo
        info = &entities.NrFrequencyInfo{NrArFcn: uint64(freqInfo.nRARFCN)}
 func getNRFreqInfo(freqInfo C.NRFreqInfo_t) (*entities.NrFrequencyInfo, error) {
        var info *entities.NrFrequencyInfo
        info = &entities.NrFrequencyInfo{NrArFcn: uint64(freqInfo.nRARFCN)}
@@ -60,7 +74,7 @@ func getNRFreqInfo(freqInfo C.NRFreqInfo_t) (*entities.NrFrequencyInfo, error) {
                        frequencyBand := &entities.FrequencyBandItem{NrFrequencyBand: uint32(freqBandNrItem.freqBandIndicatorNr)}
 
                        if freqBandNrItem.supportedSULBandList.list.count > 0 && freqBandNrItem.supportedSULBandList.list.count <= maxnoofNrCellBands {
                        frequencyBand := &entities.FrequencyBandItem{NrFrequencyBand: uint32(freqBandNrItem.freqBandIndicatorNr)}
 
                        if freqBandNrItem.supportedSULBandList.list.count > 0 && freqBandNrItem.supportedSULBandList.list.count <= maxnoofNrCellBands {
-                               count:= int(freqBandNrItem.supportedSULBandList.list.count)
+                               count := int(freqBandNrItem.supportedSULBandList.list.count)
                                supportedSULBandList_slice := (*[1 << 30]*C.SupportedSULFreqBandItem_t)(unsafe.Pointer(freqBandNrItem.supportedSULBandList.list.array))[:count:count]
                                for _, supportedSULFreqBandItem := range supportedSULBandList_slice {
                                        frequencyBand.SupportedSulBands = append(frequencyBand.SupportedSulBands, uint32(supportedSULFreqBandItem.freqBandIndicatorNr))
                                supportedSULBandList_slice := (*[1 << 30]*C.SupportedSULFreqBandItem_t)(unsafe.Pointer(freqBandNrItem.supportedSULBandList.list.array))[:count:count]
                                for _, supportedSULFreqBandItem := range supportedSULBandList_slice {
                                        frequencyBand.SupportedSulBands = append(frequencyBand.SupportedSulBands, uint32(supportedSULFreqBandItem.freqBandIndicatorNr))
@@ -165,7 +179,7 @@ func getnRNeighbourInfo(neighbour_Information *C.NRNeighbour_Information_t) ([]*
        var neighbours []*entities.NrNeighbourInformation
 
        if neighbour_Information != nil && neighbour_Information.list.count > 0 && neighbour_Information.list.count <= maxofNRNeighbours {
        var neighbours []*entities.NrNeighbourInformation
 
        if neighbour_Information != nil && neighbour_Information.list.count > 0 && neighbour_Information.list.count <= maxofNRNeighbours {
-               count:=int(neighbour_Information.list.count)
+               count := int(neighbour_Information.list.count)
                neighbour_Information_slice := (*[1 << 30]*C.NRNeighbour_Information__Member)(unsafe.Pointer(neighbour_Information.list.array))[:count:count]
                for _, member := range neighbour_Information_slice {
                        info := &entities.NrNeighbourInformation{NrPci: uint32(member.nrpCI)}
                neighbour_Information_slice := (*[1 << 30]*C.NRNeighbour_Information__Member)(unsafe.Pointer(neighbour_Information.list.array))[:count:count]
                for _, member := range neighbour_Information_slice {
                        info := &entities.NrNeighbourInformation{NrPci: uint32(member.nrpCI)}
@@ -206,7 +220,7 @@ func getServedNRCells(servedNRcellsManagementList *C.ServedNRcellsENDCX2Manageme
        var servedNRCells []*entities.ServedNRCell
 
        if servedNRcellsManagementList != nil && servedNRcellsManagementList.list.count > 0 && servedNRcellsManagementList.list.count <= maxCellinengNB {
        var servedNRCells []*entities.ServedNRCell
 
        if servedNRcellsManagementList != nil && servedNRcellsManagementList.list.count > 0 && servedNRcellsManagementList.list.count <= maxCellinengNB {
-               count :=int(servedNRcellsManagementList.list.count)
+               count := int(servedNRcellsManagementList.list.count)
                servedNRcellsENDCX2ManagementList__Member_slice := (*[1 << 30]*C.ServedNRcellsENDCX2ManagementList__Member)(unsafe.Pointer(servedNRcellsManagementList.list.array))[:count:count]
                for _, servedNRcellsENDCX2ManagementList__Member := range servedNRcellsENDCX2ManagementList__Member_slice {
                        servedNRCellInfo := servedNRcellsENDCX2ManagementList__Member.servedNRCellInfo
                servedNRcellsENDCX2ManagementList__Member_slice := (*[1 << 30]*C.ServedNRcellsENDCX2ManagementList__Member)(unsafe.Pointer(servedNRcellsManagementList.list.array))[:count:count]
                for _, servedNRcellsENDCX2ManagementList__Member := range servedNRcellsENDCX2ManagementList__Member_slice {
                        servedNRCellInfo := servedNRcellsENDCX2ManagementList__Member.servedNRCellInfo
@@ -226,7 +240,7 @@ func getServedNRCells(servedNRcellsManagementList *C.ServedNRcellsENDCX2Manageme
                        }
 
                        if servedNRCellInfo.broadcastPLMNs.list.count > 0 && servedNRCellInfo.broadcastPLMNs.list.count <= maxnoofBPLMNs {
                        }
 
                        if servedNRCellInfo.broadcastPLMNs.list.count > 0 && servedNRCellInfo.broadcastPLMNs.list.count <= maxnoofBPLMNs {
-                               count:=int(servedNRCellInfo.broadcastPLMNs.list.count)
+                               count := int(servedNRCellInfo.broadcastPLMNs.list.count)
                                pLMN_Identity_slice := (*[1 << 30]*C.PLMN_Identity_t)(unsafe.Pointer(servedNRCellInfo.broadcastPLMNs.list.array))[:count:count]
                                for _, pLMN_Identity := range pLMN_Identity_slice {
                                        servedNRCell.ServedNrCellInformation.ServedPlmns = append(servedNRCell.ServedNrCellInformation.ServedPlmns, fmt.Sprintf("%02x", C.GoBytes(unsafe.Pointer(pLMN_Identity.buf), C.int(pLMN_Identity.size))))
                                pLMN_Identity_slice := (*[1 << 30]*C.PLMN_Identity_t)(unsafe.Pointer(servedNRCellInfo.broadcastPLMNs.list.array))[:count:count]
                                for _, pLMN_Identity := range pLMN_Identity_slice {
                                        servedNRCell.ServedNrCellInformation.ServedPlmns = append(servedNRCell.ServedNrCellInformation.ServedPlmns, fmt.Sprintf("%02x", C.GoBytes(unsafe.Pointer(pLMN_Identity.buf), C.int(pLMN_Identity.size))))
@@ -274,7 +288,7 @@ func endcX2SetupResponseToProtobuf(pdu *C.E2AP_PDU_t) (*entities.GlobalNbId, *en
                if successfulOutcome != nil && successfulOutcome.value.present == C.SuccessfulOutcome__value_PR_ENDCX2SetupResponse {
                        endcX2SetupResponse := (*C.ENDCX2SetupResponse_t)(unsafe.Pointer(&successfulOutcome.value.choice[0]))
                        if endcX2SetupResponse != nil && endcX2SetupResponse.protocolIEs.list.count > 0 {
                if successfulOutcome != nil && successfulOutcome.value.present == C.SuccessfulOutcome__value_PR_ENDCX2SetupResponse {
                        endcX2SetupResponse := (*C.ENDCX2SetupResponse_t)(unsafe.Pointer(&successfulOutcome.value.choice[0]))
                        if endcX2SetupResponse != nil && endcX2SetupResponse.protocolIEs.list.count > 0 {
-                               count:=int(endcX2SetupResponse.protocolIEs.list.count)
+                               count := int(endcX2SetupResponse.protocolIEs.list.count)
                                endcX2SetupResponse_IEs_slice := (*[1 << 30]*C.ENDCX2SetupResponse_IEs_t)(unsafe.Pointer(endcX2SetupResponse.protocolIEs.list.array))[:count:count]
                                for _, endcX2SetupResponse_IE := range endcX2SetupResponse_IEs_slice {
                                        if endcX2SetupResponse_IE.value.present == C.ENDCX2SetupResponse_IEs__value_PR_RespondingNodeType_EndcX2Setup {
                                endcX2SetupResponse_IEs_slice := (*[1 << 30]*C.ENDCX2SetupResponse_IEs_t)(unsafe.Pointer(endcX2SetupResponse.protocolIEs.list.array))[:count:count]
                                for _, endcX2SetupResponse_IE := range endcX2SetupResponse_IEs_slice {
                                        if endcX2SetupResponse_IE.value.present == C.ENDCX2SetupResponse_IEs__value_PR_RespondingNodeType_EndcX2Setup {
@@ -283,7 +297,7 @@ func endcX2SetupResponseToProtobuf(pdu *C.E2AP_PDU_t) (*entities.GlobalNbId, *en
                                                case C.RespondingNodeType_EndcX2Setup_PR_respond_en_gNB:
                                                        en_gNB_ENDCX2SetupReqAckIEs_Container := *(**C.ProtocolIE_Container_119P89_t)(unsafe.Pointer(&respondingNodeType.choice[0]))
                                                        if en_gNB_ENDCX2SetupReqAckIEs_Container != nil && en_gNB_ENDCX2SetupReqAckIEs_Container.list.count > 0 {
                                                case C.RespondingNodeType_EndcX2Setup_PR_respond_en_gNB:
                                                        en_gNB_ENDCX2SetupReqAckIEs_Container := *(**C.ProtocolIE_Container_119P89_t)(unsafe.Pointer(&respondingNodeType.choice[0]))
                                                        if en_gNB_ENDCX2SetupReqAckIEs_Container != nil && en_gNB_ENDCX2SetupReqAckIEs_Container.list.count > 0 {
-                                                               count:=int(en_gNB_ENDCX2SetupReqAckIEs_Container.list.count)
+                                                               count := int(en_gNB_ENDCX2SetupReqAckIEs_Container.list.count)
                                                                en_gNB_ENDCX2SetupReqAckIEs_slice := (*[1 << 30]*C.En_gNB_ENDCX2SetupReqAckIEs_t)(unsafe.Pointer(en_gNB_ENDCX2SetupReqAckIEs_Container.list.array))[:count:count]
                                                                for _, en_gNB_ENDCX2SetupReqAckIE := range en_gNB_ENDCX2SetupReqAckIEs_slice {
                                                                        switch en_gNB_ENDCX2SetupReqAckIE.value.present {
                                                                en_gNB_ENDCX2SetupReqAckIEs_slice := (*[1 << 30]*C.En_gNB_ENDCX2SetupReqAckIEs_t)(unsafe.Pointer(en_gNB_ENDCX2SetupReqAckIEs_Container.list.array))[:count:count]
                                                                for _, en_gNB_ENDCX2SetupReqAckIE := range en_gNB_ENDCX2SetupReqAckIEs_slice {
                                                                        switch en_gNB_ENDCX2SetupReqAckIE.value.present {
@@ -318,8 +332,9 @@ func endcX2SetupResponseToProtobuf(pdu *C.E2AP_PDU_t) (*entities.GlobalNbId, *en
        return globalNbId, gnb, nil
 }
 
        return globalNbId, gnb, nil
 }
 
-func UnpackEndcX2SetupResponseAndExtract(logger *logger.Logger, allocationBufferSize int, packedBufferSize int, packedBuf []byte, maxMessageBufferSize int) (*entities.GlobalNbId, *entities.Gnb, error) {
-       pdu, err := UnpackX2apPdu(logger, allocationBufferSize, packedBufferSize, packedBuf, maxMessageBufferSize)
+func (c *EndcSetupResponseConverter) UnpackEndcSetupResponseAndExtract(packedBuf []byte) (*entities.GlobalNbId, *entities.Gnb, error) {
+       pdu, err := UnpackX2apPdu(c.logger, e2pdus.MaxAsn1CodecAllocationBufferSize, len(packedBuf), packedBuf, e2pdus.MaxAsn1CodecMessageBufferSize)
+
        if err != nil {
                return nil, nil, err
        }
        if err != nil {
                return nil, nil, err
        }
@@ -22,7 +22,6 @@
 package converters
 
 import (
 package converters
 
 import (
-       "e2mgr/e2pdus"
        "e2mgr/logger"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "e2mgr/logger"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
@@ -559,6 +558,8 @@ func TestUnpackEndcX2SetupResponseAndExtract(t *testing.T) {
                        failure: fmt.Errorf("getList for path [successfulOutcome_t ENDCX2SetupResponse protocolIEs_t ProtocolIE_Container_elm RespondingNodeType-EndcX2Setup respond_en_gNB_t ProtocolIE_Container_elm ServedNRcellsENDCX2ManagementList ServedNRcellsENDCX2ManagementList_elm servedNRCellInfo_t nrpCI_t] failed, rc = 1" /*NO_ITEMS*/),},
        }
 
                        failure: fmt.Errorf("getList for path [successfulOutcome_t ENDCX2SetupResponse protocolIEs_t ProtocolIE_Container_elm RespondingNodeType-EndcX2Setup respond_en_gNB_t ProtocolIE_Container_elm ServedNRcellsENDCX2ManagementList ServedNRcellsENDCX2ManagementList_elm servedNRCellInfo_t nrpCI_t] failed, rc = 1" /*NO_ITEMS*/),},
        }
 
+       converter := NewEndcSetupResponseConverter(logger)
+
        for _, tc := range testCases {
                t.Run(tc.packedPdu, func(t *testing.T) {
 
        for _, tc := range testCases {
                t.Run(tc.packedPdu, func(t *testing.T) {
 
@@ -570,7 +571,7 @@ func TestUnpackEndcX2SetupResponseAndExtract(t *testing.T) {
                                t.Errorf("convert inputPayloadAsStr to payloadAsByte. Error: %v\n", err)
                        }
 
                                t.Errorf("convert inputPayloadAsStr to payloadAsByte. Error: %v\n", err)
                        }
 
-                       key, gnb, err := UnpackEndcX2SetupResponseAndExtract(logger, e2pdus.MaxAsn1CodecAllocationBufferSize, len(payload), payload, e2pdus.MaxAsn1CodecMessageBufferSize)
+                       key, gnb, err := converter.UnpackEndcSetupResponseAndExtract(payload)
 
                        if err != nil {
                                if tc.failure == nil {
 
                        if err != nil {
                                if tc.failure == nil {
diff --git a/E2Manager/e2managererrors/e2t_instance_absence_error.go b/E2Manager/e2managererrors/e2t_instance_absence_error.go
new file mode 100644 (file)
index 0000000..772d62a
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package e2managererrors
+
+type E2TInstanceAbsenceError struct {
+       *BaseError
+}
+
+func NewE2TInstanceAbsenceError() *E2TInstanceAbsenceError {
+       return &E2TInstanceAbsenceError{
+               &BaseError{
+                       Code:    510,
+                       Message: "The New RAN can't be added, please try later.",
+               },
+       }
+}
+
+func (e *E2TInstanceAbsenceError) Error() string {
+       return e.Message
+}
diff --git a/E2Manager/e2managererrors/routing_manager_error.go b/E2Manager/e2managererrors/routing_manager_error.go
new file mode 100644 (file)
index 0000000..529df35
--- /dev/null
@@ -0,0 +1,29 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package e2managererrors
+
+type RoutingManagerError struct {
+}
+
+func NewRoutingManagerError() *RoutingManagerError {
+       return &RoutingManagerError{}
+}
+
+func (e *RoutingManagerError) Error() string {
+       return "Routing Manager Error"
+}
diff --git a/E2Manager/e2mgr-sonar-scanner.properties b/E2Manager/e2mgr-sonar-scanner.properties
new file mode 100644 (file)
index 0000000..a0c9ca9
--- /dev/null
@@ -0,0 +1,14 @@
+#----- Default SonarQube server
+sonar.host.url=http://135.25.121.110:9000
+sonar.projectKey=oran:e2mgr
+sonar.projectName=e2mgr
+sonar.login=admin
+sonar.password=admin
+sonar.go.coverage.reportPaths=coverage.txt
+#----- Default source code encoding
+#sonar.sourceEncoding=UTF-8
+sonar.projectBaseDir=/home/ubuntu/oran_repo/e2mgr/E2Manager/
+sonar.sources=.
+sonar.exclusions=**/*_test.go,**/generate_source.go,**/*_generated.go,**/build/**,**/.gogradle/**,**/mocks/**,**/tests/**,**/e2managererrors/**,**/enums/**
+sonar.go.golangci-lint.reportPaths=sca.xml
+
diff --git a/E2Manager/e2pdus/configuration_update.go b/E2Manager/e2pdus/configuration_update.go
new file mode 100644 (file)
index 0000000..032c6cf
--- /dev/null
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ *
+ *   Copyright (c) 2019 AT&T Intellectual Property.
+ *
+ *   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.
+ *
+ *******************************************************************************/
+package e2pdus
+
+// #cgo CFLAGS: -I../asn1codec/inc/  -I../asn1codec/e2ap_engine/
+// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec
+// #include <configuration_update_wrapper.h>
+import "C"
+import (
+       "fmt"
+       "unsafe"
+)
+
+var PackedEndcConfigurationUpdateFailure []byte
+var PackedEndcConfigurationUpdateAck []byte
+var PackedX2EnbConfigurationUpdateFailure []byte
+var PackedX2EnbConfigurationUpdateAck []byte
+
+func prepareEndcConfigurationUpdateFailurePDU(maxAsn1PackedBufferSize int, maxAsn1CodecMessageBufferSize int) error {
+
+       packedBuffer := make([]C.uchar, maxAsn1PackedBufferSize)
+       errorBuffer := make([]C.char, maxAsn1CodecMessageBufferSize)
+       var payloadSize = C.ulong(maxAsn1PackedBufferSize)
+
+       if status := C.build_pack_endc_configuration_update_failure(&payloadSize, &packedBuffer[0], C.ulong(maxAsn1CodecMessageBufferSize), &errorBuffer[0]); !status {
+               return fmt.Errorf("#configuration_update.prepareEndcConfigurationUpdateFailurePDU - failed to build and pack the endc configuration update failure message %s ", C.GoString(&errorBuffer[0]))
+
+       }
+       PackedEndcConfigurationUpdateFailure = C.GoBytes(unsafe.Pointer(&packedBuffer[0]), C.int(payloadSize))
+
+       return nil
+}
+
+func prepareX2EnbConfigurationUpdateFailurePDU(maxAsn1PackedBufferSize int, maxAsn1CodecMessageBufferSize int) error {
+
+       packedBuffer := make([]C.uchar, maxAsn1PackedBufferSize)
+       errorBuffer := make([]C.char, maxAsn1CodecMessageBufferSize)
+       var payloadSize = C.ulong(maxAsn1PackedBufferSize)
+
+       if status := C.build_pack_x2enb_configuration_update_failure(&payloadSize, &packedBuffer[0], C.ulong(maxAsn1CodecMessageBufferSize), &errorBuffer[0]); !status {
+               return fmt.Errorf("#configuration_update.prepareX2EnbConfigurationUpdateFailurePDU - failed to build and pack the x2 configuration update failure message %s ", C.GoString(&errorBuffer[0]))
+
+       }
+       PackedX2EnbConfigurationUpdateFailure = C.GoBytes(unsafe.Pointer(&packedBuffer[0]), C.int(payloadSize))
+
+       return nil
+}
+
+func prepareEndcConfigurationUpdateAckPDU(maxAsn1PackedBufferSize int, maxAsn1CodecMessageBufferSize int) error {
+
+       packedBuffer := make([]C.uchar, maxAsn1PackedBufferSize)
+       errorBuffer := make([]C.char, maxAsn1CodecMessageBufferSize)
+       var payloadSize = C.ulong(maxAsn1PackedBufferSize)
+
+       if status := C.build_pack_endc_configuration_update_ack(&payloadSize, &packedBuffer[0], C.ulong(maxAsn1CodecMessageBufferSize), &errorBuffer[0]); !status {
+               return fmt.Errorf("#configuration_update.prepareEndcConfigurationUpdateAckPDU - failed to build and pack the endc configuration update ack message %s ", C.GoString(&errorBuffer[0]))
+
+       }
+       PackedEndcConfigurationUpdateAck = C.GoBytes(unsafe.Pointer(&packedBuffer[0]), C.int(payloadSize))
+
+       return nil
+}
+
+func prepareX2EnbConfigurationUpdateAckPDU(maxAsn1PackedBufferSize int, maxAsn1CodecMessageBufferSize int) error {
+
+       packedBuffer := make([]C.uchar, maxAsn1PackedBufferSize)
+       errorBuffer := make([]C.char, maxAsn1CodecMessageBufferSize)
+       var payloadSize = C.ulong(maxAsn1PackedBufferSize)
+
+       if status := C.build_pack_x2enb_configuration_update_ack(&payloadSize, &packedBuffer[0], C.ulong(maxAsn1CodecMessageBufferSize), &errorBuffer[0]); !status {
+               return fmt.Errorf("#configuration_update.prepareX2EnbConfigurationUpdateAckPDU - failed to build and pack the x2 configuration update ack message %s ", C.GoString(&errorBuffer[0]))
+
+       }
+       PackedX2EnbConfigurationUpdateAck = C.GoBytes(unsafe.Pointer(&packedBuffer[0]), C.int(payloadSize))
+
+       return nil
+}
+
+func init() {
+       if err := prepareEndcConfigurationUpdateFailurePDU(MaxAsn1PackedBufferSize, MaxAsn1CodecMessageBufferSize); err != nil {
+               panic(err)
+       }
+       if err := prepareEndcConfigurationUpdateAckPDU(MaxAsn1PackedBufferSize, MaxAsn1CodecMessageBufferSize); err != nil {
+               panic(err)
+       }
+       if err := prepareX2EnbConfigurationUpdateFailurePDU(MaxAsn1PackedBufferSize, MaxAsn1CodecMessageBufferSize); err != nil {
+               panic(err)
+       }
+       if err := prepareX2EnbConfigurationUpdateAckPDU(MaxAsn1PackedBufferSize, MaxAsn1CodecMessageBufferSize); err != nil {
+               panic(err)
+       }
+}
diff --git a/E2Manager/e2pdus/configuration_update_test.go b/E2Manager/e2pdus/configuration_update_test.go
new file mode 100644 (file)
index 0000000..a90ba13
--- /dev/null
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ *
+ *   Copyright (c) 2019 AT&T Intellectual Property.
+ *
+ *   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.
+ *
+ *******************************************************************************/
+package e2pdus
+
+import (
+       "e2mgr/logger"
+       "fmt"
+       "strings"
+       "testing"
+)
+
+func TestPrepareEndcConfigurationUpdateFailurePDU(t *testing.T) {
+       _,err := logger.InitLogger(logger.InfoLevel)
+       if err!=nil{
+               t.Errorf("failed to initialize logger, error: %s", err)
+       }
+       packedPdu := "402500080000010005400142"
+       packedEndcConfigurationUpdateFailure := PackedEndcConfigurationUpdateFailure
+
+       tmp := fmt.Sprintf("%x", packedEndcConfigurationUpdateFailure)
+       if len(tmp) != len(packedPdu) {
+               t.Errorf("want packed len:%d, got: %d\n", len(packedPdu)/2, len(packedEndcConfigurationUpdateFailure)/2)
+       }
+
+       if strings.Compare(tmp, packedPdu) != 0 {
+               t.Errorf("\nwant :\t[%s]\n got: \t\t[%s]\n", packedPdu, tmp)
+       }
+}
+
+func TestPrepareEndcConfigurationUpdateFailurePDUFailure(t *testing.T) {
+       _, err := logger.InitLogger(logger.InfoLevel)
+       if err != nil {
+               t.Errorf("failed to initialize logger, error: %s", err)
+       }
+
+       err  = prepareEndcConfigurationUpdateFailurePDU(1, 4096)
+       if err == nil {
+               t.Errorf("want: error, got: success.\n")
+       }
+
+       expected:= "#configuration_update.prepareEndcConfigurationUpdateFailurePDU - failed to build and pack the endc configuration update failure message #src/asn1codec_utils.c.pack_pdu_aux - Encoded output of E2AP-PDU, is too big"
+       if !strings.Contains(err.Error(), expected) {
+               t.Errorf("want :[%s], got: [%s]\n", expected, err)
+       }
+}
+
+func TestPrepareX2EnbConfigurationUpdateFailurePDU(t *testing.T) {
+       _,err := logger.InitLogger(logger.InfoLevel)
+       if err!=nil{
+               t.Errorf("failed to initialize logger, error: %s", err)
+       }
+       packedPdu := "400800080000010005400142"
+       packedEndcX2ConfigurationUpdateFailure := PackedX2EnbConfigurationUpdateFailure
+
+       tmp := fmt.Sprintf("%x", packedEndcX2ConfigurationUpdateFailure)
+       if len(tmp) != len(packedPdu) {
+               t.Errorf("want packed len:%d, got: %d\n", len(packedPdu)/2, len(packedEndcX2ConfigurationUpdateFailure)/2)
+       }
+
+       if strings.Compare(tmp, packedPdu) != 0 {
+               t.Errorf("\nwant :\t[%s]\n got: \t\t[%s]\n", packedPdu, tmp)
+       }
+}
+
+func TestPrepareX2EnbConfigurationUpdateFailurePDUFailure(t *testing.T) {
+       _, err := logger.InitLogger(logger.InfoLevel)
+       if err != nil {
+               t.Errorf("failed to initialize logger, error: %s", err)
+       }
+
+       err  = prepareX2EnbConfigurationUpdateFailurePDU(1, 4096)
+       if err == nil {
+               t.Errorf("want: error, got: success.\n")
+       }
+
+       expected:= "#configuration_update.prepareX2EnbConfigurationUpdateFailurePDU - failed to build and pack the x2 configuration update failure message #src/asn1codec_utils.c.pack_pdu_aux - Encoded output of E2AP-PDU, is too big"
+       if !strings.Contains(err.Error(), expected) {
+               t.Errorf("want :[%s], got: [%s]\n", expected, err)
+       }
+}
+
+func TestPrepareEndcConfigurationUpdateAckPDU(t *testing.T) {
+       _,err := logger.InitLogger(logger.InfoLevel)
+       if err!=nil{
+               t.Errorf("failed to initialize logger, error: %s", err)
+       }
+       packedPdu := "2025000a00000100f70003000000"
+       packedEndcConfigurationUpdateAck := PackedEndcConfigurationUpdateAck
+
+       tmp := fmt.Sprintf("%x", packedEndcConfigurationUpdateAck)
+       if len(tmp) != len(packedPdu) {
+               t.Errorf("want packed len:%d, got: %d\n", len(packedPdu)/2, len(packedEndcConfigurationUpdateAck)/2)
+       }
+
+       if strings.Compare(tmp, packedPdu) != 0 {
+               t.Errorf("\nwant :\t[%s]\n got: \t\t[%s]\n", packedPdu, tmp)
+       }
+}
+
+func TestPrepareEndcConfigurationUpdateAckPDUFailure(t *testing.T) {
+       _, err := logger.InitLogger(logger.InfoLevel)
+       if err != nil {
+               t.Errorf("failed to initialize logger, error: %s", err)
+       }
+
+       err  = prepareEndcConfigurationUpdateAckPDU(1, 4096)
+       if err == nil {
+               t.Errorf("want: error, got: success.\n")
+       }
+
+       expected:= "#configuration_update.prepareEndcConfigurationUpdateAckPDU - failed to build and pack the endc configuration update ack message #src/asn1codec_utils.c.pack_pdu_aux - Encoded output of E2AP-PDU, is too big"
+       if !strings.Contains(err.Error(), expected) {
+               t.Errorf("want :[%s], got: [%s]\n", expected, err)
+       }
+}
+
+func TestPrepareX2EnbConfigurationUpdateAckPDU(t *testing.T) {
+       _,err := logger.InitLogger(logger.InfoLevel)
+       if err!=nil{
+               t.Errorf("failed to initialize logger, error: %s", err)
+       }
+       packedPdu := "200800080000010011400100"
+       packedEndcX2ConfigurationUpdateAck := PackedX2EnbConfigurationUpdateAck
+
+       tmp := fmt.Sprintf("%x", packedEndcX2ConfigurationUpdateAck)
+       if len(tmp) != len(packedPdu) {
+               t.Errorf("want packed len:%d, got: %d\n", len(packedPdu)/2, len(packedEndcX2ConfigurationUpdateAck)/2)
+       }
+
+       if strings.Compare(tmp, packedPdu) != 0 {
+               t.Errorf("\nwant :\t[%s]\n got: \t\t[%s]\n", packedPdu, tmp)
+       }
+}
+
+func TestPrepareX2EnbConfigurationUpdateAckPDUFailure(t *testing.T) {
+       _, err := logger.InitLogger(logger.InfoLevel)
+       if err != nil {
+               t.Errorf("failed to initialize logger, error: %s", err)
+       }
+
+       err  = prepareX2EnbConfigurationUpdateAckPDU(1, 4096)
+       if err == nil {
+               t.Errorf("want: error, got: success.\n")
+       }
+
+       expected:= "#configuration_update.prepareX2EnbConfigurationUpdateAckPDU - failed to build and pack the x2 configuration update ack message #src/asn1codec_utils.c.pack_pdu_aux - Encoded output of E2AP-PDU, is too big"
+       if !strings.Contains(err.Error(), expected) {
+               t.Errorf("want :[%s], got: [%s]\n", expected, err)
+       }
+}
\ No newline at end of file
index 12789ec..e63577b 100644 (file)
@@ -23,81 +23,11 @@ package e2pdus
 
 import (
        "bytes"
 
 import (
        "bytes"
-       "e2mgr/logger"
        "fmt"
        "strings"
        "testing"
 )
 
        "fmt"
        "strings"
        "testing"
 )
 
-func TestPreparePackedEndcX2SetupRequest(t *testing.T) {
-       _,err := logger.InitLogger(logger.InfoLevel)
-       if err!=nil{
-               t.Errorf("failed to initialize logger, error: %s", err)
-       }
-       packedPdu := "0024003100000100f4002a0000020015000800bbbccc00abcde000fa0017000001f700bbbcccabcde0000000bbbccc000000000001"
-       packedEndcX2setupRequest := PackedEndcX2setupRequest
-
-       tmp := fmt.Sprintf("%x", packedEndcX2setupRequest)
-       if len(tmp) != len(packedPdu) {
-               t.Errorf("want packed len:%d, got: %d\n", len(packedPdu)/2, len(packedEndcX2setupRequest)/2)
-       }
-
-       if strings.Compare(tmp, packedPdu) != 0 {
-               t.Errorf("\nwant :\t[%s]\n got: \t\t[%s]\n", packedPdu, tmp)
-       }
-}
-
-func TestPreparePackedX2SetupRequest(t *testing.T) {
-       _,err := logger.InitLogger(logger.InfoLevel)
-       if err!=nil{
-               t.Errorf("failed to initialize logger, error: %s", err)
-       }
-       packedPdu := "0006002a0000020015000800bbbccc00abcde000140017000001f700bbbcccabcde0000000bbbccc000000000001"
-       packedX2setupRequest := PackedX2setupRequest
-
-       tmp := fmt.Sprintf("%x", packedX2setupRequest)
-       if len(tmp) != len(packedPdu) {
-               t.Errorf("want packed len:%d, got: %d\n", len(packedPdu)/2, len(packedX2setupRequest)/2)
-       }
-
-       if strings.Compare(tmp, packedPdu) != 0 {
-               t.Errorf("\nwant :\t[%s]\n got: \t\t[%s]\n", packedPdu, tmp)
-       }
-}
-
-func TestPreparePackedX2SetupRequestFailure(t *testing.T) {
-       _, err := logger.InitLogger(logger.InfoLevel)
-       if err != nil {
-               t.Errorf("failed to initialize logger, error: %s", err)
-       }
-
-       _, _, err  = preparePackedX2SetupRequest(1, 4096, pLMNId, eNBId, eNBIdBitqty, ricFlag)
-       if err == nil {
-               t.Errorf("want: error, got: success.\n")
-       }
-
-       expected:= "packing error: #src/asn1codec_utils.c.pack_pdu_aux - Encoded output of E2AP-PDU, is too big"
-       if !strings.Contains(err.Error(), expected) {
-               t.Errorf("want :[%s], got: [%s]\n", expected, err)
-       }
-}
-
-func TestPreparePackedEndcSetupRequestFailure(t *testing.T) {
-       _, err := logger.InitLogger(logger.InfoLevel)
-       if err != nil {
-               t.Errorf("failed to initialize logger, error: %s", err)
-       }
-
-       _, _, err  = preparePackedEndcX2SetupRequest(1, 4096, pLMNId, eNBId, eNBIdBitqty, ricFlag)
-       if err == nil {
-               t.Errorf("want: error, got: success.\n")
-       }
-
-       expected:= "packing error: #src/asn1codec_utils.c.pack_pdu_aux - Encoded output of E2AP-PDU, is too big"
-       if !strings.Contains(err.Error(), expected) {
-               t.Errorf("want :[%s], got: [%s]\n", expected, err)
-       }
-}
 
 func TestParseRicId(t *testing.T) {
        var testCases = []struct {
 
 func TestParseRicId(t *testing.T) {
        var testCases = []struct {
index 6892b02..1fd1095 100644 (file)
@@ -1,20 +1,30 @@
 module e2mgr
 
 require (
 module e2mgr
 
 require (
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.23
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.23
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.23
-       gerrit.o-ran-sc.org/r/ric-plt/sdlgo v0.3.1
+       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.28
+       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.28
+       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.28
+       gerrit.o-ran-sc.org/r/ric-plt/sdlgo v0.5.0
        github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
        github.com/go-ozzo/ozzo-validation v3.5.0+incompatible
        github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
        github.com/go-ozzo/ozzo-validation v3.5.0+incompatible
-       github.com/golang/protobuf v1.3.1
-       github.com/gorilla/context v1.1.1 // indirect
-       github.com/gorilla/mux v1.6.2
+       github.com/golang/protobuf v1.3.2
+       github.com/gorilla/mux v1.7.0
+       github.com/magiconair/properties v1.8.1 // indirect
+       github.com/pelletier/go-toml v1.5.0 // indirect
        github.com/pkg/errors v0.8.1
        github.com/pkg/errors v0.8.1
+       github.com/spf13/afero v1.2.2 // indirect
+       github.com/spf13/jwalterweatherman v1.1.0 // indirect
+       github.com/spf13/pflag v1.0.5 // indirect
        github.com/spf13/viper v1.4.0
        github.com/spf13/viper v1.4.0
-       github.com/stretchr/testify v1.3.0
-       go.uber.org/zap v1.10.0
-       gopkg.in/yaml.v2 v2.2.2
+       github.com/stretchr/objx v0.2.0 // indirect
+       github.com/stretchr/testify v1.4.0
+       go.uber.org/multierr v1.2.0 // indirect
+       go.uber.org/zap v1.11.0
+       golang.org/x/net v0.0.0-20191021144547-ec77196f6094 // indirect
+       golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 // indirect
+       golang.org/x/text v0.3.2 // indirect
+       gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
+       gopkg.in/yaml.v2 v2.2.4
 )
 
 )
 
-replace gerrit.o-ran-sc.org/r/ric-plt/sdlgo => gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.3.1
+replace gerrit.o-ran-sc.org/r/ric-plt/sdlgo => gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.0
index 6576a0b..9c518c1 100644 (file)
@@ -1,12 +1,18 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.23 h1:JbSOhvj9fVEUF2XZg8cw5QAyeKUi5xXgpwXrrxfDgLM=
-gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.23/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes=
-gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.23 h1:akVZc8NWJ9oPujd7cQY3Ti3se4PF1/NoC+Dwt+YzINc=
-gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.23/go.mod h1:GXiXLz4ORBeIr0FLIbzENRykgh3Po5uPkX2jICxnRF0=
-gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.23 h1:TYV3HE2UNwGOWiA4C226/WhB94crwjuHKIFTgDDvo8I=
-gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.23/go.mod h1:uZVjwZjfWV4JJzyQVO/O48Ykph57zfpfMB7nK+WGKX8=
-gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.3.1 h1:ZIhABs0WLMn8lp1Y3719315/3jbV+yLcovOGScL03eM=
-gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.3.1/go.mod h1:y2WhrCvdLkAKdH+ySdHSOSehACJkTMyZghCGVcqoZzc=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.27 h1:frasTDcg8Q8FgYutzJ+xSLHz9YseR2BmPSSBs4GI/1M=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.27/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.28 h1:Rewapfbc30ZkBaYB/3gW3W1BEivoiPdQm5UnmUswcMA=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.28/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.27 h1:nvZDzuB/SYKDuF1It7M4/Y/iVlVrCZ0Ob8AITAyppKo=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.27/go.mod h1:Fh23KkroYw5CRBh39WzZzxpKSkpQWL3scdzGnMngLo8=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.28 h1:+8Nn+Jn/AvhwBI1LtLsNS1PtOGAOYUHdicOrMn/8mmU=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.28/go.mod h1:Fh23KkroYw5CRBh39WzZzxpKSkpQWL3scdzGnMngLo8=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.27 h1:sWjlU/wBiWIBeSixnr9etCqtNmS2LW8jv+x2JGpf2eI=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.27/go.mod h1:vZ/335+rRSQW82wcbc80fNNICSK3TiCqIxmkqeC2Pfo=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.28 h1:AaYvK59fxDXQUV9NCo6WuxDOvBQbnRU3WTPyJaYhkkg=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.28/go.mod h1:vZ/335+rRSQW82wcbc80fNNICSK3TiCqIxmkqeC2Pfo=
+gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.0 h1:+P3XuWKSaMbzh5PNtrW9gkZlCN0hKrZq+Cn8JetwBys=
+gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.0/go.mod h1:y2WhrCvdLkAKdH+ySdHSOSehACJkTMyZghCGVcqoZzc=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@@ -48,12 +54,12 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
-github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
-github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
-github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
+github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
@@ -76,6 +82,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
+github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
@@ -88,6 +96,8 @@ github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
 github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pelletier/go-toml v1.5.0 h1:5BakdOZdtKJ1FFk6QdL8iSGrMWsXgchNJcrnarjbmJQ=
+github.com/pelletier/go-toml v1.5.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -108,20 +118,30 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
+github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
 github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
 github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
 github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
@@ -131,8 +151,12 @@ go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.2.0 h1:6I+W7f5VwC5SV9dNrZ3qXrDB9mD0dyGOi/ZJmYw03T4=
+go.uber.org/multierr v1.2.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.11.0 h1:gSmpCfs+R47a4yQPAI4xJ0IPDLTRGXskm6UelqNXpqE=
+go.uber.org/zap v1.11.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -144,6 +168,8 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20191021144547-ec77196f6094 h1:5O4U9trLjNpuhpynaDsqwCk+Tw6seqJz1EbqbnzHrc8=
+golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -156,10 +182,15 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU=
+golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@@ -170,6 +201,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
@@ -179,4 +212,6 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
index 5093589..956a366 100644 (file)
@@ -25,7 +25,6 @@ import (
        "e2mgr/e2managererrors"
        "e2mgr/logger"
        "e2mgr/mocks"
        "e2mgr/e2managererrors"
        "e2mgr/logger"
        "e2mgr/mocks"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
@@ -33,7 +32,6 @@ import (
        "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"
        "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"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
        "reflect"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
        "reflect"
@@ -45,14 +43,10 @@ func setupTest(t *testing.T) (*logger.Logger, *configuration.Configuration, *moc
        config := configuration.ParseConfiguration()
 
        readerMock := &mocks.RnibReaderMock{}
        config := configuration.ParseConfiguration()
 
        readerMock := &mocks.RnibReaderMock{}
-       readerProvider := func() reader.RNibReader {
-               return readerMock
-       }
+
        writerMock := &mocks.RnibWriterMock{}
        writerMock := &mocks.RnibWriterMock{}
-       writerProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
-       rnibDataService := services.NewRnibDataService(log, config, readerProvider, writerProvider)
+
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        return log, config, readerMock, writerMock, rnibDataService, rmrMessengerMock
 }
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        return log, config, readerMock, writerMock, rnibDataService, rmrMessengerMock
 }
@@ -144,7 +138,7 @@ func TestHandleSuccessFlow(t *testing.T) {
        writerMock.On("SaveNodeb", mock.Anything, updatedNb3AfterTimer).Return(nil)
 
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
        writerMock.On("SaveNodeb", mock.Anything, updatedNb3AfterTimer).Return(nil)
 
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
-       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf))).Return(mbuf, nil)
+       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf)), true).Return(mbuf, nil)
 
        _, actual := handler.Handle(nil)
 
 
        _, actual := handler.Handle(nil)
 
@@ -176,7 +170,7 @@ func TestHandleSuccessGetNextStatusFlow(t *testing.T) {
        writerMock.On("SaveNodeb", mock.Anything, updatedNb1AfterTimer).Return(nil)
 
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
        writerMock.On("SaveNodeb", mock.Anything, updatedNb1AfterTimer).Return(nil)
 
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
-       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf))).Return(mbuf, nil)
+       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf)), true).Return(mbuf, nil)
 
        _, actual := handler.Handle(nil)
 
 
        _, actual := handler.Handle(nil)
 
@@ -205,7 +199,7 @@ func TestHandleShuttingDownStatusFlow(t *testing.T) {
        writerMock.On("SaveNodeb", mock.Anything, updatedNb1AfterTimer).Return(nil)
 
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
        writerMock.On("SaveNodeb", mock.Anything, updatedNb1AfterTimer).Return(nil)
 
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
-       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf))).Return(mbuf, nil)
+       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf)), true).Return(mbuf, nil)
 
        _, actual := handler.Handle(nil)
 
 
        _, actual := handler.Handle(nil)
 
@@ -251,7 +245,7 @@ func TestHandleGetNodebFailedFlow(t *testing.T) {
        writerMock.On("SaveNodeb", mock.Anything, updatedNb3AfterTimer).Return(nil)
 
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
        writerMock.On("SaveNodeb", mock.Anything, updatedNb3AfterTimer).Return(nil)
 
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
-       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf))).Return(mbuf, nil)
+       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf)), true).Return(mbuf, nil)
 
        _, actual := handler.Handle(nil)
 
 
        _, actual := handler.Handle(nil)
 
@@ -297,7 +291,7 @@ func TestHandleSaveFailedFlow(t *testing.T) {
        writerMock.On("SaveNodeb", mock.Anything, updatedNb3AfterTimer).Return(errRnib)
 
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
        writerMock.On("SaveNodeb", mock.Anything, updatedNb3AfterTimer).Return(errRnib)
 
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
-       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf))).Return(mbuf, nil)
+       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf)), true).Return(mbuf, nil)
 
        _, actual := handler.Handle(nil)
 
 
        _, actual := handler.Handle(nil)
 
@@ -343,7 +337,7 @@ func TestHandleSendRmrFailedFlow(t *testing.T) {
 
        expected := e2managererrors.NewRmrError()
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
 
        expected := e2managererrors.NewRmrError()
        mbuf := rmrCgo.NewMBuf(tests.MessageType, tests.MaxMsgSize, "RanName", &tests.DummyPayload, &tests.DummyXAction)
-       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf))).Return(mbuf, expected)
+       rmrMessengerMock.On("SendMsg", mock.AnythingOfType(fmt.Sprintf("%T", mbuf)), true).Return(mbuf, expected)
 
        _, actual := handler.Handle(nil)
 
 
        _, actual := handler.Handle(nil)
 
@@ -391,5 +385,5 @@ func initLog(t *testing.T) *logger.Logger {
 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
-       return rmrsender.NewRmrSender(log, &rmrMessenger)
+       return rmrsender.NewRmrSender(log, rmrMessenger)
 }
 }
diff --git a/E2Manager/handlers/httpmsghandlers/get_e2t_instances_request_handler.go b/E2Manager/handlers/httpmsghandlers/get_e2t_instances_request_handler.go
new file mode 100644 (file)
index 0000000..fd20bdf
--- /dev/null
@@ -0,0 +1,54 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package httpmsghandlers
+
+import (
+       "e2mgr/logger"
+       "e2mgr/managers"
+       "e2mgr/models"
+)
+
+type GetE2TInstancesRequestHandler struct {
+       e2tInstancesManager managers.IE2TInstancesManager
+       logger              *logger.Logger
+}
+
+func NewGetE2TInstancesRequestHandler(logger *logger.Logger, e2tInstancesManager managers.IE2TInstancesManager) *GetE2TInstancesRequestHandler {
+       return &GetE2TInstancesRequestHandler{
+               logger:              logger,
+               e2tInstancesManager: e2tInstancesManager,
+       }
+}
+
+func (h *GetE2TInstancesRequestHandler) Handle(request models.Request) (models.IResponse, error) {
+
+       e2tInstances, err := h.e2tInstancesManager.GetE2TInstances()
+
+       if err != nil {
+               h.logger.Errorf("#GetE2TInstancesRequestHandler.Handle - Error fetching E2T instances from rNib: %s", err)
+               return nil, err
+       }
+
+       mapped := make([]*models.E2TInstanceResponseModel, len(e2tInstances))
+
+       for i, v := range e2tInstances {
+               mapped[i] = models.NewE2TInstanceResponseModel(v.Address, v.AssociatedRanList)
+       }
+
+       return models.E2TInstancesResponse(mapped), nil
+}
diff --git a/E2Manager/handlers/httpmsghandlers/get_e2t_instances_request_handler_test.go b/E2Manager/handlers/httpmsghandlers/get_e2t_instances_request_handler_test.go
new file mode 100644 (file)
index 0000000..b4ee6b4
--- /dev/null
@@ -0,0 +1,75 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package httpmsghandlers
+
+import (
+       "e2mgr/configuration"
+       "e2mgr/managers"
+       "e2mgr/mocks"
+       "e2mgr/models"
+       "e2mgr/services"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/pkg/errors"
+       "github.com/stretchr/testify/assert"
+
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
+       "testing"
+)
+
+const E2TAddress2 = "10.0.2.15:3213"
+
+func setupGetE2TInstancesListRequestHandlerTest(t *testing.T) (*GetE2TInstancesRequestHandler, *mocks.RnibReaderMock) {
+       log := initLog(t)
+       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
+       readerMock := &mocks.RnibReaderMock{}
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, nil)
+       e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, log)
+       handler := NewGetE2TInstancesRequestHandler(log, e2tInstancesManager)
+       return handler, readerMock
+}
+
+func TestGetE2TInstancesFailure(t *testing.T) {
+       handler, rnibReaderMock := setupGetE2TInstancesListRequestHandlerTest(t)
+       rnibReaderMock.On("GetE2TAddresses").Return([]string{}, common.NewInternalError(errors.New("error")))
+       _, err := handler.Handle(nil)
+       assert.NotNil(t, err)
+}
+
+func TestGetE2TInstancesNoInstances(t *testing.T) {
+       handler, rnibReaderMock := setupGetE2TInstancesListRequestHandlerTest(t)
+       rnibReaderMock.On("GetE2TAddresses").Return([]string{}, nil)
+       resp, err := handler.Handle(nil)
+       assert.Nil(t, err)
+       assert.IsType(t, models.E2TInstancesResponse{}, resp)
+       assert.Len(t, resp, 0)
+}
+
+func TestGetE2TInstancesSuccess(t *testing.T) {
+       handler, rnibReaderMock := setupGetE2TInstancesListRequestHandlerTest(t)
+
+       e2tAddresses := []string{E2TAddress, E2TAddress2}
+       rnibReaderMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
+       e2tInstance := entities.E2TInstance{Address: E2TAddress, AssociatedRanList: []string{"test1", "test2"}}
+       e2tInstance2 := entities.E2TInstance{Address: E2TAddress2, AssociatedRanList: []string{"test3", "test4", "test5"}}
+
+       rnibReaderMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{&e2tInstance, &e2tInstance2}, nil)
+       resp, err := handler.Handle(nil)
+       assert.Nil(t, err)
+       assert.IsType(t, models.E2TInstancesResponse{}, resp)
+       assert.Len(t, resp, 2)
+}
index a835377..eb5bae3 100644 (file)
@@ -27,7 +27,6 @@ import (
        "e2mgr/services"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "e2mgr/services"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/pkg/errors"
        "github.com/stretchr/testify/assert"
        "testing"
        "github.com/pkg/errors"
        "github.com/stretchr/testify/assert"
        "testing"
@@ -37,10 +36,8 @@ func setupGetNodebIdListRequestHandlerTest(t *testing.T) (*GetNodebIdListRequest
        log := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
        log := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
-       readerProvider := func() reader.RNibReader {
-               return readerMock
-       }
-       rnibDataService := services.NewRnibDataService(log, config, readerProvider, nil)
+
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, nil)
        handler := NewGetNodebIdListRequestHandler(log, rnibDataService)
        return handler, readerMock
 }
        handler := NewGetNodebIdListRequestHandler(log, rnibDataService)
        return handler, readerMock
 }
index 12e3226..0177561 100644 (file)
@@ -27,7 +27,6 @@ import (
        "e2mgr/services"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "e2mgr/services"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/pkg/errors"
        "github.com/stretchr/testify/assert"
        "testing"
        "github.com/pkg/errors"
        "github.com/stretchr/testify/assert"
        "testing"
@@ -37,10 +36,7 @@ func setupGetNodebRequestHandlerTest(t *testing.T) (*GetNodebRequestHandler, *mo
        log := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
        log := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
-       readerProvider := func() reader.RNibReader {
-               return readerMock
-       }
-       rnibDataService := services.NewRnibDataService(log, config, readerProvider, nil)
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, nil)
        handler := NewGetNodebRequestHandler(log, rnibDataService)
        return handler, readerMock
 }
        handler := NewGetNodebRequestHandler(log, rnibDataService)
        return handler, readerMock
 }
index 9233411..92ec944 100644 (file)
@@ -24,7 +24,6 @@ import (
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/models"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/models"
-       "e2mgr/rnibBuilders"
        "e2mgr/services"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "e2mgr/services"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
@@ -38,77 +37,173 @@ const (
 )
 
 type SetupRequestHandler struct {
 )
 
 type SetupRequestHandler struct {
-       rNibDataService services.RNibDataService
-       logger          *logger.Logger
-       ranSetupManager *managers.RanSetupManager
-       protocol        entities.E2ApplicationProtocol
+       rNibDataService     services.RNibDataService
+       logger              *logger.Logger
+       ranSetupManager     managers.IRanSetupManager
+       protocol            entities.E2ApplicationProtocol
+       e2tInstancesManager managers.IE2TInstancesManager
 }
 
 func NewSetupRequestHandler(logger *logger.Logger, rNibDataService services.RNibDataService,
 }
 
 func NewSetupRequestHandler(logger *logger.Logger, rNibDataService services.RNibDataService,
-       ranSetupManager *managers.RanSetupManager, protocol entities.E2ApplicationProtocol) *SetupRequestHandler {
+       ranSetupManager managers.IRanSetupManager, protocol entities.E2ApplicationProtocol, e2tInstancesManager managers.IE2TInstancesManager) *SetupRequestHandler {
        return &SetupRequestHandler{
        return &SetupRequestHandler{
-               logger:          logger,
-               rNibDataService:  rNibDataService,
-               ranSetupManager: ranSetupManager,
-               protocol:        protocol,
+               logger:              logger,
+               rNibDataService:     rNibDataService,
+               ranSetupManager:     ranSetupManager,
+               protocol:            protocol,
+               e2tInstancesManager: e2tInstancesManager,
        }
 }
 
        }
 }
 
-func (handler *SetupRequestHandler) Handle(request models.Request) (models.IResponse, error) {
+func (h *SetupRequestHandler) Handle(request models.Request) (models.IResponse, error) {
 
        setupRequest := request.(models.SetupRequest)
 
 
        setupRequest := request.(models.SetupRequest)
 
-       err := handler.validateRequestDetails(setupRequest)
+       err := h.validateRequestDetails(setupRequest)
        if err != nil {
                return nil, err
        }
 
        if err != nil {
                return nil, err
        }
 
-       nodebInfo, err := handler.rNibDataService.GetNodeb(setupRequest.RanName)
+       nodebInfo, err := h.rNibDataService.GetNodeb(setupRequest.RanName)
+
        if err != nil {
                _, ok := err.(*common.ResourceNotFoundError)
                if !ok {
        if err != nil {
                _, ok := err.(*common.ResourceNotFoundError)
                if !ok {
-                       handler.logger.Errorf("#SetupRequestHandler.Handle - failed to get nodeB entity for ran name: %v from RNIB. Error: %s",
-                               setupRequest.RanName, err.Error())
+                       h.logger.Errorf("#SetupRequestHandler.Handle - failed to get nodeB entity for ran name: %v from RNIB. Error: %s", setupRequest.RanName, err)
                        return nil, e2managererrors.NewRnibDbError()
                }
 
                        return nil, e2managererrors.NewRnibDbError()
                }
 
-               result := handler.connectNewRan(&setupRequest, handler.protocol)
+               result := h.connectNewRan(&setupRequest, h.protocol)
+               return nil, result
+       }
+
+       if nodebInfo.ConnectionStatus == entities.ConnectionStatus_SHUTTING_DOWN {
+               h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithAssociatedE2TAddress - RAN: %s in wrong state (%s)", nodebInfo.RanName, entities.ConnectionStatus_name[int32(nodebInfo.ConnectionStatus)])
+               result := e2managererrors.NewWrongStateError(h.getActivityName(h.protocol), entities.ConnectionStatus_name[int32(nodebInfo.ConnectionStatus)])
+               return nil, result
+       }
+
+       if len(nodebInfo.AssociatedE2TInstanceAddress) != 0 {
+               result := h.connectExistingRanWithAssociatedE2TAddress(nodebInfo)
                return nil, result
        }
 
                return nil, result
        }
 
-       result := handler.connectExistingRan(nodebInfo)
+       result := h.connectExistingRanWithoutAssociatedE2TAddress(nodebInfo)
        return nil, result
 }
 
        return nil, result
 }
 
-func (handler *SetupRequestHandler) connectExistingRan(nodebInfo *entities.NodebInfo) error {
+func createInitialNodeInfo(requestDetails *models.SetupRequest, protocol entities.E2ApplicationProtocol, e2tAddress string) (*entities.NodebInfo, *entities.NbIdentity) {
 
 
-       if nodebInfo.ConnectionStatus == entities.ConnectionStatus_SHUTTING_DOWN {
-               handler.logger.Errorf("#SetupRequestHandler.connectExistingRan - RAN: %s in wrong state (%s)", nodebInfo.RanName, entities.ConnectionStatus_name[int32(nodebInfo.ConnectionStatus)])
-               return e2managererrors.NewWrongStateError(handler.getActivityName(handler.protocol), entities.ConnectionStatus_name[int32(nodebInfo.ConnectionStatus)])
+       nodebInfo := &entities.NodebInfo{
+               Ip:                           requestDetails.RanIp,
+               Port:                         uint32(requestDetails.RanPort),
+               ConnectionStatus:             entities.ConnectionStatus_CONNECTING,
+               E2ApplicationProtocol:        protocol,
+               RanName:                      requestDetails.RanName,
+               ConnectionAttempts:           0,
+               AssociatedE2TInstanceAddress: e2tAddress,
+       }
+
+       nbIdentity := &entities.NbIdentity{
+               InventoryName: requestDetails.RanName,
+       }
+
+       return nodebInfo, nbIdentity
+}
+
+func (h *SetupRequestHandler) connectExistingRanWithoutAssociatedE2TAddress(nodebInfo *entities.NodebInfo) error {
+       e2tAddress, err := h.e2tInstancesManager.SelectE2TInstance()
+
+       if err != nil {
+               h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - failed selecting E2T instance", nodebInfo.RanName)
+
+               if nodebInfo.ConnectionStatus == entities.ConnectionStatus_DISCONNECTED && nodebInfo.ConnectionAttempts == 0 {
+                       return err
+               }
+
+               nodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+               nodebInfo.ConnectionAttempts = 0
+               updateError := h.rNibDataService.UpdateNodebInfo(nodebInfo)
+
+               if updateError != nil {
+                       h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - failed updating nodeb. error: %s", nodebInfo.RanName, updateError)
+               }
+
+               return err
+       }
+
+       err = h.e2tInstancesManager.AssociateRan(nodebInfo.RanName, e2tAddress)
+
+       if err != nil {
+               h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - failed associating ran to e2t address %s. error: %s", nodebInfo.RanName, e2tAddress, err)
+               return err
+       }
+
+       nodebInfo.AssociatedE2TInstanceAddress = e2tAddress
+       nodebInfo.ConnectionAttempts = 0
+
+       err = h.rNibDataService.UpdateNodebInfo(nodebInfo)
+
+       if err != nil {
+               h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - failed updating nodeb in rNib. error: %s", nodebInfo.RanName, err)
+               return e2managererrors.NewRnibDbError()
        }
 
        }
 
+       h.logger.Infof("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - successfully updated nodeb in rNib", nodebInfo.RanName)
+
+       result := h.ranSetupManager.ExecuteSetup(nodebInfo, entities.ConnectionStatus_CONNECTING)
+       return result
+}
+
+func (h *SetupRequestHandler) connectExistingRanWithAssociatedE2TAddress(nodebInfo *entities.NodebInfo) error {
        status := entities.ConnectionStatus_CONNECTING
        status := entities.ConnectionStatus_CONNECTING
-       if nodebInfo.ConnectionStatus == entities.ConnectionStatus_CONNECTED{
+       if nodebInfo.ConnectionStatus == entities.ConnectionStatus_CONNECTED {
                status = nodebInfo.ConnectionStatus
        }
        nodebInfo.ConnectionAttempts = 0
                status = nodebInfo.ConnectionStatus
        }
        nodebInfo.ConnectionAttempts = 0
+       err := h.rNibDataService.UpdateNodebInfo(nodebInfo)
+
+       if err != nil {
+               h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithAssociatedE2TAddress - RAN name: %s - failed resetting connection attempts of RAN. error: %s", nodebInfo.RanName, err)
+               return e2managererrors.NewRnibDbError()
+       }
 
 
-       result := handler.ranSetupManager.ExecuteSetup(nodebInfo, status)
+       h.logger.Infof("#SetupRequestHandler.connectExistingRanWithAssociatedE2TAddress - RAN name: %s - successfully reset connection attempts of RAN", nodebInfo.RanName)
+
+
+       result := h.ranSetupManager.ExecuteSetup(nodebInfo, status)
        return result
 }
 
        return result
 }
 
-func (handler *SetupRequestHandler) connectNewRan(request *models.SetupRequest, protocol entities.E2ApplicationProtocol) error {
+func (h *SetupRequestHandler) connectNewRan(request *models.SetupRequest, protocol entities.E2ApplicationProtocol) error {
+
+       e2tAddress, err := h.e2tInstancesManager.SelectE2TInstance()
+
+       if err != nil {
+               h.logger.Errorf("#SetupRequestHandler.connectNewRan - RAN name: %s - failed selecting E2T instance", request.RanName)
+               return err
+       }
+
+       err = h.e2tInstancesManager.AssociateRan(request.RanName, e2tAddress)
 
 
-       nodebInfo, nodebIdentity := rnibBuilders.CreateInitialNodeInfo(request, protocol)
+       if err != nil {
+               h.logger.Errorf("#SetupRequestHandler.connectNewRan - RAN name: %s - failed associating ran to e2t address %s. error: %s", request.RanName, e2tAddress, err)
+               return err
+       }
+
+       nodebInfo, nodebIdentity := createInitialNodeInfo(request, protocol, e2tAddress)
+
+       err = h.rNibDataService.SaveNodeb(nodebIdentity, nodebInfo)
 
 
-       rNibErr := handler.rNibDataService.SaveNodeb(nodebIdentity, nodebInfo)
-       if rNibErr != nil {
-               handler.logger.Errorf("#SetupRequestHandler.connectNewRan - failed to initial nodeb entity for ran name: %v in RNIB. Error: %s", request.RanName, rNibErr.Error())
+       if err != nil {
+               h.logger.Errorf("#SetupRequestHandler.connectNewRan - RAN name: %s - failed to save initial nodeb entity in RNIB. error: %s", request.RanName, err)
                return e2managererrors.NewRnibDbError()
        }
                return e2managererrors.NewRnibDbError()
        }
-       handler.logger.Infof("#SetupRequestHandler.connectNewRan - initial nodeb entity for ran name: %v was saved to RNIB ", request.RanName)
 
 
-       result := handler.ranSetupManager.ExecuteSetup(nodebInfo, entities.ConnectionStatus_CONNECTING)
+       h.logger.Infof("#SetupRequestHandler.connectNewRan - RAN name: %s - initial nodeb entity was saved to rNib", request.RanName)
+
+       result := h.ranSetupManager.ExecuteSetup(nodebInfo, entities.ConnectionStatus_CONNECTING)
+
        return result
 }
 
        return result
 }
 
index 23cb44f..5086c91 100644 (file)
 package httpmsghandlers
 
 import (
 package httpmsghandlers
 
 import (
-       "e2mgr/rnibBuilders"
        "e2mgr/configuration"
        "e2mgr/e2managererrors"
        "e2mgr/e2pdus"
        "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/models"
        "e2mgr/configuration"
        "e2mgr/e2managererrors"
        "e2mgr/e2pdus"
        "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/models"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/rmrCgo"
        "e2mgr/services"
+       "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"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
-       "reflect"
        "testing"
 )
 
        "testing"
 )
 
-func TestSetupHandleNewRanSave_Error(t *testing.T) {
-       readerMock, writerMock, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST)
+const E2TAddress = "10.0.2.15:8989"
+const RanName = "test"
 
 
-       ranName := "RanName"
-       rnibErr := &common.ResourceNotFoundError{}
-       sr := models.SetupRequest{"127.0.0.1", 8080, ranName,}
-
-       nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST}
-       readerMock.On("GetNodeb", ranName).Return(nb, rnibErr)
-
-       vErr := &common.ValidationError{}
-       updatedNb, _ := rnibBuilders.CreateInitialNodeInfo(&sr, entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST)
-       writerMock.On("SaveNodeb", mock.Anything, updatedNb).Return(vErr)
-
-       var nbUpdated = &entities.NodebInfo{RanName: ranName, Ip: sr.RanIp, Port: uint32(sr.RanPort), ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, ConnectionAttempts: 1}
-       writerMock.On("UpdateNodebInfo", nbUpdated).Return(nil)
-
-       payload := e2pdus.PackedEndcX2setupRequest
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
+func initSetupRequestTest(t *testing.T, protocol entities.E2ApplicationProtocol) (*mocks.RnibReaderMock, *mocks.RnibWriterMock, *SetupRequestHandler, *mocks.E2TInstancesManagerMock, *mocks.RanSetupManagerMock) {
+       log := initLog(t)
+       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
 
 
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
 
 
-       _, actual := handler.Handle(sr)
-       expected := &e2managererrors.RnibDbError{}
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
 
 
-       if reflect.TypeOf(actual) != reflect.TypeOf(expected) {
-               t.Errorf("Error actual = %v, and Expected = %v.", actual, expected)
-       }
+       ranSetupManagerMock := &mocks.RanSetupManagerMock{}
+       e2tInstancesManagerMock := &mocks.E2TInstancesManagerMock{}
+       handler := NewSetupRequestHandler(log, rnibDataService, ranSetupManagerMock, protocol, e2tInstancesManagerMock)
 
 
-       writerMock.AssertNumberOfCalls(t, "SaveNodeb", 1)
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 0)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+       return readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock
 }
 
 }
 
-func TestSetupHandleNewRan_Success(t *testing.T) {
-       readerMock, writerMock, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST)
-
-       ranName := "RanName"
-       rnibErr := &common.ResourceNotFoundError{}
-       sr := models.SetupRequest{"127.0.0.1", 8080, ranName,}
-
-       nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST}
-       readerMock.On("GetNodeb", ranName).Return(nb, rnibErr)
-
-       updatedNb, _ := rnibBuilders.CreateInitialNodeInfo(&sr, entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST)
-       writerMock.On("SaveNodeb", mock.Anything, updatedNb).Return(nil)
-
-       var nbUpdated = &entities.NodebInfo{RanName: ranName, Ip: sr.RanIp, Port: uint32(sr.RanPort), ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, ConnectionAttempts: 1}
-       writerMock.On("UpdateNodebInfo", nbUpdated).Return(nil)
-
-       payload := e2pdus.PackedEndcX2setupRequest
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
+func initSetupRequestTestBasicMocks(t *testing.T, protocol entities.E2ApplicationProtocol) (*mocks.RnibReaderMock, *mocks.RnibWriterMock, *SetupRequestHandler, *mocks.RmrMessengerMock) {
+       log := initLog(t)
+       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
 
 
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
 
 
-       _, actual := handler.Handle(sr)
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
 
 
-       assert.Nil(t, actual)
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
+       rmrSender := getRmrSender(rmrMessengerMock, log)
+       ranSetupManager := managers.NewRanSetupManager(log, rmrSender, rnibDataService)
+       e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, log)
+       handler := NewSetupRequestHandler(log, rnibDataService, ranSetupManager, protocol, e2tInstancesManager)
 
 
-       writerMock.AssertNumberOfCalls(t, "SaveNodeb", 1)
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
+       return readerMock, writerMock, handler, rmrMessengerMock
 }
 
 }
 
-func TestEndcSetupHandleRmr_Error(t *testing.T) {
-       readerMock, writerMock, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST)
-
-       ranName := "RanName"
-       nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST}
-       readerMock.On("GetNodeb", ranName).Return(nb, nil)
-
-       var nbUpdated = &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, ConnectionAttempts: 1}
-       writerMock.On("UpdateNodebInfo", nbUpdated).Return(nil)
-
-       var nbDisconnected = &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, ConnectionAttempts: 0}
-       writerMock.On("UpdateNodebInfo", nbDisconnected).Return(nil)
-
-       payload := e2pdus.PackedEndcX2setupRequest
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
-
-       rmrErr := &e2managererrors.RmrError{}
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, rmrErr)
-
-       sr := models.SetupRequest{"127.0.0.1", 8080, ranName,}
-       _, actual := handler.Handle(sr)
+func TestX2SetupHandleNoPortError(t *testing.T) {
+       readerMock, _, handler, _, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
 
 
-       if reflect.TypeOf(actual) != reflect.TypeOf(rmrErr) {
-               t.Errorf("Error actual = %v, and Expected = %v.", actual, rmrErr)
-       }
-
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
+       sr := models.SetupRequest{"127.0.0.1", 0, RanName,}
+       _, err := handler.Handle(sr)
+       assert.IsType(t, &e2managererrors.RequestValidationError{}, err)
+       readerMock.AssertNotCalled(t, "GetNodeb")
 }
 
 }
 
-func TestEndcSetupHandleExistingDisconnectedRan_Success(t *testing.T) {
-       readerMock, writerMock, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST)
-
-       ranName := "RanName"
-       nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST}
-       readerMock.On("GetNodeb", ranName).Return(nb, nil)
-
-       var nbUpdated = &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, ConnectionAttempts: 1}
-       writerMock.On("UpdateNodebInfo", nbUpdated).Return(nil)
-
-       payload := e2pdus.PackedEndcX2setupRequest
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
+func TestX2SetupHandleNoRanNameError(t *testing.T) {
+       readerMock, _, handler, _, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
 
 
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
-
-       sr := models.SetupRequest{"127.0.0.1", 8080, ranName,}
-       _, actual := handler.Handle(sr)
-
-       assert.Nil(t, actual)
-
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
+       sr := models.SetupRequest{RanPort: 8080, RanIp: "127.0.0.1"}
+       _, err := handler.Handle(sr)
+       assert.IsType(t, &e2managererrors.RequestValidationError{}, err)
+       readerMock.AssertNotCalled(t, "GetNodeb")
 }
 
 }
 
-func TestX2SetupHandleExistingConnectedRan_Success(t *testing.T) {
-       readerMock, writerMock, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
-
-       ranName := "RanName"
-       nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
-       readerMock.On("GetNodeb", ranName).Return(nb, nil)
+func TestX2SetupHandleNoIpError(t *testing.T) {
+       readerMock, _, handler, _, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
 
 
-       var nbUpdated = &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
-       writerMock.On("UpdateNodebInfo", nbUpdated).Return(nil)
-
-       payload := e2pdus.PackedX2setupRequest
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
-
-       rmrMessengerMock.On("SendMsg", mock.Anything, mock.Anything).Return(msg, nil)
-
-       sr := models.SetupRequest{"127.0.0.1", 8080, ranName,}
-       _, actual := handler.Handle(sr)
+       sr := models.SetupRequest{RanPort: 8080, RanName: RanName}
+       _, err := handler.Handle(sr)
+       assert.IsType(t, &e2managererrors.RequestValidationError{}, err)
+       readerMock.AssertNotCalled(t, "GetNodeb")
+}
 
 
-       assert.Nil(t, actual)
+func TestX2SetupHandleInvalidIpError(t *testing.T) {
+       readerMock, _, handler, _, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
 
 
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
+       sr := models.SetupRequest{RanPort: 8080, RanName: RanName, RanIp: "invalid ip"}
+       _, err := handler.Handle(sr)
+       assert.IsType(t, &e2managererrors.RequestValidationError{}, err)
+       readerMock.AssertNotCalled(t, "GetNodeb")
 }
 
 }
 
-func TestX2SetupHandleRnibGet_Error(t *testing.T) {
-       readerMock, _, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+func TestSetupGetNodebFailure(t *testing.T) {
+       readerMock, _, handler, _, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
 
        rnibErr := &common.ValidationError{}
 
        rnibErr := &common.ValidationError{}
-       nb := &entities.NodebInfo{RanName: "RanName", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
-       readerMock.On("GetNodeb", "RanName").Return(nb, rnibErr)
+       nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
+       readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
 
 
-       sr := models.SetupRequest{"127.0.0.1", 8080, "RanName",}
-       _, actual := handler.Handle(sr)
-
-       expected := &e2managererrors.RnibDbError{}
-       if reflect.TypeOf(actual) != reflect.TypeOf(expected) {
-               t.Errorf("Error actual = %v, and Expected = %v.", actual, expected)
-       }
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+       sr := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       _, err := handler.Handle(sr)
+       assert.IsType(t, &e2managererrors.RnibDbError{}, err)
 }
 
 }
 
-func TestX2SetupHandleShuttingDownRan_Error(t *testing.T) {
-       readerMock, writerMock, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
-
-       nb := &entities.NodebInfo{RanName: "RanName", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
-       readerMock.On("GetNodeb", "RanName").Return(nb, nil)
-
-       sr := models.SetupRequest{"127.0.0.1", 8080, "RanName",}
-       _, actual := handler.Handle(sr)
-
-       expected := &e2managererrors.WrongStateError{}
-       if reflect.TypeOf(actual) != reflect.TypeOf(expected) {
-               t.Errorf("Error actual = %v, and Expected = %v.", actual, expected)
-       }
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 0)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+func TestSetupNewRanSelectE2TInstancesDbError(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return("", e2managererrors.NewRnibDbError())
+       _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
+       assert.IsType(t, &e2managererrors.RnibDbError{}, err)
+       e2tInstancesManagerMock.AssertNotCalled(t, "AssociateRan")
+       writerMock.AssertNotCalled(t, "SaveNodeb")
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
 }
 
 }
 
-func TestX2SetupHandleNoPort_Error(t *testing.T) {
-       _, writerMock, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
-
-       sr := models.SetupRequest{"127.0.0.1", 0, "RanName",}
-       _, actual := handler.Handle(sr)
-
-       expected := &e2managererrors.RequestValidationError{}
-       if reflect.TypeOf(actual) != reflect.TypeOf(expected) {
-               t.Errorf("Error actual = %v, and Expected = %v.", actual, expected)
-       }
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 0)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+func TestSetupNewRanSelectE2TInstancesNoInstances(t *testing.T) {
+       readerMock, writerMock, handler, rmrMessengerMock := initSetupRequestTestBasicMocks(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
+       readerMock.On("GetE2TAddresses").Return([]string{}, nil)
+       _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
+       assert.IsType(t, &e2managererrors.E2TInstanceAbsenceError{}, err)
+       writerMock.AssertNotCalled(t, "SaveNodeb")
+       rmrMessengerMock.AssertNotCalled(t, "SendMsg")
 }
 
 }
 
-func TestX2SetupHandleNoRanName_Error(t *testing.T) {
-       _, writerMock, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+func TestSetupNewRanAssociateRanFailure(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
+       e2tInstancesManagerMock.On("AssociateRan", RanName, E2TAddress).Return(e2managererrors.NewRnibDbError())
+       _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
+       assert.IsType(t, &e2managererrors.RnibDbError{}, err)
+       writerMock.AssertNotCalled(t, "SaveNodeb")
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
+}
 
 
-       sr := models.SetupRequest{}
-       sr.RanPort = 8080
-       sr.RanIp = "127.0.0.1"
+func TestSetupNewRanSaveNodebFailure(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
+       e2tInstancesManagerMock.On("AssociateRan", RanName, E2TAddress).Return(nil)
+       setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       nodebInfo, nbIdentity := createInitialNodeInfo(&setupRequest, entities.E2ApplicationProtocol_X2_SETUP_REQUEST, E2TAddress)
+       writerMock.On("SaveNodeb", nbIdentity, nodebInfo).Return(common.NewInternalError(fmt.Errorf("")))
+       _, err := handler.Handle(setupRequest)
+       assert.IsType(t, &e2managererrors.RnibDbError{}, err)
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
+}
 
 
-       _, actual := handler.Handle(sr)
+func TestSetupNewRanSetupDbError(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
+       e2tInstancesManagerMock.On("AssociateRan", RanName, E2TAddress).Return(nil)
+       setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       nodebInfo, nbIdentity := createInitialNodeInfo(&setupRequest, entities.E2ApplicationProtocol_X2_SETUP_REQUEST, E2TAddress)
+       writerMock.On("SaveNodeb", nbIdentity, nodebInfo).Return(nil)
+       ranSetupManagerMock.On("ExecuteSetup", nodebInfo, entities.ConnectionStatus_CONNECTING).Return(e2managererrors.NewRnibDbError())
+       _, err := handler.Handle(setupRequest)
+       assert.IsType(t, &e2managererrors.RnibDbError{}, err)
+}
 
 
-       expected := &e2managererrors.RequestValidationError{}
-       if reflect.TypeOf(actual) != reflect.TypeOf(expected) {
-               t.Errorf("Error actual = %v, and Expected = %v.", actual, expected)
-       }
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 0)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+func TestSetupNewRanSetupRmrError(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
+       e2tInstancesManagerMock.On("AssociateRan", RanName, E2TAddress).Return(nil)
+       setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       nodebInfo, nbIdentity := createInitialNodeInfo(&setupRequest, entities.E2ApplicationProtocol_X2_SETUP_REQUEST, E2TAddress)
+       writerMock.On("SaveNodeb", nbIdentity, nodebInfo).Return(nil)
+       ranSetupManagerMock.On("ExecuteSetup", nodebInfo, entities.ConnectionStatus_CONNECTING).Return(e2managererrors.NewRmrError())
+       _, err := handler.Handle(setupRequest)
+       assert.IsType(t, &e2managererrors.RmrError{}, err)
 }
 
 }
 
-func TestX2SetupHandleNoIP_Error(t *testing.T) {
-       _, writerMock, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+func TestSetupNewRanSetupSuccess(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
+       e2tInstancesManagerMock.On("AssociateRan", RanName, E2TAddress).Return(nil)
+       setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       nodebInfo, nbIdentity := createInitialNodeInfo(&setupRequest, entities.E2ApplicationProtocol_X2_SETUP_REQUEST, E2TAddress)
+       writerMock.On("SaveNodeb", nbIdentity, nodebInfo).Return(nil)
+       ranSetupManagerMock.On("ExecuteSetup", nodebInfo, entities.ConnectionStatus_CONNECTING).Return(nil)
+       _, err := handler.Handle(setupRequest)
+       assert.Nil(t, err)
+}
 
 
-       sr := models.SetupRequest{}
-       sr.RanPort = 8080
-       sr.RanName = "RanName"
+func TestX2SetupExistingRanShuttingDown(t *testing.T) {
+       readerMock, _, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN}, nil)
+       setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       _, err := handler.Handle(setupRequest)
+       assert.IsType(t, &e2managererrors.WrongStateError{}, err)
+       e2tInstancesManagerMock.AssertNotCalled(t, "SelectE2TInstance")
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
+}
 
 
-       _, actual := handler.Handle(sr)
+func TestEndcSetupExistingRanShuttingDown(t *testing.T) {
+       readerMock, _, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST)
+       readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN}, nil)
+       setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       _, err := handler.Handle(setupRequest)
+       assert.IsType(t, &e2managererrors.WrongStateError{}, err)
+       e2tInstancesManagerMock.AssertNotCalled(t, "SelectE2TInstance")
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
+}
 
 
-       expected := &e2managererrors.RequestValidationError{}
-       if reflect.TypeOf(actual) != reflect.TypeOf(expected) {
-               t.Errorf("Error actual = %v, and Expected = %v.", actual, expected)
-       }
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 0)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+func TestSetupExistingRanWithoutAssocE2TInstanceSelectDbError(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return("", e2managererrors.NewRnibDbError())
+       updatedNb := *nb
+       updatedNb.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+       writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
+       setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       _, err := handler.Handle(setupRequest)
+       assert.IsType(t, &e2managererrors.RnibDbError{}, err)
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
 }
 
 }
 
-func TestX2SetupHandleInvalidIp_Error(t *testing.T) {
-       _, writerMock, handler, rmrMessengerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+func TestSetupExistingRanWithoutAssocE2TInstanceSelectNoInstanceError(t *testing.T) {
+       readerMock, writerMock, handler, rmrMessengerMock := initSetupRequestTestBasicMocks(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       readerMock.On("GetE2TAddresses").Return([]string{}, nil)
+       updatedNb := *nb
+       updatedNb.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+       writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
+       setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       _, err := handler.Handle(setupRequest)
+       assert.IsType(t, &e2managererrors.E2TInstanceAbsenceError{}, err)
+       rmrMessengerMock.AssertNotCalled(t, "SendMsg")
+       writerMock.AssertExpectations(t)
+}
 
 
-       sr := models.SetupRequest{}
-       sr.RanPort = 8080
-       sr.RanName = "RanName"
-       sr.RanIp = "invalid ip"
+func TestSetupExistingRanWithoutAssocE2TInstanceSelectNoInstanceErrorUpdateFailure(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return("", e2managererrors.NewE2TInstanceAbsenceError())
+       updatedNb := *nb
+       updatedNb.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+       writerMock.On("UpdateNodebInfo", &updatedNb).Return(common.NewInternalError(fmt.Errorf("")))
+       setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       _, err := handler.Handle(setupRequest)
+       assert.IsType(t, &e2managererrors.E2TInstanceAbsenceError{}, err)
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
+}
 
 
-       _, actual := handler.Handle(sr)
+func TestSetupExistingRanWithoutAssocE2TInstanceSelectErrorAlreadyDisconnected(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, e2managererrors.NewE2TInstanceAbsenceError())
+       setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
+       _, err := handler.Handle(setupRequest)
+       assert.IsType(t, &e2managererrors.E2TInstanceAbsenceError{}, err)
+       writerMock.AssertNotCalled(t, "UpdateNodebInfo")
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
+}
 
 
-       expected := &e2managererrors.RequestValidationError{}
-       if reflect.TypeOf(actual) != reflect.TypeOf(expected) {
-               t.Errorf("Error actual = %v, and Expected = %v.", actual, expected)
-       }
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 0)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+func TestSetupExistingRanWithoutAssocE2TInstanceAssociateRanFailure(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
+       e2tInstancesManagerMock.On("AssociateRan", RanName, E2TAddress).Return(e2managererrors.NewRnibDbError())
+       _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
+       assert.IsType(t, &e2managererrors.RnibDbError{}, err)
+       writerMock.AssertNotCalled(t, "UpdateNodebInfo")
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
 }
 
 }
 
-func initSetupRequestTest(t *testing.T, protocol entities.E2ApplicationProtocol) (*mocks.RnibReaderMock, *mocks.RnibWriterMock, *SetupRequestHandler, *mocks.RmrMessengerMock) {
-       log := initLog(t)
-       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
+func TestSetupExistingRanWithoutAssocE2TInstanceAssociateRanSucceedsUpdateNodebFails(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
+       e2tInstancesManagerMock.On("AssociateRan", RanName, E2TAddress).Return(nil)
+       updatedNb := *nb
+       updatedNb.AssociatedE2TInstanceAddress = E2TAddress
+       updatedNb.ConnectionAttempts = 0
+       writerMock.On("UpdateNodebInfo", &updatedNb).Return(common.NewInternalError(fmt.Errorf("")))
+       _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
+       assert.IsType(t, &e2managererrors.RnibDbError{}, err)
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
+}
 
 
-       readerMock := &mocks.RnibReaderMock{}
-       readerProvider := func() reader.RNibReader {
-               return readerMock
-       }
-       writerMock := &mocks.RnibWriterMock{}
-       writerProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
+func TestSetupExistingRanWithoutAssocE2TInstanceExecuteSetupFailure(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
+       e2tInstancesManagerMock.On("AssociateRan", RanName, E2TAddress).Return(nil)
+       updatedNb := *nb
+       updatedNb.AssociatedE2TInstanceAddress = E2TAddress
+       updatedNb.ConnectionAttempts = 0
+       writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
+       ranSetupManagerMock.On("ExecuteSetup", &updatedNb, entities.ConnectionStatus_CONNECTING).Return(e2managererrors.NewRnibDbError())
+       _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
+       assert.IsType(t, &e2managererrors.RnibDbError{}, err)
+}
 
 
-       rmrMessengerMock := &mocks.RmrMessengerMock{}
-       rmrSender := getRmrSender(rmrMessengerMock, log)
+func TestSetupExistingRanWithoutAssocE2TInstanceSuccess(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
+       e2tInstancesManagerMock.On("AssociateRan", RanName, E2TAddress).Return(nil)
+       updatedNb := *nb
+       updatedNb.AssociatedE2TInstanceAddress = E2TAddress
+       updatedNb.ConnectionAttempts = 0
+       writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
+       ranSetupManagerMock.On("ExecuteSetup", &updatedNb, entities.ConnectionStatus_CONNECTING).Return(nil)
+       _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
+       assert.Nil(t, err)
+}
 
 
-       rnibDataService := services.NewRnibDataService(log, config, readerProvider, writerProvider)
+func TestSetupExistingRanWithAssocE2TInstanceUpdateNodebFailure(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       updatedNb := *nb
+       updatedNb.ConnectionAttempts = 0
+       writerMock.On("UpdateNodebInfo", &updatedNb).Return(common.NewInternalError(fmt.Errorf("")))
+       _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
+       assert.IsType(t, &e2managererrors.RnibDbError{}, err)
+       e2tInstancesManagerMock.AssertNotCalled(t, "SelectE2TInstance")
+       e2tInstancesManagerMock.AssertNotCalled(t, "AssociateRan")
+       ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
+}
 
 
-       ranSetupManager := managers.NewRanSetupManager(log, rmrSender, rnibDataService)
-       handler := NewSetupRequestHandler(log, rnibDataService, ranSetupManager, protocol)
+func TestSetupExistingRanWithAssocE2TInstanceExecuteSetupRmrError(t *testing.T) {
+       readerMock, writerMock, handler, rmrMessengerMock := initSetupRequestTestBasicMocks(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       updatedNb := *nb
+       updatedNb.ConnectionAttempts = 0
+       updatedNb2 := updatedNb
+       updatedNb2.ConnectionAttempts++
+       updatedNb3 := updatedNb2
+       updatedNb3.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+       updatedNb3.ConnectionAttempts--
+       writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
+       writerMock.On("UpdateNodebInfo", &updatedNb2).Return(nil)
+       payload := e2pdus.PackedX2setupRequest
+       xaction := []byte(RanName)
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), RanName, &payload, &xaction)
+       rmrMessengerMock.On("SendMsg",mock.Anything, true).Return(msg, e2managererrors.NewRmrError())
+       writerMock.On("UpdateNodebInfo", &updatedNb3).Return(nil)
+       _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
+       assert.IsType(t, &e2managererrors.RmrError{}, err)
+       writerMock.AssertExpectations(t)
+}
 
 
-       return readerMock, writerMock, handler, rmrMessengerMock
+func TestSetupExistingRanWithAssocE2TInstanceConnectedSuccess(t *testing.T) {
+       readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
+       nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED}
+       readerMock.On("GetNodeb", RanName).Return(nb, nil)
+       updatedNb := *nb
+       updatedNb.ConnectionAttempts = 0
+       writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
+       ranSetupManagerMock.On("ExecuteSetup", &updatedNb, entities.ConnectionStatus_CONNECTED).Return(nil)
+       _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
+       assert.Nil(t, err)
+       e2tInstancesManagerMock.AssertNotCalled(t, "SelectE2TInstance")
+       e2tInstancesManagerMock.AssertNotCalled(t, "AssociateRan")
 }
 }
index 0738eae..13a88ad 100644 (file)
@@ -81,7 +81,9 @@ func (handler *X2ResetRequestHandler) Handle(request models.Request) (models.IRe
                return nil, e2managererrors.NewWrongStateError(X2_RESET_ACTIVITY_NAME, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)])
        }
 
                return nil, e2managererrors.NewWrongStateError(X2_RESET_ACTIVITY_NAME, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)])
        }
 
-       msg := models.NewRmrMessage(rmrCgo.RIC_X2_RESET, resetRequest.RanName, payload)
+       var xAction []byte
+
+       msg := models.NewRmrMessage(rmrCgo.RIC_X2_RESET, resetRequest.RanName, payload, xAction)
 
        err = handler.rmrSender.Send(msg)
 
 
        err = handler.rmrSender.Send(msg)
 
index 870385b..16def4c 100644 (file)
@@ -5,13 +5,11 @@ import (
        "e2mgr/e2managererrors"
        "e2mgr/mocks"
        "e2mgr/models"
        "e2mgr/e2managererrors"
        "e2mgr/mocks"
        "e2mgr/models"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "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"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "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"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/assert"
        "testing"
 )
        "github.com/stretchr/testify/assert"
        "testing"
 )
@@ -20,14 +18,8 @@ func setupX2ResetRequestHandlerTest(t *testing.T) (*X2ResetRequestHandler, *mock
        log := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
        log := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
-       readerProvider := func() reader.RNibReader {
-               return readerMock
-       }
        writerMock := &mocks.RnibWriterMock{}
        writerMock := &mocks.RnibWriterMock{}
-       writerProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
-       rnibDataService := services.NewRnibDataService(log, config, readerProvider, writerProvider)
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        rmrSender := getRmrSender(rmrMessengerMock, log)
        handler := NewX2ResetRequestHandler(log, rmrSender, rnibDataService)
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        rmrSender := getRmrSender(rmrMessengerMock, log)
        handler := NewX2ResetRequestHandler(log, rmrSender, rnibDataService)
@@ -40,10 +32,10 @@ func TestHandleSuccessfulDefaultCause(t *testing.T) {
        ranName := "test1"
        // o&m intervention
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
        ranName := "test1"
        // o&m intervention
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xaction)
+       var xAction[]byte
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction)
 
 
-       rmrMessengerMock.On("SendMsg", msg).Return(msg, nil)
+       rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
 
        var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
        readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
 
        var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
        readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
@@ -58,9 +50,9 @@ func TestHandleSuccessfulRequestedCause(t *testing.T) {
 
        ranName := "test1"
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
 
        ranName := "test1"
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", msg).Return(msg, nil)
+       var xAction[]byte
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction)
+       rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
 
        var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
        readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
 
        var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
        readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
@@ -125,9 +117,9 @@ func TestHandleFailureRmrError(t *testing.T) {
        ranName := "test1"
        // o&m intervention
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
        ranName := "test1"
        // o&m intervention
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
-       xaction := []byte(ranName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", msg).Return(&rmrCgo.MBuf{}, fmt.Errorf("rmr error"))
+       var xAction[]byte
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction)
+       rmrMessengerMock.On("SendMsg", msg, true).Return(&rmrCgo.MBuf{}, fmt.Errorf("rmr error"))
 
        var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
        readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
 
        var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
        readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
index 6bc047c..283de35 100644 (file)
 package rmrmsghandlers
 
 import (
 package rmrmsghandlers
 
 import (
+       "e2mgr/clients"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/models"
        "e2mgr/services"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/models"
        "e2mgr/services"
+       "encoding/json"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "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 E2TermInitNotificationHandler struct {
        logger                 *logger.Logger
        rnibDataService        services.RNibDataService
        ranReconnectionManager *managers.RanReconnectionManager
 )
 
 type E2TermInitNotificationHandler struct {
        logger                 *logger.Logger
        rnibDataService        services.RNibDataService
        ranReconnectionManager *managers.RanReconnectionManager
+       e2tInstancesManager    managers.IE2TInstancesManager
+       routingManagerClient   clients.IRoutingManagerClient
 }
 
 }
 
-func NewE2TermInitNotificationHandler(logger *logger.Logger, ranReconnectionManager *managers.RanReconnectionManager, rnibDataService services.RNibDataService) E2TermInitNotificationHandler {
+func NewE2TermInitNotificationHandler(logger *logger.Logger, ranReconnectionManager *managers.RanReconnectionManager, rnibDataService services.RNibDataService, e2tInstancesManager managers.IE2TInstancesManager, routingManagerClient clients.IRoutingManagerClient) E2TermInitNotificationHandler {
        return E2TermInitNotificationHandler{
                logger:                 logger,
                rnibDataService:        rnibDataService,
                ranReconnectionManager: ranReconnectionManager,
        return E2TermInitNotificationHandler{
                logger:                 logger,
                rnibDataService:        rnibDataService,
                ranReconnectionManager: ranReconnectionManager,
+               e2tInstancesManager:    e2tInstancesManager,
+               routingManagerClient:   routingManagerClient,
        }
 }
 
 func (h E2TermInitNotificationHandler) Handle(request *models.NotificationRequest) {
        }
 }
 
 func (h E2TermInitNotificationHandler) Handle(request *models.NotificationRequest) {
+       unmarshalledPayload := models.E2TermInitPayload{}
+       err := json.Unmarshal(request.Payload, &unmarshalledPayload)
 
 
-       h.logger.Infof("#E2TermInitNotificationHandler.Handle - Handling E2_TERM_INIT")
+       if err != nil {
+               h.logger.Errorf("#E2TermInitNotificationHandler.Handle - Error unmarshaling E2 Term Init payload: %s", err)
+               return
+       }
+
+       e2tAddress := unmarshalledPayload.Address
+
+       if len(e2tAddress) == 0 {
+               h.logger.Errorf("#E2TermInitNotificationHandler.Handle - Empty E2T address received")
+               return
+       }
+
+       h.logger.Infof("#E2TermInitNotificationHandler.Handle - E2T address: %s - handling E2_TERM_INIT", e2tAddress)
+
+       e2tInstance, err := h.e2tInstancesManager.GetE2TInstance(e2tAddress)
 
 
-       nbIdentityList, err := h.rnibDataService.GetListNodebIds()
        if err != nil {
        if err != nil {
-               h.logger.Errorf("#E2TermInitNotificationHandler.Handle - Failed to get nodes list from RNIB. Error: %s", err.Error())
+               _, ok := err.(*common.ResourceNotFoundError)
+
+               if !ok {
+                       h.logger.Errorf("#E2TermInitNotificationHandler.Handle - Failed retrieving E2TInstance. error: %s", err)
+                       return
+               }
+
+               h.HandleNewE2TInstance(e2tAddress)
                return
        }
 
                return
        }
 
-       if len(nbIdentityList) == 0 {
-               h.logger.Warnf("#E2TermInitNotificationHandler.Handle - The Nodes list in RNIB is empty")
+       if len(e2tInstance.AssociatedRanList) == 0 {
+               h.logger.Infof("#E2TermInitNotificationHandler.Handle - E2T Address: %s - E2T instance has no associated RANs", e2tInstance.Address)
                return
        }
 
                return
        }
 
-       for _, nbIdentity := range nbIdentityList {
+       if e2tInstance.State == entities.ToBeDeleted{
+               h.logger.Infof("#E2TermInitNotificationHandler.Handle - E2T Address: %s - E2T instance status is: %s, ignore", e2tInstance.Address, e2tInstance.State)
+               return
+       }
 
 
-               if err := h.ranReconnectionManager.ReconnectRan(nbIdentity.InventoryName); err != nil {
-                       h.logger.Errorf("#E2TermInitNotificationHandler.Handle - Ran name: %s - connection attempt failure, error: %s", (*nbIdentity).GetInventoryName(), err.Error())
+       if e2tInstance.State == entities.RoutingManagerFailure {
+               err := h.e2tInstancesManager.ActivateE2TInstance(e2tInstance)
+               if err != nil {
+                       return
+               }
+       }
+
+       h.HandleExistingE2TInstance(e2tInstance)
+
+       h.logger.Infof("#E2TermInitNotificationHandler.Handle - Completed handling of E2_TERM_INIT")
+}
+
+func (h E2TermInitNotificationHandler) HandleExistingE2TInstance(e2tInstance *entities.E2TInstance) {
+
+       for _, ranName := range e2tInstance.AssociatedRanList {
+
+               if err := h.ranReconnectionManager.ReconnectRan(ranName); err != nil {
+                       h.logger.Errorf("#E2TermInitNotificationHandler.HandleExistingE2TInstance - Ran name: %s - connection attempt failure, error: %s", ranName, err)
                        _, ok := err.(*common.ResourceNotFoundError)
                        if !ok {
                                break
                        }
                }
        }
                        _, ok := err.(*common.ResourceNotFoundError)
                        if !ok {
                                break
                        }
                }
        }
-
-       h.logger.Infof("#E2TermInitNotificationHandler.Handle - Completed handling of E2_TERM_INIT")
 }
 }
+
+func (h E2TermInitNotificationHandler) HandleNewE2TInstance(e2tAddress string) {
+
+       err := h.routingManagerClient.AddE2TInstance(e2tAddress)
+
+       if err != nil{
+               h.logger.Errorf("#E2TermInitNotificationHandler.HandleNewE2TInstance - e2t address: %s - routing manager failure", e2tAddress)
+               return
+       }
+
+       _ = h.e2tInstancesManager.AddE2TInstance(e2tAddress)
+}
\ No newline at end of file
index ae88cb2..f6779df 100644 (file)
@@ -1,3 +1,19 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
 package rmrmsghandlers
 
 import (
 package rmrmsghandlers
 
 import (
@@ -7,7 +23,6 @@ import (
        "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/models"
        "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/models"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
@@ -15,12 +30,14 @@ import (
        "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"
        "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"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/mock"
        "testing"
 )
 
        "github.com/stretchr/testify/mock"
        "testing"
 )
 
-func initRanLostConnectionTest(t *testing.T) (*logger.Logger, E2TermInitNotificationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock) {
+const e2tInstanceAddress = "10.0.2.15"
+const e2tInitPayload = "{\"address\":\"10.0.2.15\", \"fqdn\":\"\"}"
+
+func initRanLostConnectionTest(t *testing.T) (*logger.Logger, E2TermInitNotificationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock, *mocks.RoutingManagerClientMock) {
 
        logger := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
 
        logger := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
@@ -29,78 +46,325 @@ func initRanLostConnectionTest(t *testing.T) (*logger.Logger, E2TermInitNotifica
        rmrSender := initRmrSender(rmrMessengerMock, logger)
 
        readerMock := &mocks.RnibReaderMock{}
        rmrSender := initRmrSender(rmrMessengerMock, logger)
 
        readerMock := &mocks.RnibReaderMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
+
        writerMock := &mocks.RnibWriterMock{}
        writerMock := &mocks.RnibWriterMock{}
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
-       rnibDataService := services.NewRnibDataService(logger, config, rnibReaderProvider, rnibWriterProvider)
+
+       routingManagerClientMock := &mocks.RoutingManagerClientMock{}
+
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+       ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
+
+       e2tInstancesManagerMock := &mocks.E2TInstancesManagerMock{}
+
+       ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, ranSetupManager, e2tInstancesManagerMock)
+       handler := NewE2TermInitNotificationHandler(logger, ranReconnectionManager, rnibDataService, e2tInstancesManagerMock, routingManagerClientMock)
+
+       return logger, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock
+}
+
+func initRanLostConnectionTestWithRealE2tInstanceManager(t *testing.T) (*logger.Logger, E2TermInitNotificationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock) {
+
+       logger := initLog(t)
+       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
+
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
+       rmrSender := initRmrSender(rmrMessengerMock, logger)
+
+       readerMock := &mocks.RnibReaderMock{}
+
+       writerMock := &mocks.RnibWriterMock{}
+       routingManagerClientMock := &mocks.RoutingManagerClientMock{}
+
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
-       ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, ranSetupManager)
-       handler := NewE2TermInitNotificationHandler(logger, ranReconnectionManager, rnibDataService)
+
+       e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, logger)
+       ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, ranSetupManager, e2tInstancesManager)
+       handler := NewE2TermInitNotificationHandler(logger, ranReconnectionManager, rnibDataService, e2tInstancesManager, routingManagerClientMock)
        return logger, handler, readerMock, writerMock, rmrMessengerMock
 }
 
        return logger, handler, readerMock, writerMock, rmrMessengerMock
 }
 
-func TestE2TerminInitHandlerSuccessOneRan(t *testing.T) {
-       _, handler, readerMock, writerMock, rmrMessengerMock := initRanLostConnectionTest(t)
-       var rnibErr error
+func TestE2TermInitUnmarshalPayloadFailure(t *testing.T) {
+       _, handler, _, _, _, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte("asd")}
+       handler.Handle(notificationRequest)
+       e2tInstancesManagerMock.AssertNotCalled(t, "GetE2TInstance")
+       e2tInstancesManagerMock.AssertNotCalled(t, "AddE2TInstance")
+}
 
 
-       ids := []*entities.NbIdentity{{InventoryName: "test1"}}
-       readerMock.On("GetListNodebIds").Return(ids, rnibErr)
+func TestE2TermInitEmptyE2TAddress(t *testing.T) {
+       _, handler, _, _, _, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte("{\"address\":\"\"}")}
+       handler.Handle(notificationRequest)
+       e2tInstancesManagerMock.AssertNotCalled(t, "GetE2TInstance")
+       e2tInstancesManagerMock.AssertNotCalled(t, "AddE2TInstance")
+}
+
+func TestE2TermInitGetE2TInstanceFailure(t *testing.T) {
+       _, handler, _, _, _, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       var e2tInstance *entities.E2TInstance
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, common.NewInternalError(fmt.Errorf("internal error")))
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+       handler.Handle(notificationRequest)
+       e2tInstancesManagerMock.AssertNotCalled(t, "AddE2TInstance")
+}
+
+func TestE2TermInitGetE2TInstanceDbFailure(t *testing.T) {
+       _, handler, readerMock, writerMock, rmrMessengerMock := initRanLostConnectionTestWithRealE2tInstanceManager(t)
+       var e2tInstance *entities.E2TInstance
+       readerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, common.NewInternalError(fmt.Errorf("internal error")))
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+       handler.Handle(notificationRequest)
+       writerMock.AssertNotCalled(t, "UpdateNodebInfo")
+       rmrMessengerMock.AssertNotCalled(t, "SendMsg")
+}
+
+func TestE2TermInitNewE2TInstance(t *testing.T) {
+       _, handler, _, _, _, e2tInstancesManagerMock, routingManagerClient := initRanLostConnectionTest(t)
+       var e2tInstance *entities.E2TInstance
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, common.NewResourceNotFoundError("not found"))
+       e2tInstance = entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstancesManagerMock.On("AddE2TInstance", e2tInstanceAddress).Return(nil)
+       routingManagerClient.On("AddE2TInstance", e2tInstanceAddress).Return(nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+       handler.Handle(notificationRequest)
+       routingManagerClient.AssertCalled(t, "AddE2TInstance", e2tInstanceAddress)
+       e2tInstancesManagerMock.AssertCalled(t, "AddE2TInstance", e2tInstanceAddress)
+}
+
+func TestE2TermInitNewE2TInstance_RoutingManagerError(t *testing.T) {
+       _, handler, _, _, _, e2tInstancesManagerMock, routingManagerClient := initRanLostConnectionTest(t)
+       var e2tInstance *entities.E2TInstance
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, common.NewResourceNotFoundError("not found"))
+       e2tInstance = entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstancesManagerMock.On("AddE2TInstance", e2tInstanceAddress).Return(nil)
+       routingManagerClient.On("AddE2TInstance", e2tInstanceAddress).Return(fmt.Errorf("error"))
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+
+       handler.Handle(notificationRequest)
+
+       routingManagerClient.AssertCalled(t, "AddE2TInstance", e2tInstanceAddress)
+       e2tInstancesManagerMock.AssertNotCalled(t, "AddE2TInstance", e2tInstanceAddress)
+}
+
+func TestE2TermInitExistingE2TInstanceNoAssociatedRans(t *testing.T) {
+       _, handler, _, _, _, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+       handler.Handle(notificationRequest)
+       e2tInstancesManagerMock.AssertCalled(t, "GetE2TInstance", e2tInstanceAddress)
+}
+
+func TestE2TermInitHandlerSuccessOneRan(t *testing.T) {
+       _, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       var rnibErr error
 
        var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
 
        var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
-       readerMock.On("GetNodeb", ids[0].InventoryName).Return(initialNodeb, rnibErr)
+       readerMock.On("GetNodeb", RanName).Return(initialNodeb, rnibErr)
 
        var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
        writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
 
        payload := e2pdus.PackedX2setupRequest
 
        var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
        writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
 
        payload := e2pdus.PackedX2setupRequest
-       xaction := []byte(ids[0].InventoryName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ids[0].InventoryName, &payload, &xaction)
+       xaction := []byte(RanName)
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), RanName, &payload, &xaction)
+
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
+
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+
+       handler.Handle(notificationRequest)
+
+       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
+       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
+}
+
+func TestE2TermInitHandlerSuccessOneRanShuttingdown(t *testing.T) {
+       _, handler, readerMock, writerMock, rmrMessengerMock := initRanLostConnectionTestWithRealE2tInstanceManager(t)
+       var rnibErr error
+
+       var initialNodeb = &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+       readerMock.On("GetNodeb", RanName).Return(initialNodeb, rnibErr)
+
+       var argNodeb = &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 0}
+       writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
+
+       payload := e2pdus.PackedX2setupRequest
+       xaction := []byte(RanName)
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), RanName, &payload, &xaction)
 
        rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
 
 
        rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
 
-       handler.Handle(nil)
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
+       readerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+
+       handler.Handle(notificationRequest)
+
+       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
+       rmrMessengerMock.AssertNotCalled(t, "SendMsg")
+}
+
+func TestE2TermInitHandlerSuccessOneRan_ToBeDeleted(t *testing.T) {
+       _, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       var rnibErr error
+
+       var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+       readerMock.On("GetNodeb", RanName).Return(initialNodeb, rnibErr)
+
+       var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
+       writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
+
+       payload := e2pdus.PackedX2setupRequest
+       xaction := []byte(RanName)
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), RanName, &payload, &xaction)
+
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
+
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.State = entities.ToBeDeleted
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
+
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+
+       handler.Handle(notificationRequest)
+
+       writerMock.AssertNotCalled(t, "UpdateNodebInfo")
+       rmrMessengerMock.AssertNotCalled(t, "SendMsg")
+}
+
+func TestE2TermInitHandlerSuccessOneRan_RoutingManagerFailure(t *testing.T) {
+       _, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       var rnibErr error
+
+       var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+       readerMock.On("GetNodeb", RanName).Return(initialNodeb, rnibErr)
+
+       var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
+       writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
+
+       payload := e2pdus.PackedX2setupRequest
+       xaction := []byte(RanName)
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), RanName, &payload, &xaction)
+
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
+
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.State = entities.RoutingManagerFailure
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
+
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       e2tInstancesManagerMock.On("ActivateE2TInstance", e2tInstance).Return(nil)
+       writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
+
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+
+       handler.Handle(notificationRequest)
 
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
        rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
 }
 
 
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
        rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
 }
 
-func TestE2TerminInitHandlerSuccessTwoRans(t *testing.T) {
-       _, handler, readerMock, writerMock, rmrMessengerMock := initRanLostConnectionTest(t)
+func TestE2TermInitHandlerSuccessOneRan_RoutingManagerFailure_Error(t *testing.T) {
+       _, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
        var rnibErr error
 
        var rnibErr error
 
-       ids := []*entities.NbIdentity{{InventoryName: "test1"}, {InventoryName: "test2"}}
-       readerMock.On("GetListNodebIds").Return(ids, rnibErr)
+       var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+       readerMock.On("GetNodeb", RanName).Return(initialNodeb, rnibErr)
+
+       var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
+       writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
 
 
+       payload := e2pdus.PackedX2setupRequest
+       xaction := []byte(RanName)
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), RanName, &payload, &xaction)
+
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
+
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.State = entities.RoutingManagerFailure
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
+
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       e2tInstancesManagerMock.On("ActivateE2TInstance", e2tInstance).Return(fmt.Errorf(" Error "))
+       writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
+
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+
+       handler.Handle(notificationRequest)
+
+       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 0)
+       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+}
+
+func TestE2TermInitHandlerSuccessTwoRans(t *testing.T) {
+       _, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       var rnibErr error
        var initialNodeb0 = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
        var initialNodeb1 = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
        var initialNodeb0 = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
        var initialNodeb1 = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
-       readerMock.On("GetNodeb", ids[0].InventoryName).Return(initialNodeb0, rnibErr)
-       readerMock.On("GetNodeb", ids[1].InventoryName).Return(initialNodeb1, rnibErr)
+       readerMock.On("GetNodeb", RanName).Return(initialNodeb0, rnibErr)
+       readerMock.On("GetNodeb", "test2").Return(initialNodeb1, rnibErr)
 
        var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
        writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
 
        payload := e2pdus.PackedX2setupRequest
 
        var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
        writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
 
        payload := e2pdus.PackedX2setupRequest
-       xaction := []byte(ids[0].InventoryName)
-       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ids[0].InventoryName, &payload, &xaction)
+       xaction := []byte(RanName)
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), RanName, &payload, &xaction)
 
 
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
+
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName, "test2")
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
 
 
-       handler.Handle(nil)
+       handler.Handle(notificationRequest)
 
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2)
        rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 2)
 }
 
 
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2)
        rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 2)
 }
 
-func TestE2TerminInitHandlerSuccessThreeRansFirstRmrFailure(t *testing.T) {
-       log, handler, readerMock, writerMock, rmrMessengerMock := initRanLostConnectionTest(t)
+func TestE2TermInitHandlerSuccessTwoRansSecondRanShutdown(t *testing.T) {
+       _, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t)
+       var rnibErr error
+       var initialNodeb0 = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+       var initialNodeb1 = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+       readerMock.On("GetNodeb", RanName).Return(initialNodeb0, rnibErr)
+       readerMock.On("GetNodeb", "test2").Return(initialNodeb1, rnibErr)
+
+       var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
+       writerMock.On("UpdateNodebInfo", argNodeb).Return(rnibErr)
+
+       payload := e2pdus.PackedX2setupRequest
+       xaction := []byte(RanName)
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), RanName, &payload, &xaction)
+
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
+
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName, "test2")
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+
+       handler.Handle(notificationRequest)
+
+       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
+       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
+       writerMock.AssertExpectations(t)
+}
+
+func TestE2TermInitHandlerSuccessThreeRansFirstRmrFailure(t *testing.T) {
+       log, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
        var rnibErr error
 
        ids := []*entities.NbIdentity{{InventoryName: "test1"}, {InventoryName: "test2"}, {InventoryName: "test3"}}
        var rnibErr error
 
        ids := []*entities.NbIdentity{{InventoryName: "test1"}, {InventoryName: "test2"}, {InventoryName: "test3"}}
-       readerMock.On("GetListNodebIds").Return(ids, rnibErr)
 
        var initialNodeb0 = &entities.NodebInfo{RanName: ids[0].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
        var initialNodeb1 = &entities.NodebInfo{RanName: ids[1].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
 
        var initialNodeb0 = &entities.NodebInfo{RanName: ids[0].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
        var initialNodeb1 = &entities.NodebInfo{RanName: ids[1].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
@@ -123,9 +387,14 @@ func TestE2TerminInitHandlerSuccessThreeRansFirstRmrFailure(t *testing.T) {
        //xaction = []byte(ids[1].InventoryName)
        //msg1 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ids[1].InventoryName, &payload, &xaction)
 
        //xaction = []byte(ids[1].InventoryName)
        //msg1 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ids[1].InventoryName, &payload, &xaction)
 
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg0, fmt.Errorf("RMR Error"))
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg0, fmt.Errorf("RMR Error"))
 
 
-       handler.Handle(nil)
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, "test1", "test2", "test3")
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+
+       handler.Handle(notificationRequest)
 
        //test1 (before send +1, after failure +1), test2 (0) test3 (0)
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2)
 
        //test1 (before send +1, after failure +1), test2 (0) test3 (0)
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2)
@@ -133,12 +402,11 @@ func TestE2TerminInitHandlerSuccessThreeRansFirstRmrFailure(t *testing.T) {
        rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
 }
 
        rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
 }
 
-func TestE2TerminInitHandlerSuccessThreeRansSecondNotFoundFailure(t *testing.T) {
-       log, handler, readerMock, writerMock, rmrMessengerMock := initRanLostConnectionTest(t)
+func TestE2TermInitHandlerSuccessThreeRansSecondNotFoundFailure(t *testing.T) {
+       log, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
        var rnibErr error
 
        ids := []*entities.NbIdentity{{InventoryName: "test1"}, {InventoryName: "test2"}, {InventoryName: "test3"}}
        var rnibErr error
 
        ids := []*entities.NbIdentity{{InventoryName: "test1"}, {InventoryName: "test2"}, {InventoryName: "test3"}}
-       readerMock.On("GetListNodebIds").Return(ids, rnibErr)
 
        var initialNodeb0 = &entities.NodebInfo{RanName: ids[0].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
        var initialNodeb1 = &entities.NodebInfo{RanName: ids[1].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
 
        var initialNodeb0 = &entities.NodebInfo{RanName: ids[0].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
        var initialNodeb1 = &entities.NodebInfo{RanName: ids[1].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
@@ -166,9 +434,14 @@ func TestE2TerminInitHandlerSuccessThreeRansSecondNotFoundFailure(t *testing.T)
        //xaction = []byte(ids[1].InventoryName)
        //msg1 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ids[1].InventoryName, &payload, &xaction)
 
        //xaction = []byte(ids[1].InventoryName)
        //msg1 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ids[1].InventoryName, &payload, &xaction)
 
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg0, nil)
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg0, nil)
+
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, "test1", "test2", "test3")
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
 
 
-       handler.Handle(nil)
+       handler.Handle(notificationRequest)
 
        readerMock.AssertNumberOfCalls(t, "GetNodeb", 3)
        //test1 (+1), test2 failure (0) test3 (+1)
 
        readerMock.AssertNumberOfCalls(t, "GetNodeb", 3)
        //test1 (+1), test2 failure (0) test3 (+1)
@@ -177,12 +450,11 @@ func TestE2TerminInitHandlerSuccessThreeRansSecondNotFoundFailure(t *testing.T)
        rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 2)
 }
 
        rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 2)
 }
 
-func TestE2TerminInitHandlerSuccessThreeRansSecondRnibInternalErrorFailure(t *testing.T) {
-       log, handler, readerMock, writerMock, rmrMessengerMock := initRanLostConnectionTest(t)
+func TestE2TermInitHandlerSuccessThreeRansSecondRnibInternalErrorFailure(t *testing.T) {
+       log, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
        var rnibErr error
 
        ids := []*entities.NbIdentity{{InventoryName: "test1"}, {InventoryName: "test2"}, {InventoryName: "test3"}}
        var rnibErr error
 
        ids := []*entities.NbIdentity{{InventoryName: "test1"}, {InventoryName: "test2"}, {InventoryName: "test3"}}
-       readerMock.On("GetListNodebIds").Return(ids, rnibErr)
 
        var initialNodeb0 = &entities.NodebInfo{RanName: ids[0].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
        var initialNodeb1 = &entities.NodebInfo{RanName: ids[1].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
 
        var initialNodeb0 = &entities.NodebInfo{RanName: ids[0].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
        var initialNodeb1 = &entities.NodebInfo{RanName: ids[1].InventoryName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
@@ -210,9 +482,14 @@ func TestE2TerminInitHandlerSuccessThreeRansSecondRnibInternalErrorFailure(t *te
        //xaction = []byte(ids[1].InventoryName)
        //msg1 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ids[1].InventoryName, &payload, &xaction)
 
        //xaction = []byte(ids[1].InventoryName)
        //msg1 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ids[1].InventoryName, &payload, &xaction)
 
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg0, nil)
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg0, nil)
 
 
-       handler.Handle(nil)
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, "test1", "test2", "test3")
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+
+       handler.Handle(notificationRequest)
 
        readerMock.AssertNumberOfCalls(t, "GetNodeb", 2)
        //test1 (+1), test2 failure (0) test3 (0)
 
        readerMock.AssertNumberOfCalls(t, "GetNodeb", 2)
        //test1 (+1), test2 failure (0) test3 (0)
@@ -221,34 +498,69 @@ func TestE2TerminInitHandlerSuccessThreeRansSecondRnibInternalErrorFailure(t *te
        rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
 }
 
        rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
 }
 
-func TestE2TerminInitHandlerSuccessZeroRans(t *testing.T) {
-       _, handler, readerMock, writerMock, rmrMessengerMock := initRanLostConnectionTest(t)
-       var rnibErr error
+func TestE2TermInitHandlerSuccessZeroRans(t *testing.T) {
+       _, handler, _, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
 
 
-       readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, rnibErr)
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
 
 
-       handler.Handle(nil)
+       handler.Handle(notificationRequest)
 
 
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 0)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+       writerMock.AssertNotCalled(t, "UpdateNodebInfo")
+       rmrMessengerMock.AssertNotCalled(t, "SendMsg")
 }
 
 }
 
-func TestE2TerminInitHandlerFailureGetListNodebIds(t *testing.T) {
-       _, handler, readerMock, writerMock, rmrMessengerMock := initRanLostConnectionTest(t)
+func TestE2TermInitHandlerFailureGetNodebInternalError(t *testing.T) {
+       _, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t)
 
 
-       readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, common.NewInternalError(fmt.Errorf("internal error")))
+       var nodebInfo *entities.NodebInfo
+       readerMock.On("GetNodeb", "test1").Return(nodebInfo, common.NewInternalError(fmt.Errorf("internal error")))
 
 
-       handler.Handle(nil)
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, "test1")
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+       handler.Handle(notificationRequest)
 
 
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 0)
-       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+       writerMock.AssertNotCalled(t, "UpdateNodebInfo")
+       rmrMessengerMock.AssertNotCalled(t, "SendMsg")
+}
+
+func TestE2TermInitHandlerSuccessTwoRansSecondIsDisconnected(t *testing.T) {
+       _, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t)
+       var rnibErr error
+       var initialNodeb0 = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+       var initialNodeb1 = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+       readerMock.On("GetNodeb", RanName).Return(initialNodeb0, rnibErr)
+       readerMock.On("GetNodeb", "test2").Return(initialNodeb1, rnibErr)
+
+       var argNodeb1 = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1}
+       writerMock.On("UpdateNodebInfo", argNodeb1).Return(rnibErr)
+
+       payload := e2pdus.PackedX2setupRequest
+       xaction := []byte(RanName)
+       msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), RanName, &payload, &xaction)
+
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
+
+       e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName, "test2")
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
+
+       handler.Handle(notificationRequest)
+
+       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2)
+       rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 2)
 }
 
 }
 
+
 // TODO: extract to test_utils
 func initRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
 // TODO: extract to test_utils
 func initRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
-       return rmrsender.NewRmrSender(log, &rmrMessenger)
+       return rmrsender.NewRmrSender(log, rmrMessenger)
 }
 
 // TODO: extract to test_utils
 }
 
 // TODO: extract to test_utils
diff --git a/E2Manager/handlers/rmrmsghandlers/e2t_keep_alive_response_handler.go b/E2Manager/handlers/rmrmsghandlers/e2t_keep_alive_response_handler.go
new file mode 100644 (file)
index 0000000..73583d4
--- /dev/null
@@ -0,0 +1,51 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package rmrmsghandlers
+
+import (
+       "e2mgr/logger"
+       "e2mgr/managers"
+       "e2mgr/models"
+       "e2mgr/services"
+       "encoding/json"
+)
+
+type E2TKeepAliveResponseHandler struct {
+       logger              *logger.Logger
+       rnibDataService     services.RNibDataService
+       e2TInstancesManager managers.IE2TInstancesManager
+}
+
+func NewE2TKeepAliveResponseHandler(logger *logger.Logger, rnibDataService services.RNibDataService, e2TInstancesManager managers.IE2TInstancesManager) E2TKeepAliveResponseHandler {
+       return E2TKeepAliveResponseHandler{
+               logger:              logger,
+               rnibDataService:     rnibDataService,
+               e2TInstancesManager: e2TInstancesManager,
+       }
+}
+
+func (h E2TKeepAliveResponseHandler) Handle(request *models.NotificationRequest) {
+       unmarshalledPayload := models.E2TKeepAlivePayload{}
+       err := json.Unmarshal(request.Payload, &unmarshalledPayload)
+
+       if err != nil {
+               h.logger.Errorf("#E2TKeepAliveResponseHandler.Handle - Error unmarshaling RMR request payload: %v", err)
+               return
+       }
+
+       _ = h.e2TInstancesManager.ResetKeepAliveTimestamp(unmarshalledPayload.Address)
+}
diff --git a/E2Manager/handlers/rmrmsghandlers/e2t_keep_alive_response_handler_test.go b/E2Manager/handlers/rmrmsghandlers/e2t_keep_alive_response_handler_test.go
new file mode 100644 (file)
index 0000000..ba9fc43
--- /dev/null
@@ -0,0 +1,59 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package rmrmsghandlers
+
+import (
+       "e2mgr/configuration"
+       "e2mgr/logger"
+       "e2mgr/mocks"
+       "e2mgr/models"
+       "e2mgr/services"
+       "testing"
+)
+
+func initE2TKeepAliveTest(t *testing.T) (*logger.Logger, E2TKeepAliveResponseHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.E2TInstancesManagerMock) {
+
+       logger := initLog(t)
+       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
+
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
+
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+
+       e2tInstancesManagerMock := &mocks.E2TInstancesManagerMock{}
+       handler := NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManagerMock)
+       return logger, handler, readerMock, writerMock, e2tInstancesManagerMock
+}
+
+func TestE2TKeepAliveUnmarshalPayloadFailure(t *testing.T) {
+       _, handler, _, _, e2tInstancesManagerMock := initE2TKeepAliveTest(t)
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte("asd")}
+       handler.Handle(notificationRequest)
+       e2tInstancesManagerMock.AssertNotCalled(t, "ResetKeepAliveTimestamp")
+}
+
+func TestE2TKeepAliveUnmarshalPayloadSuccess(t *testing.T) {
+       _, handler, _, _, e2tInstancesManagerMock := initE2TKeepAliveTest(t)
+
+       jsonRequest := "{\"address\":\"10.10.2.15:9800\"}"
+       notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(jsonRequest)}
+
+       e2tInstancesManagerMock.On("ResetKeepAliveTimestamp", "10.10.2.15:9800").Return(nil)
+       handler.Handle(notificationRequest)
+       e2tInstancesManagerMock.AssertCalled(t, "ResetKeepAliveTimestamp", "10.10.2.15:9800")
+}
index a6a6234..8989af5 100644 (file)
@@ -1,6 +1,21 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
 package rmrmsghandlers
 
 package rmrmsghandlers
 
-import "C"
 import (
        "e2mgr/converters"
        "e2mgr/e2pdus"
 import (
        "e2mgr/converters"
        "e2mgr/e2pdus"
@@ -44,7 +59,7 @@ func (h EnbLoadInformationNotificationHandler) Handle(request *models.Notificati
 
        err = h.extractor.ExtractAndBuildRanLoadInformation(pdu, ranLoadInformation)
 
 
        err = h.extractor.ExtractAndBuildRanLoadInformation(pdu, ranLoadInformation)
 
-       if (err != nil) {
+       if err != nil {
                h.logger.Errorf("#EnbLoadInformationNotificationHandler.Handle - RAN name: %s - Failed at ExtractAndBuildRanLoadInformation. Error: %v", request.RanName, err)
                return
        }
                h.logger.Errorf("#EnbLoadInformationNotificationHandler.Handle - RAN name: %s - Failed at ExtractAndBuildRanLoadInformation. Error: %v", request.RanName, err)
                return
        }
index 9c58274..8c5627a 100644 (file)
@@ -34,7 +34,7 @@ const (
        GarbagePdu   string = "12312312"
 )
 
        GarbagePdu   string = "12312312"
 )
 
-func createNotificationRequest(ranName string, transactionId string, packedPdu string) (*models.NotificationRequest, error) {
+func createNotificationRequest(ranName string, transactionId []byte, packedPdu string) (*models.NotificationRequest, error) {
        var packedByteSlice []byte
 
        _, err := fmt.Sscanf(packedPdu, "%x", &packedByteSlice)
        var packedByteSlice []byte
 
        _, err := fmt.Sscanf(packedPdu, "%x", &packedByteSlice)
@@ -46,7 +46,7 @@ func createNotificationRequest(ranName string, transactionId string, packedPdu s
        return models.NewNotificationRequest(ranName, packedByteSlice, time.Now(), transactionId), nil
 }
 
        return models.NewNotificationRequest(ranName, packedByteSlice, time.Now(), transactionId), nil
 }
 
-func createNotificationRequestAndHandle(ranName string, transactionId string, loadInformationHandler EnbLoadInformationNotificationHandler, pdu string) error {
+func createNotificationRequestAndHandle(ranName string, transactionId []byte, loadInformationHandler EnbLoadInformationNotificationHandler, pdu string) error {
        notificationRequest, err := createNotificationRequest(ranName, transactionId, pdu)
 
        if err != nil {
        notificationRequest, err := createNotificationRequest(ranName, transactionId, pdu)
 
        if err != nil {
index bfc4e1b..c460941 100644 (file)
@@ -32,7 +32,7 @@ import (
        "e2mgr/models"
        "e2mgr/rmrCgo"
        "e2mgr/services/rmrsender"
        "e2mgr/models"
        "e2mgr/rmrCgo"
        "e2mgr/services/rmrsender"
-       "unsafe"
+       "e2mgr/utils"
 )
 
 type EndcConfigurationUpdateHandler struct {
 )
 
 type EndcConfigurationUpdateHandler struct {
@@ -49,35 +49,22 @@ func NewEndcConfigurationUpdateHandler(logger *logger.Logger, rmrSender *rmrsend
 
 func (h EndcConfigurationUpdateHandler) Handle(request *models.NotificationRequest) {
 
 
 func (h EndcConfigurationUpdateHandler) Handle(request *models.NotificationRequest) {
 
-       var payloadSize C.ulong
-       payloadSize = e2pdus.MaxAsn1PackedBufferSize
-       packedBuffer := [e2pdus.MaxAsn1PackedBufferSize]C.uchar{}
-       errorBuffer := [e2pdus.MaxAsn1PackedBufferSize]C.char{}
        refinedMessage, err := converters.UnpackX2apPduAndRefine(h.logger, e2pdus.MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, request.Len, request.Payload, e2pdus.MaxAsn1CodecMessageBufferSize /*message buffer*/)
        refinedMessage, err := converters.UnpackX2apPduAndRefine(h.logger, e2pdus.MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, request.Len, request.Payload, e2pdus.MaxAsn1CodecMessageBufferSize /*message buffer*/)
+
        if err != nil {
        if err != nil {
-               status := C.build_pack_endc_configuration_update_failure(&payloadSize, &packedBuffer[0], e2pdus.MaxAsn1PackedBufferSize, &errorBuffer[0])
-               if status {
-                       payload := (*[1 << 30]byte)(unsafe.Pointer(&packedBuffer))[:payloadSize:payloadSize]
-                       h.logger.Debugf("#endc_configuration_update_handler.Handle - Endc configuration update negative ack message payload: (%d) %02x", len(payload), payload)
-                       msg := models.NewRmrMessage(rmrCgo.RIC_ENDC_CONF_UPDATE_FAILURE, request.RanName, payload)
-                       _ = h.rmrSender.Send(msg)
-               } else {
-                       h.logger.Errorf("#endc_configuration_update_handler.Handle - failed to build and pack Endc configuration update unsuccessful outcome message. Error: %v", errorBuffer)
-               }
                h.logger.Errorf("#endc_configuration_update_handler.Handle - unpack failed. Error: %v", err)
                h.logger.Errorf("#endc_configuration_update_handler.Handle - unpack failed. Error: %v", err)
-       } else {
-               h.logger.Infof("#endc_configuration_update_handler.Handle - Endc configuration update initiating message received")
-               h.logger.Debugf("#endc_configuration_update_handler.Handle - Endc configuration update initiating message payload: %s", refinedMessage.PduPrint)
-               status := C.build_pack_endc_configuration_update_ack(&payloadSize, &packedBuffer[0], e2pdus.MaxAsn1PackedBufferSize, &errorBuffer[0])
-               if status {
-                       payload := (*[1 << 30]byte)(unsafe.Pointer(&packedBuffer))[:payloadSize:payloadSize]
-                       h.logger.Debugf("#endc_configuration_update_handler.Handle - Endc configuration update positive ack message payload: (%d) %02x", len(payload), payload)
-                       msg := models.NewRmrMessage(rmrCgo.RIC_ENDC_CONF_UPDATE_ACK, request.RanName, payload)
-                       _ = h.rmrSender.Send(msg)
-               } else {
-                       h.logger.Errorf("#endc_configuration_update_handler.Handle - failed to build and pack endc configuration update successful outcome message. Error: %v", errorBuffer)
-               }
+
+               msg := models.NewRmrMessage(rmrCgo.RIC_ENDC_CONF_UPDATE_FAILURE, request.RanName, e2pdus.PackedEndcConfigurationUpdateFailure, request.TransactionId)
+               _ = h.rmrSender.Send(msg)
+
+               h.logger.Infof("#EndcConfigurationUpdateHandler.Handle - Summary: elapsed time for receiving and handling endc configuration update initiating message from E2 terminator: %f ms", utils.ElapsedTime(request.StartTime))
+               return
        }
 
        }
 
-       printHandlingSetupResponseElapsedTimeInMs(h.logger, "#endc_configuration_update_handler.Handle - Summary: Elapsed time for receiving and handling endc configuration update initiating message from E2 terminator", request.StartTime)
+       h.logger.Infof("#endc_configuration_update_handler.Handle - Endc configuration update initiating message received")
+       h.logger.Debugf("#endc_configuration_update_handler.Handle - Endc configuration update initiating message payload: %s", refinedMessage.PduPrint)
+       msg := models.NewRmrMessage(rmrCgo.RIC_ENDC_CONF_UPDATE_ACK, request.RanName, e2pdus.PackedEndcConfigurationUpdateAck, request.TransactionId)
+       _ = h.rmrSender.Send(msg)
+
+       h.logger.Infof("#EndcConfigurationUpdateHandler.Handle - Summary: elapsed time for receiving and handling endc configuration update initiating message from E2 terminator: %f ms", utils.ElapsedTime(request.StartTime))
 }
 }
index db847ad..1c2afe9 100644 (file)
@@ -43,31 +43,33 @@ func TestHandleEndcConfigUpdateSuccess(t *testing.T) {
        h, rmrMessengerMock := initEndcConfigurationUpdateHandlerTest(t)
 
        ranName := "test"
        h, rmrMessengerMock := initEndcConfigurationUpdateHandlerTest(t)
 
        ranName := "test"
-       xaction := []byte(ranName)
+       xAction := []byte("123456aa")
 
        var payload []byte
        _, _ = fmt.Sscanf(PackedEndcConfigurationUpdateAck, "%x", &payload)
 
 
        var payload []byte
        _, _ = fmt.Sscanf(PackedEndcConfigurationUpdateAck, "%x", &payload)
 
-       mBuf := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_CONF_UPDATE_ACK, len(payload), ranName, &payload, &xaction)
-       notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload, StartTime: time.Now()}
+       mBuf := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_CONF_UPDATE_ACK, len(payload), ranName, &payload, &xAction)
+       notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload, StartTime: time.Now(),
+               TransactionId: *mBuf.XAction}
        var err error
        var err error
-       rmrMessengerMock.On("SendMsg", mBuf).Return(&rmrCgo.MBuf{}, err)
+       rmrMessengerMock.On("SendMsg", mBuf, true).Return(&rmrCgo.MBuf{}, err)
        h.Handle(&notificationRequest)
        h.Handle(&notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf, true)
 }
 
 func TestHandleEndcConfigUpdateFailure(t *testing.T) {
        h, rmrMessengerMock := initEndcConfigurationUpdateHandlerTest(t)
 
        ranName := "test"
 }
 
 func TestHandleEndcConfigUpdateFailure(t *testing.T) {
        h, rmrMessengerMock := initEndcConfigurationUpdateHandlerTest(t)
 
        ranName := "test"
-       xaction := []byte(ranName)
+       xAction := []byte("123456aa")
 
        var payload []byte
        _, _ = fmt.Sscanf(PackedEndcConfigurationUpdateFailure, "%x", &payload)
 
 
        var payload []byte
        _, _ = fmt.Sscanf(PackedEndcConfigurationUpdateFailure, "%x", &payload)
 
-       mBuf := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_CONF_UPDATE_FAILURE, len(payload), ranName, &payload, &xaction)
-       notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: 0, Payload: []byte{0}, StartTime: time.Now()}
-       rmrMessengerMock.On("SendMsg", mBuf).Return(&rmrCgo.MBuf{}, fmt.Errorf("send failure"))
+       mBuf := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_CONF_UPDATE_FAILURE, len(payload), ranName, &payload, &xAction)
+       notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: 0, Payload: []byte{0}, StartTime: time.Now(),
+               TransactionId: *mBuf.XAction}
+       rmrMessengerMock.On("SendMsg", mBuf, true).Return(&rmrCgo.MBuf{}, fmt.Errorf("send failure"))
        h.Handle(&notificationRequest)
        h.Handle(&notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf, true)
 }
 }
index 6ec0720..4a85de2 100644 (file)
 package rmrmsghandlers
 
 import (
 package rmrmsghandlers
 
 import (
-       "e2mgr/logger"
        "e2mgr/models"
        "e2mgr/models"
-       "time"
 )
 
 type NotificationHandler interface {
        Handle(*models.NotificationRequest)
 }
 )
 
 type NotificationHandler interface {
        Handle(*models.NotificationRequest)
 }
-
-//TODO: remove that
-func printHandlingSetupResponseElapsedTimeInMs(logger *logger.Logger, msg string, startTime time.Time) {
-       logger.Infof("%s: %f ms", msg, float64(time.Since(startTime))/float64(time.Millisecond))
-}
index 111b1a4..f4bfd63 100644 (file)
@@ -29,7 +29,6 @@ import (
        "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/models"
        "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/models"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
@@ -37,7 +36,6 @@ import (
        "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"
        "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"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/pkg/errors"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
        "github.com/pkg/errors"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
@@ -84,13 +82,8 @@ func NewSetupResponseTestContext(manager managers.ISetupResponseManager) *setupR
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
        writerMock := &mocks.RnibWriterMock{}
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
        writerMock := &mocks.RnibWriterMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
-       rnibDataService := services.NewRnibDataService(logger, config, rnibReaderProvider, rnibWriterProvider)
+
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
 
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        rmrSender := initRmrSender(rmrMessengerMock, logger)
 
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        rmrSender := initRmrSender(rmrMessengerMock, logger)
@@ -157,17 +150,17 @@ func executeHandleSetupSuccessResponse(t *testing.T, tc setupSuccessResponseTest
 
        testContext.readerMock.On("GetNodeb", RanName).Return(nodebInfo, rnibErr)
        testContext.writerMock.On("SaveNodeb", mock.Anything, mock.Anything).Return(tc.saveNodebMockError)
 
        testContext.readerMock.On("GetNodeb", RanName).Return(nodebInfo, rnibErr)
        testContext.writerMock.On("SaveNodeb", mock.Anything, mock.Anything).Return(tc.saveNodebMockError)
-       testContext.rmrMessengerMock.On("SendMsg", tc.statusChangeMbuf).Return(&rmrCgo.MBuf{}, tc.sendMsgError)
+       testContext.rmrMessengerMock.On("SendMsg", tc.statusChangeMbuf, true).Return(&rmrCgo.MBuf{}, tc.sendMsgError)
        handler.Handle(&notificationRequest)
 
        return testContext, nodebInfo
 }
 
 func getRanConnectedMbuf(nodeType entities.Node_Type) *rmrCgo.MBuf {
        handler.Handle(&notificationRequest)
 
        return testContext, nodebInfo
 }
 
 func getRanConnectedMbuf(nodeType entities.Node_Type) *rmrCgo.MBuf {
-       xaction := []byte(RanName)
+       var xAction []byte
        resourceStatusPayload := models.NewResourceStatusPayload(nodeType, enums.RIC_TO_RAN)
        resourceStatusJson, _ := json.Marshal(resourceStatusPayload)
        resourceStatusPayload := models.NewResourceStatusPayload(nodeType, enums.RIC_TO_RAN)
        resourceStatusJson, _ := json.Marshal(resourceStatusPayload)
-       return rmrCgo.NewMBuf(rmrCgo.RAN_CONNECTED, len(resourceStatusJson), RanName, &resourceStatusJson, &xaction)
+       return rmrCgo.NewMBuf(rmrCgo.RAN_CONNECTED, len(resourceStatusJson), RanName, &resourceStatusJson, &xAction)
 }
 
 func executeHandleSetupFailureResponse(t *testing.T, tc setupFailureResponseTestCase) (*setupResponseTestContext, *entities.NodebInfo) {
 }
 
 func executeHandleSetupFailureResponse(t *testing.T, tc setupFailureResponseTestCase) (*setupResponseTestContext, *entities.NodebInfo) {
@@ -222,7 +215,7 @@ func TestX2SetupResponse(t *testing.T) {
        assert.IsType(t, &entities.NodebInfo_Enb{}, nodebInfo.Configuration)
        i, _ := nodebInfo.Configuration.(*entities.NodebInfo_Enb)
        assert.NotNil(t, i.Enb)
        assert.IsType(t, &entities.NodebInfo_Enb{}, nodebInfo.Configuration)
        i, _ := nodebInfo.Configuration.(*entities.NodebInfo_Enb)
        assert.NotNil(t, i.Enb)
-       testContext.rmrMessengerMock.AssertCalled(t, "SendMsg", tc.statusChangeMbuf)
+       testContext.rmrMessengerMock.AssertCalled(t, "SendMsg", tc.statusChangeMbuf, true)
 }
 
 func TestX2SetupFailureResponse(t *testing.T) {
 }
 
 func TestX2SetupFailureResponse(t *testing.T) {
@@ -246,11 +239,12 @@ func TestX2SetupFailureResponse(t *testing.T) {
 }
 
 func TestEndcSetupResponse(t *testing.T) {
 }
 
 func TestEndcSetupResponse(t *testing.T) {
+       logger := initLog(t)
        var saveNodebMockError error
        var sendMsgError error
        tc := setupSuccessResponseTestCase{
                EndcSetupResponsePackedPdu,
        var saveNodebMockError error
        var sendMsgError error
        tc := setupSuccessResponseTestCase{
                EndcSetupResponsePackedPdu,
-               &managers.EndcSetupResponseManager{},
+               managers.NewEndcSetupResponseManager(converters.NewEndcSetupResponseConverter(logger)),
                rmrCgo.RIC_ENDC_X2_SETUP_RESP,
                saveNodebMockError,
                sendMsgError,
                rmrCgo.RIC_ENDC_X2_SETUP_RESP,
                saveNodebMockError,
                sendMsgError,
@@ -267,15 +261,15 @@ func TestEndcSetupResponse(t *testing.T) {
 
        i, _ := nodebInfo.Configuration.(*entities.NodebInfo_Gnb)
        assert.NotNil(t, i.Gnb)
 
        i, _ := nodebInfo.Configuration.(*entities.NodebInfo_Gnb)
        assert.NotNil(t, i.Gnb)
-       testContext.rmrMessengerMock.AssertCalled(t, "SendMsg", tc.statusChangeMbuf)
+       testContext.rmrMessengerMock.AssertCalled(t, "SendMsg", tc.statusChangeMbuf, true)
 }
 
 func TestEndcSetupFailureResponse(t *testing.T) {
 }
 
 func TestEndcSetupFailureResponse(t *testing.T) {
-
+       logger := initLog(t)
        var saveNodebMockError error
        tc := setupFailureResponseTestCase{
                EndcSetupFailureResponsePackedPdu,
        var saveNodebMockError error
        tc := setupFailureResponseTestCase{
                EndcSetupFailureResponsePackedPdu,
-               &managers.EndcSetupFailureResponseManager{},
+               managers.NewEndcSetupFailureResponseManager(converters.NewEndcSetupFailureResponseConverter(logger)),
                rmrCgo.RIC_ENDC_X2_SETUP_FAILURE,
                saveNodebMockError,
        }
                rmrCgo.RIC_ENDC_X2_SETUP_FAILURE,
                saveNodebMockError,
        }
@@ -346,5 +340,5 @@ func TestSetupResponseStatusChangeSendFailure(t *testing.T) {
        assert.IsType(t, &entities.NodebInfo_Enb{}, nodebInfo.Configuration)
        i, _ := nodebInfo.Configuration.(*entities.NodebInfo_Enb)
        assert.NotNil(t, i.Enb)
        assert.IsType(t, &entities.NodebInfo_Enb{}, nodebInfo.Configuration)
        i, _ := nodebInfo.Configuration.(*entities.NodebInfo_Enb)
        assert.NotNil(t, i.Enb)
-       testContext.rmrMessengerMock.AssertCalled(t, "SendMsg", tc.statusChangeMbuf)
+       testContext.rmrMessengerMock.AssertCalled(t, "SendMsg", tc.statusChangeMbuf, true)
 }
 }
index 53af51e..164984a 100644 (file)
@@ -35,9 +35,7 @@ import (
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/utils"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/utils"
-       "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-       "unsafe"
 )
 
 type X2ResetRequestNotificationHandler struct {
 )
 
 type X2ResetRequestNotificationHandler struct {
@@ -81,27 +79,9 @@ func (h X2ResetRequestNotificationHandler) Handle(request *models.NotificationRe
                return
        }
 
                return
        }
 
-       msg, err := createX2ResetResponseNotification(request)
-       if err != nil {
-               h.logger.Errorf("#X2ResetRequestNotificationHandler.Handle - %s", err)
-               return
-       }
+       msg := models.NewRmrMessage(rmrCgo.RIC_X2_RESET_RESP, request.RanName, e2pdus.PackedX2ResetResponse, request.TransactionId)
 
        _ = h.rmrSender.Send(msg)
        h.logger.Infof("#X2ResetRequestNotificationHandler.Handle - Summary: elapsed time for receiving and handling reset request message from E2 terminator: %f ms", utils.ElapsedTime(request.StartTime))
        _ = h.ranStatusChangeManager.Execute(rmrCgo.RAN_RESTARTED, enums.RAN_TO_RIC, nb)
 }
 
        _ = h.rmrSender.Send(msg)
        h.logger.Infof("#X2ResetRequestNotificationHandler.Handle - Summary: elapsed time for receiving and handling reset request message from E2 terminator: %f ms", utils.ElapsedTime(request.StartTime))
        _ = h.ranStatusChangeManager.Execute(rmrCgo.RAN_RESTARTED, enums.RAN_TO_RIC, nb)
 }
-
-func createX2ResetResponseNotification(request *models.NotificationRequest) (*models.RmrMessage, error) {
-
-       packedBuffer := make([]C.uchar, e2pdus.MaxAsn1PackedBufferSize)
-       errorBuffer := make([]C.char, e2pdus.MaxAsn1CodecMessageBufferSize)
-       var payloadSize = C.ulong(e2pdus.MaxAsn1PackedBufferSize)
-
-       if status := C.build_pack_x2reset_response(&payloadSize, &packedBuffer[0], C.ulong(e2pdus.MaxAsn1CodecMessageBufferSize), &errorBuffer[0]); !status {
-               return nil, fmt.Errorf("failed to build and pack the reset response message %s ", C.GoString(&errorBuffer[0]))
-       }
-       payload := C.GoBytes(unsafe.Pointer(&packedBuffer[0]), C.int(payloadSize))
-       msg := models.NewRmrMessage(rmrCgo.RIC_X2_RESET_RESP, request.RanName, payload)
-       return msg, nil
-}
index 7a7e95c..6b6f00c 100644 (file)
@@ -33,7 +33,6 @@ import (
        "encoding/json"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "encoding/json"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "testing"
        "time"
 )
        "testing"
        "time"
 )
@@ -42,10 +41,8 @@ func initX2ResetRequestNotificationHandlerTest(t *testing.T) (X2ResetRequestNoti
        log := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
        log := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
        readerMock := &mocks.RnibReaderMock{}
-       readerProvider := func() reader.RNibReader {
-               return readerMock
-       }
-       rnibDataService := services.NewRnibDataService(log, config, readerProvider, nil)
+
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, nil)
 
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        rmrSender := initRmrSender(rmrMessengerMock, log)
 
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        rmrSender := initRmrSender(rmrMessengerMock, log)
@@ -55,38 +52,38 @@ func initX2ResetRequestNotificationHandlerTest(t *testing.T) (X2ResetRequestNoti
 }
 
 func getRanRestartedMbuf(nodeType entities.Node_Type, messageDirection enums.MessageDirection) *rmrCgo.MBuf {
 }
 
 func getRanRestartedMbuf(nodeType entities.Node_Type, messageDirection enums.MessageDirection) *rmrCgo.MBuf {
-       xaction := []byte(RanName)
+       var xAction []byte
        resourceStatusPayload := models.NewResourceStatusPayload(nodeType, messageDirection)
        resourceStatusJson, _ := json.Marshal(resourceStatusPayload)
        resourceStatusPayload := models.NewResourceStatusPayload(nodeType, messageDirection)
        resourceStatusJson, _ := json.Marshal(resourceStatusPayload)
-       return rmrCgo.NewMBuf(rmrCgo.RAN_RESTARTED, len(resourceStatusJson), RanName, &resourceStatusJson, &xaction)
+       return rmrCgo.NewMBuf(rmrCgo.RAN_RESTARTED, len(resourceStatusJson), RanName, &resourceStatusJson, &xAction)
 }
 
 func TestHandleX2ResetRequestNotificationSuccess(t *testing.T) {
        h, readerMock, rmrMessengerMock := initX2ResetRequestNotificationHandlerTest(t)
        ranName := "test"
 }
 
 func TestHandleX2ResetRequestNotificationSuccess(t *testing.T) {
        h, readerMock, rmrMessengerMock := initX2ResetRequestNotificationHandlerTest(t)
        ranName := "test"
-       xaction := []byte(ranName)
-       notificationRequest := models.NewNotificationRequest(ranName, []byte{}, time.Now(), ranName)
+       xAction := []byte("123456aa")
+       notificationRequest := models.NewNotificationRequest(ranName, []byte{}, time.Now(), xAction)
 
        nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_ENB}
        var err error
        readerMock.On("GetNodeb", ranName).Return(nb, err)
 
        nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_ENB}
        var err error
        readerMock.On("GetNodeb", ranName).Return(nb, err)
-       resetResponseMbuf := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET_RESP, len(e2pdus.PackedX2ResetResponse), ranName, &e2pdus.PackedX2ResetResponse, &xaction)
-       rmrMessengerMock.On("SendMsg", resetResponseMbuf).Return(&rmrCgo.MBuf{}, err)
+       resetResponseMbuf := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET_RESP, len(e2pdus.PackedX2ResetResponse), ranName, &e2pdus.PackedX2ResetResponse, &xAction)
+       rmrMessengerMock.On("SendMsg", resetResponseMbuf, true).Return(&rmrCgo.MBuf{}, err)
        ranRestartedMbuf := getRanRestartedMbuf(nb.NodeType, enums.RAN_TO_RIC)
        ranRestartedMbuf := getRanRestartedMbuf(nb.NodeType, enums.RAN_TO_RIC)
-       rmrMessengerMock.On("SendMsg", ranRestartedMbuf).Return(&rmrCgo.MBuf{}, err)
+       rmrMessengerMock.On("SendMsg", ranRestartedMbuf, true).Return(&rmrCgo.MBuf{}, err)
        h.Handle(notificationRequest)
        h.Handle(notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", resetResponseMbuf)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", ranRestartedMbuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", resetResponseMbuf, true)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", ranRestartedMbuf, true)
 }
 
 func TestHandleX2ResetRequestNotificationShuttingDownStatus(t *testing.T) {
        h, readerMock, rmrMessengerMock := initX2ResetRequestNotificationHandlerTest(t)
        var payload []byte
 
 }
 
 func TestHandleX2ResetRequestNotificationShuttingDownStatus(t *testing.T) {
        h, readerMock, rmrMessengerMock := initX2ResetRequestNotificationHandlerTest(t)
        var payload []byte
 
-       xaction := []byte("RanName")
-       mBuf := rmrCgo.NewMBuf(tests.MessageType, len(payload), "RanName", &payload, &xaction)
+       xAction := []byte("123456aa")
+       mBuf := rmrCgo.NewMBuf(tests.MessageType, len(payload), "RanName", &payload, &xAction)
        notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload,
        notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload,
-               StartTime: time.Now(), TransactionId: string(xaction)}
+               StartTime: time.Now(), TransactionId: xAction}
 
        nb := &entities.NodebInfo{RanName: mBuf.Meid, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
        var rnibErr error
 
        nb := &entities.NodebInfo{RanName: mBuf.Meid, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
        var rnibErr error
@@ -100,9 +97,9 @@ func TestHandleX2ResetRequestNotificationShuttingDownStatus(t *testing.T) {
 func TestHandleX2ResetRequestNotificationDisconnectStatus(t *testing.T) {
        h, readerMock, rmrMessengerMock := initX2ResetRequestNotificationHandlerTest(t)
        var payload []byte
 func TestHandleX2ResetRequestNotificationDisconnectStatus(t *testing.T) {
        h, readerMock, rmrMessengerMock := initX2ResetRequestNotificationHandlerTest(t)
        var payload []byte
-       xaction := []byte("RanName")
-       mBuf := rmrCgo.NewMBuf(tests.MessageType, len(payload), "RanName", &payload, &xaction)
-       notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload, StartTime: time.Now(), TransactionId: string(xaction)}
+       xAction := []byte("123456aa")
+       mBuf := rmrCgo.NewMBuf(tests.MessageType, len(payload), "RanName", &payload, &xAction)
+       notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload, StartTime: time.Now(), TransactionId: xAction}
        nb := &entities.NodebInfo{RanName: mBuf.Meid, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,}
        var rnibErr error
        readerMock.On("GetNodeb", mBuf.Meid).Return(nb, rnibErr)
        nb := &entities.NodebInfo{RanName: mBuf.Meid, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,}
        var rnibErr error
        readerMock.On("GetNodeb", mBuf.Meid).Return(nb, rnibErr)
@@ -115,10 +112,10 @@ func TestHandleX2ResetRequestNotificationGetNodebFailed(t *testing.T) {
 
         h, readerMock, rmrMessengerMock := initX2ResetRequestNotificationHandlerTest(t)
        var payload []byte
 
         h, readerMock, rmrMessengerMock := initX2ResetRequestNotificationHandlerTest(t)
        var payload []byte
-       xaction := []byte("RanName")
-       mBuf := rmrCgo.NewMBuf(tests.MessageType, len(payload), "RanName", &payload, &xaction)
+       var xAction []byte
+       mBuf := rmrCgo.NewMBuf(tests.MessageType, len(payload), "RanName", &payload, &xAction)
        notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload,
        notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload,
-               StartTime: time.Now(), TransactionId: string(xaction)}
+               StartTime: time.Now(), TransactionId: xAction}
 
        var nb *entities.NodebInfo
        rnibErr := &common.ResourceNotFoundError{}
 
        var nb *entities.NodebInfo
        rnibErr := &common.ResourceNotFoundError{}
index 2c26b43..1097ed2 100644 (file)
@@ -56,7 +56,7 @@ func (h X2ResetResponseHandler) Handle(request *models.NotificationRequest) {
        ranName := request.RanName
        h.logger.Infof("#X2ResetResponseHandler.Handle - RAN name: %s - received reset response. Payload: %x", ranName, request.Payload)
 
        ranName := request.RanName
        h.logger.Infof("#X2ResetResponseHandler.Handle - RAN name: %s - received reset response. Payload: %x", ranName, request.Payload)
 
-       nodebInfo, err := h.rnibDataService.GetNodeb(ranName);
+       nodebInfo, err := h.rnibDataService.GetNodeb(ranName)
        if err != nil {
                h.logger.Errorf("#x2ResetResponseHandler.Handle - RAN name: %s - failed to retrieve nodebInfo entity. Error: %s", ranName, err)
                return
        if err != nil {
                h.logger.Errorf("#x2ResetResponseHandler.Handle - RAN name: %s - failed to retrieve nodebInfo entity. Error: %s", ranName, err)
                return
index 2ff6094..7a99903 100644 (file)
@@ -33,7 +33,6 @@ import (
        "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"
        "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"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "testing"
        "time"
 )
        "testing"
        "time"
 )
@@ -51,11 +50,8 @@ func initX2ResetResponseHandlerTest(t *testing.T) (X2ResetResponseHandler, *mock
                t.Errorf("#initX2ResetResponseHandlerTest - failed to initialize logger, error: %s", err)
        }
        readerMock := &mocks.RnibReaderMock{}
                t.Errorf("#initX2ResetResponseHandlerTest - failed to initialize logger, error: %s", err)
        }
        readerMock := &mocks.RnibReaderMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
 
 
-       rnibDataService := services.NewRnibDataService(log, config, rnibReaderProvider, nil)
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, nil)
 
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        rmrSender := initRmrSender(rmrMessengerMock, log)
 
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        rmrSender := initRmrSender(rmrMessengerMock, log)
@@ -73,15 +69,15 @@ func TestX2ResetResponseSuccess(t *testing.T) {
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
-       xaction := []byte(RanName)
-       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: string(xaction)}
+       var xAction []byte
+       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: xAction}
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
        ranRestartedMbuf := getRanRestartedMbuf(nb.NodeType, enums.RIC_TO_RAN)
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
        ranRestartedMbuf := getRanRestartedMbuf(nb.NodeType, enums.RIC_TO_RAN)
-       rmrMessengerMock.On("SendMsg", ranRestartedMbuf).Return(&rmrCgo.MBuf{}, err)
+       rmrMessengerMock.On("SendMsg", ranRestartedMbuf, true).Return(&rmrCgo.MBuf{}, err)
        h.Handle(&notificationRequest)
        h.Handle(&notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", ranRestartedMbuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", ranRestartedMbuf, true)
 }
 
 func TestX2ResetResponseSuccessEmptyIEs(t *testing.T) {
 }
 
 func TestX2ResetResponseSuccessEmptyIEs(t *testing.T) {
@@ -92,15 +88,15 @@ func TestX2ResetResponseSuccessEmptyIEs(t *testing.T) {
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
-       xaction := []byte(RanName)
-       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: string(xaction)}
+       var xAction []byte
+       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: xAction}
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
        ranRestartedMbuf := getRanRestartedMbuf(nb.NodeType, enums.RIC_TO_RAN)
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
        ranRestartedMbuf := getRanRestartedMbuf(nb.NodeType, enums.RIC_TO_RAN)
-       rmrMessengerMock.On("SendMsg", ranRestartedMbuf).Return(&rmrCgo.MBuf{}, err)
+       rmrMessengerMock.On("SendMsg", ranRestartedMbuf, true).Return(&rmrCgo.MBuf{}, err)
        h.Handle(&notificationRequest)
        h.Handle(&notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", ranRestartedMbuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", ranRestartedMbuf, true)
 }
 
 func TestX2ResetResponseShuttingDown(t *testing.T) {
 }
 
 func TestX2ResetResponseShuttingDown(t *testing.T) {
@@ -111,8 +107,8 @@ func TestX2ResetResponseShuttingDown(t *testing.T) {
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
-       xaction := []byte(RanName)
-       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: string(xaction)}
+       var xAction []byte
+       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: xAction}
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
@@ -128,8 +124,8 @@ func TestX2ResetResponseInvalidConnectionStatus(t *testing.T) {
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
-       xaction := []byte(RanName)
-       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: string(xaction)}
+       var xAction []byte
+       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: xAction}
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
@@ -145,8 +141,8 @@ func TestX2ResetResponseError(t *testing.T) {
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
-       xaction := []byte(RanName)
-       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: string(xaction)}
+       var xAction []byte
+       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: xAction}
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
@@ -163,8 +159,8 @@ func TestX2ResetResponseGetNodebFailure(t *testing.T) {
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
                t.Fatalf("Failed converting packed pdu. Error: %v\n", err)
        }
 
-       xaction := []byte(RanName)
-       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: string(xaction)}
+       var xAction []byte
+       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: xAction}
 
        var nb *entities.NodebInfo
        rnibErr := common.NewResourceNotFoundError("nodeb not found")
 
        var nb *entities.NodebInfo
        rnibErr := common.NewResourceNotFoundError("nodeb not found")
@@ -178,8 +174,8 @@ func TestX2ResetResponseUnpackFailure(t *testing.T) {
        h, readerMock, rmrMessengerMock := initX2ResetResponseHandlerTest(t)
 
        payload := []byte("Invalid payload")
        h, readerMock, rmrMessengerMock := initX2ResetResponseHandlerTest(t)
 
        payload := []byte("Invalid payload")
-       xaction := []byte(RanName)
-       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: string(xaction)}
+       var xAction []byte
+       notificationRequest := models.NotificationRequest{RanName: RanName, Len: len(payload), Payload: payload, StartTime: time.Now(), TransactionId: xAction}
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
        nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_ENB}
        var rnibErr error
        readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
index d33f784..591acff 100644 (file)
@@ -32,7 +32,7 @@ import (
        "e2mgr/models"
        "e2mgr/rmrCgo"
        "e2mgr/services/rmrsender"
        "e2mgr/models"
        "e2mgr/rmrCgo"
        "e2mgr/services/rmrsender"
-       "unsafe"
+       "e2mgr/utils"
 )
 
 type X2EnbConfigurationUpdateHandler struct {
 )
 
 type X2EnbConfigurationUpdateHandler struct {
@@ -49,40 +49,23 @@ func NewX2EnbConfigurationUpdateHandler(logger *logger.Logger, rmrSender *rmrsen
 
 func (h X2EnbConfigurationUpdateHandler) Handle(request *models.NotificationRequest) {
 
 
 func (h X2EnbConfigurationUpdateHandler) Handle(request *models.NotificationRequest) {
 
-       var payloadSize C.ulong
-       payloadSize = e2pdus.MaxAsn1PackedBufferSize
-       packedBuffer := [e2pdus.MaxAsn1PackedBufferSize]C.uchar{}
-       errorBuffer := [e2pdus.MaxAsn1PackedBufferSize]C.char{}
-
        refinedMessage, err := converters.UnpackX2apPduAndRefine(h.logger, e2pdus.MaxAsn1CodecAllocationBufferSize, request.Len, request.Payload, e2pdus.MaxAsn1CodecMessageBufferSize)
 
        if err != nil {
        refinedMessage, err := converters.UnpackX2apPduAndRefine(h.logger, e2pdus.MaxAsn1CodecAllocationBufferSize, request.Len, request.Payload, e2pdus.MaxAsn1CodecMessageBufferSize)
 
        if err != nil {
-               status := C.build_pack_x2enb_configuration_update_failure(&payloadSize, &packedBuffer[0], e2pdus.MaxAsn1PackedBufferSize, &errorBuffer[0])
-               if status {
-                       payload := (*[1 << 30]byte)(unsafe.Pointer(&packedBuffer))[:payloadSize:payloadSize]
-                       h.logger.Debugf("#x2enb_configuration_update_handler.Handle - Enb configuration update negative ack message payload: (%d) %02x", len(payload), payload)
-                       msg := models.NewRmrMessage(rmrCgo.RIC_ENB_CONFIGURATION_UPDATE_FAILURE, request.RanName, payload)
-                       _ = h.rmrSender.Send(msg)
-               } else {
-                       h.logger.Errorf("#x2enb_configuration_update_handler.Handle - failed to build and pack Enb configuration update unsuccessful outcome message. Error: %v", errorBuffer)
-               }
                h.logger.Errorf("#x2enb_configuration_update_handler.Handle - unpack failed. Error: %v", err)
 
                h.logger.Errorf("#x2enb_configuration_update_handler.Handle - unpack failed. Error: %v", err)
 
-               printHandlingSetupResponseElapsedTimeInMs(h.logger, "#x2enb_configuration_update_handler.Handle - Summary: Elapsed time for receiving and handling enb configuration update initiating message from E2 terminator", request.StartTime)
+               msg := models.NewRmrMessage(rmrCgo.RIC_ENB_CONFIGURATION_UPDATE_FAILURE, request.RanName, e2pdus.PackedX2EnbConfigurationUpdateFailure, request.TransactionId)
+               _ = h.rmrSender.Send(msg)
+
+               h.logger.Infof("#X2EnbConfigurationUpdateHandler.Handle - Summary: elapsed time for receiving and handling enb configuration update initiating message from E2 terminator: %f ms", utils.ElapsedTime(request.StartTime))
                return
        }
 
        h.logger.Infof("#x2enb_configuration_update_handler.Handle - Enb configuration update initiating message received")
        h.logger.Debugf("#x2enb_configuration_update_handler.Handle - Enb configuration update initiating message payload: %s", refinedMessage.PduPrint)
 
                return
        }
 
        h.logger.Infof("#x2enb_configuration_update_handler.Handle - Enb configuration update initiating message received")
        h.logger.Debugf("#x2enb_configuration_update_handler.Handle - Enb configuration update initiating message payload: %s", refinedMessage.PduPrint)
 
-       status := C.build_pack_x2enb_configuration_update_ack(&payloadSize, &packedBuffer[0], e2pdus.MaxAsn1PackedBufferSize, &errorBuffer[0])
-       if status {
-               payload := (*[1 << 30]byte)(unsafe.Pointer(&packedBuffer))[:payloadSize:payloadSize]
-               h.logger.Debugf("#x2enb_configuration_update_handler.Handle - Enb configuration update positive ack message payload: (%d) %02x", len(payload), payload)
-               msg := models.NewRmrMessage(rmrCgo.RIC_ENB_CONFIGURATION_UPDATE_ACK, request.RanName, payload)
-               _ = h.rmrSender.Send(msg)
-       } else {
-               h.logger.Errorf("#x2enb_configuration_update_handler.Handle - failed to build and pack enb configuration update successful outcome message. Error: %v", errorBuffer)
-       }
-       printHandlingSetupResponseElapsedTimeInMs(h.logger, "#x2enb_configuration_update_handler.Handle - Summary: Elapsed time for receiving and handling enb configuration update initiating message from E2 terminator", request.StartTime)
+       msg := models.NewRmrMessage(rmrCgo.RIC_ENB_CONFIGURATION_UPDATE_ACK, request.RanName, e2pdus.PackedX2EnbConfigurationUpdateAck,request.TransactionId)
+       _ = h.rmrSender.Send(msg)
+
+       h.logger.Infof("#X2EnbConfigurationUpdateHandler.Handle - Summary: elapsed time for receiving and handling enb configuration update initiating message from E2 terminator: %f ms", utils.ElapsedTime(request.StartTime))
 }
 }
index 60a3a96..c29d21b 100644 (file)
@@ -43,31 +43,32 @@ func TestHandleX2EnbConfigUpdateSuccess(t *testing.T) {
        h, rmrMessengerMock := initX2EnbConfigurationUpdateHandlerTest(t)
 
        ranName := "test"
        h, rmrMessengerMock := initX2EnbConfigurationUpdateHandlerTest(t)
 
        ranName := "test"
-       xaction := []byte(ranName)
-
+       xAction := []byte("123456aa")
        var payload []byte
        _, _ = fmt.Sscanf(PackedX2EnbConfigurationUpdateAck, "%x", &payload)
 
        var payload []byte
        _, _ = fmt.Sscanf(PackedX2EnbConfigurationUpdateAck, "%x", &payload)
 
-       mBuf := rmrCgo.NewMBuf(rmrCgo.RIC_ENB_CONFIGURATION_UPDATE_ACK, len(payload), ranName, &payload, &xaction)
-       notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload, StartTime: time.Now()}
+       mBuf := rmrCgo.NewMBuf(rmrCgo.RIC_ENB_CONFIGURATION_UPDATE_ACK, len(payload), ranName, &payload, &xAction)
+       notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload,
+               StartTime: time.Now(), TransactionId:xAction}
        var err error
        var err error
-       rmrMessengerMock.On("SendMsg", mBuf).Return(&rmrCgo.MBuf{}, err)
+       rmrMessengerMock.On("SendMsg", mBuf, true).Return(&rmrCgo.MBuf{}, err)
        h.Handle(&notificationRequest)
        h.Handle(&notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf, true)
 }
 
 func TestHandleX2EnbConfigUpdateFailure(t *testing.T) {
        h, rmrMessengerMock := initX2EnbConfigurationUpdateHandlerTest(t)
 
        ranName := "test"
 }
 
 func TestHandleX2EnbConfigUpdateFailure(t *testing.T) {
        h, rmrMessengerMock := initX2EnbConfigurationUpdateHandlerTest(t)
 
        ranName := "test"
-       xaction := []byte(ranName)
+       xAction := []byte("123456aa")
 
        var payload []byte
        _, _ = fmt.Sscanf(PackedX2EnbConfigurationUpdateFailure, "%x", &payload)
 
 
        var payload []byte
        _, _ = fmt.Sscanf(PackedX2EnbConfigurationUpdateFailure, "%x", &payload)
 
-       mBuf := rmrCgo.NewMBuf(rmrCgo.RIC_ENB_CONFIGURATION_UPDATE_FAILURE, len(payload), ranName, &payload, &xaction)
-       notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: 0, Payload: []byte{0}, StartTime: time.Now()}
-       rmrMessengerMock.On("SendMsg", mBuf).Return(&rmrCgo.MBuf{}, fmt.Errorf("send failure"))
+       mBuf := rmrCgo.NewMBuf(rmrCgo.RIC_ENB_CONFIGURATION_UPDATE_FAILURE, len(payload), ranName, &payload, &xAction)
+       notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: 0, Payload: []byte{0},
+               StartTime: time.Now(), TransactionId:xAction}
+       rmrMessengerMock.On("SendMsg", mBuf, true).Return(&rmrCgo.MBuf{}, fmt.Errorf("send failure"))
        h.Handle(&notificationRequest)
        h.Handle(&notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf, true)
 }
 }
index 1c087bd..608110f 100644 (file)
@@ -22,27 +22,26 @@ package httpserver
 
 import (
        "e2mgr/controllers"
 
 import (
        "e2mgr/controllers"
+       "e2mgr/logger"
        "fmt"
        "github.com/gorilla/mux"
        "fmt"
        "github.com/gorilla/mux"
-       "log"
        "net/http"
 )
 
        "net/http"
 )
 
-func Run(port int, controller controllers.IRootController, newController controllers.INodebController) {
+func Run(log *logger.Logger, port int, rootController controllers.IRootController, nodebController controllers.INodebController, e2tController controllers.IE2TController) error {
 
        router := mux.NewRouter();
 
        router := mux.NewRouter();
-       initializeRoutes(router, controller, newController)
+       initializeRoutes(router, rootController, nodebController, e2tController)
 
        addr := fmt.Sprintf(":%d", port)
 
        err := http.ListenAndServe(addr, router)
 
 
        addr := fmt.Sprintf(":%d", port)
 
        err := http.ListenAndServe(addr, router)
 
-       if err != nil {
-               log.Fatalf("#http_server.Run - Fail initiating HTTP server. Error: %v", err)
-       }
+       log.Errorf("#http_server.Run - Fail initiating HTTP server. Error: %v", err)
+       return err
 }
 
 }
 
-func initializeRoutes(router *mux.Router, rootController controllers.IRootController, nodebController controllers.INodebController) {
+func initializeRoutes(router *mux.Router, rootController controllers.IRootController, nodebController controllers.INodebController, e2tController controllers.IE2TController) {
        r := router.PathPrefix("/v1").Subrouter()
        r.HandleFunc("/health", rootController.HandleHealthCheckRequest).Methods("GET")
 
        r := router.PathPrefix("/v1").Subrouter()
        r.HandleFunc("/health", rootController.HandleHealthCheckRequest).Methods("GET")
 
@@ -53,4 +52,7 @@ func initializeRoutes(router *mux.Router, rootController controllers.IRootContro
        rr.HandleFunc("/{ranName}/reset", nodebController.X2Reset).Methods("PUT")
        rr.HandleFunc("/x2-setup", nodebController.X2Setup).Methods("POST")
        rr.HandleFunc("/endc-setup", nodebController.EndcSetup).Methods("POST")
        rr.HandleFunc("/{ranName}/reset", nodebController.X2Reset).Methods("PUT")
        rr.HandleFunc("/x2-setup", nodebController.X2Setup).Methods("POST")
        rr.HandleFunc("/endc-setup", nodebController.EndcSetup).Methods("POST")
+
+       rrr := r.PathPrefix("/e2t").Subrouter()
+       rrr.HandleFunc("/list", e2tController.GetE2TInstances).Methods("GET")
 }
 }
index c841681..e6e1ef5 100644 (file)
 package httpserver
 
 import (
 package httpserver
 
 import (
+       "e2mgr/logger"
        "e2mgr/mocks"
        "github.com/gorilla/mux"
        "github.com/stretchr/testify/assert"
        "net/http"
        "net/http/httptest"
        "testing"
        "e2mgr/mocks"
        "github.com/gorilla/mux"
        "github.com/stretchr/testify/assert"
        "net/http"
        "net/http/httptest"
        "testing"
+       "time"
 )
 
 )
 
-func setupRouterAndMocks() (*mux.Router, *mocks.ControllerMock, *mocks.NodebControllerMock) {
-       controllerMock := &mocks.ControllerMock{}
-       controllerMock.On("Shutdown").Return(nil)
-       controllerMock.On("X2Reset").Return(nil)
-       controllerMock.On("X2Setup").Return(nil)
-       controllerMock.On("EndcSetup").Return(nil)
-       controllerMock.On("GetNodeb").Return(nil)
-       controllerMock.On("GetNodebIdList").Return(nil)
-
-
+func setupRouterAndMocks() (*mux.Router, *mocks.RootControllerMock, *mocks.NodebControllerMock, *mocks.E2TControllerMock) {
+       rootControllerMock := &mocks.RootControllerMock{}
+       rootControllerMock.On("HandleHealthCheckRequest").Return(nil)
 
        nodebControllerMock := &mocks.NodebControllerMock{}
 
        nodebControllerMock := &mocks.NodebControllerMock{}
+       nodebControllerMock.On("Shutdown").Return(nil)
+       nodebControllerMock.On("X2Reset").Return(nil)
+       nodebControllerMock.On("X2Setup").Return(nil)
+       nodebControllerMock.On("EndcSetup").Return(nil)
+       nodebControllerMock.On("GetNodeb").Return(nil)
        nodebControllerMock.On("GetNodebIdList").Return(nil)
        nodebControllerMock.On("GetNodebIdList").Return(nil)
-       nodebControllerMock.On("GetNodeb").Return(nil) // TODO: remove
-       nodebControllerMock.On("HandleHealthCheckRequest").Return(nil)
+
+       e2tControllerMock := &mocks.E2TControllerMock{}
+
+       e2tControllerMock.On("GetE2TInstances").Return(nil)
 
        router := mux.NewRouter()
 
        router := mux.NewRouter()
-       initializeRoutes(router, nodebControllerMock, controllerMock)
-       return router, controllerMock, nodebControllerMock
+       initializeRoutes(router, rootControllerMock, nodebControllerMock, e2tControllerMock)
+       return router, rootControllerMock, nodebControllerMock, e2tControllerMock
 }
 
 func TestRoutePostEndcSetup(t *testing.T) {
 }
 
 func TestRoutePostEndcSetup(t *testing.T) {
-       router, controllerMock, _ := setupRouterAndMocks()
+       router, _, nodebControllerMock, _ := setupRouterAndMocks()
 
        req, err := http.NewRequest("POST", "/v1/nodeb/endc-setup", nil)
        if err != nil {
 
        req, err := http.NewRequest("POST", "/v1/nodeb/endc-setup", nil)
        if err != nil {
@@ -60,11 +62,11 @@ func TestRoutePostEndcSetup(t *testing.T) {
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
-       controllerMock.AssertNumberOfCalls(t,"EndcSetup", 1)
+       nodebControllerMock.AssertNumberOfCalls(t, "EndcSetup", 1)
 }
 
 func TestRoutePostX2Setup(t *testing.T) {
 }
 
 func TestRoutePostX2Setup(t *testing.T) {
-       router, controllerMock, _ := setupRouterAndMocks()
+       router, _, nodebControllerMock, _ := setupRouterAndMocks()
 
        req, err := http.NewRequest("POST", "/v1/nodeb/x2-setup", nil)
        if err != nil {
 
        req, err := http.NewRequest("POST", "/v1/nodeb/x2-setup", nil)
        if err != nil {
@@ -73,11 +75,11 @@ func TestRoutePostX2Setup(t *testing.T) {
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
-       controllerMock.AssertNumberOfCalls(t,"X2Setup", 1)
+       nodebControllerMock.AssertNumberOfCalls(t, "X2Setup", 1)
 }
 
 func TestRouteGetNodebIds(t *testing.T) {
 }
 
 func TestRouteGetNodebIds(t *testing.T) {
-       router, controllerMock, _ := setupRouterAndMocks()
+       router, _, nodebControllerMock, _ := setupRouterAndMocks()
 
        req, err := http.NewRequest("GET", "/v1/nodeb/ids", nil)
        if err != nil {
 
        req, err := http.NewRequest("GET", "/v1/nodeb/ids", nil)
        if err != nil {
@@ -86,11 +88,11 @@ func TestRouteGetNodebIds(t *testing.T) {
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
-       controllerMock.AssertNumberOfCalls(t, "GetNodebIdList", 1)
+       nodebControllerMock.AssertNumberOfCalls(t, "GetNodebIdList", 1)
 }
 
 func TestRouteGetNodebRanName(t *testing.T) {
 }
 
 func TestRouteGetNodebRanName(t *testing.T) {
-       router, controllerMock,_ := setupRouterAndMocks()
+       router, _, nodebControllerMock, _ := setupRouterAndMocks()
 
        req, err := http.NewRequest("GET", "/v1/nodeb/ran1", nil)
        if err != nil {
 
        req, err := http.NewRequest("GET", "/v1/nodeb/ran1", nil)
        if err != nil {
@@ -101,11 +103,11 @@ func TestRouteGetNodebRanName(t *testing.T) {
 
        assert.Equal(t, http.StatusOK, rr.Code, "handler returned wrong status code")
        assert.Equal(t, "ran1", rr.Body.String(), "handler returned wrong body")
 
        assert.Equal(t, http.StatusOK, rr.Code, "handler returned wrong status code")
        assert.Equal(t, "ran1", rr.Body.String(), "handler returned wrong body")
-       controllerMock.AssertNumberOfCalls(t, "GetNodeb", 1)
+       nodebControllerMock.AssertNumberOfCalls(t, "GetNodeb", 1)
 }
 
 func TestRouteGetHealth(t *testing.T) {
 }
 
 func TestRouteGetHealth(t *testing.T) {
-       router, _, nodebControllerMock := setupRouterAndMocks()
+       router, rootControllerMock, _, _ := setupRouterAndMocks()
 
        req, err := http.NewRequest("GET", "/v1/health", nil)
        if err != nil {
 
        req, err := http.NewRequest("GET", "/v1/health", nil)
        if err != nil {
@@ -114,11 +116,11 @@ func TestRouteGetHealth(t *testing.T) {
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
-       nodebControllerMock.AssertNumberOfCalls(t, "HandleHealthCheckRequest", 1)
+       rootControllerMock.AssertNumberOfCalls(t, "HandleHealthCheckRequest", 1)
 }
 
 func TestRoutePutNodebShutdown(t *testing.T) {
 }
 
 func TestRoutePutNodebShutdown(t *testing.T) {
-       router, controllerMock, _ := setupRouterAndMocks()
+       router, _, nodebControllerMock, _ := setupRouterAndMocks()
 
        req, err := http.NewRequest("PUT", "/v1/nodeb/shutdown", nil)
        if err != nil {
 
        req, err := http.NewRequest("PUT", "/v1/nodeb/shutdown", nil)
        if err != nil {
@@ -127,11 +129,11 @@ func TestRoutePutNodebShutdown(t *testing.T) {
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
        rr := httptest.NewRecorder()
        router.ServeHTTP(rr, req)
 
-       controllerMock.AssertNumberOfCalls(t, "Shutdown", 1)
+       nodebControllerMock.AssertNumberOfCalls(t, "Shutdown", 1)
 }
 
 func TestRoutePutNodebResetRanName(t *testing.T) {
 }
 
 func TestRoutePutNodebResetRanName(t *testing.T) {
-       router, controllerMock, _ := setupRouterAndMocks()
+       router, _, nodebControllerMock, _ := setupRouterAndMocks()
 
        req, err := http.NewRequest("PUT", "/v1/nodeb/ran1/reset", nil)
        if err != nil {
 
        req, err := http.NewRequest("PUT", "/v1/nodeb/ran1/reset", nil)
        if err != nil {
@@ -142,11 +144,11 @@ func TestRoutePutNodebResetRanName(t *testing.T) {
 
        assert.Equal(t, http.StatusOK, rr.Code, "handler returned wrong status code")
        assert.Equal(t, "ran1", rr.Body.String(), "handler returned wrong body")
 
        assert.Equal(t, http.StatusOK, rr.Code, "handler returned wrong status code")
        assert.Equal(t, "ran1", rr.Body.String(), "handler returned wrong body")
-       controllerMock.AssertNumberOfCalls(t, "X2Reset", 1)
+       nodebControllerMock.AssertNumberOfCalls(t, "X2Reset", 1)
 }
 
 func TestRouteNotFound(t *testing.T) {
 }
 
 func TestRouteNotFound(t *testing.T) {
-       router, _, _ := setupRouterAndMocks()
+       router, _, _,_ := setupRouterAndMocks()
 
        req, err := http.NewRequest("GET", "/v1/no/such/route", nil)
        if err != nil {
 
        req, err := http.NewRequest("GET", "/v1/no/such/route", nil)
        if err != nil {
@@ -156,4 +158,31 @@ func TestRouteNotFound(t *testing.T) {
        router.ServeHTTP(rr, req)
 
        assert.Equal(t, http.StatusNotFound, rr.Code, "handler returned wrong status code")
        router.ServeHTTP(rr, req)
 
        assert.Equal(t, http.StatusNotFound, rr.Code, "handler returned wrong status code")
-}
\ No newline at end of file
+}
+
+func TestRunError(t *testing.T) {
+       log := initLog(t)
+       err := Run(log, 1234567, &mocks.RootControllerMock{}, &mocks.NodebControllerMock{}, &mocks.E2TControllerMock{})
+       assert.NotNil(t, err)
+}
+
+func TestRun(t *testing.T) {
+       log := initLog(t)
+       _, rootControllerMock, nodebControllerMock, e2tControllerMock := setupRouterAndMocks()
+       go Run(log, 11223, rootControllerMock, nodebControllerMock, e2tControllerMock)
+
+       time.Sleep(time.Millisecond * 100)
+       resp, err := http.Get("http://localhost:11223/v1/health")
+       if err != nil {
+               t.Fatalf("failed to perform GET to http://localhost:11223/v1/health")
+       }
+       assert.Equal(t, 200, resp.StatusCode)
+}
+
+func initLog(t *testing.T) *logger.Logger {
+       log, err := logger.InitLogger(logger.InfoLevel)
+       if err != nil {
+               t.Errorf("#initLog test - failed to initialize logger, error: %s", err)
+       }
+       return log
+}
index 9921ce1..d1d00d2 100644 (file)
@@ -44,6 +44,34 @@ func TestInitInfoLoggerSuccess(t *testing.T) {
        assert.True(t, log.Logger.Core().Enabled(zap.InfoLevel))
 }
 
        assert.True(t, log.Logger.Core().Enabled(zap.InfoLevel))
 }
 
+func TestInitWarnLoggerSuccess(t *testing.T) {
+       log, err := InitLogger(WarnLevel)
+       assert.Nil(t, err)
+       assert.NotNil(t, log)
+       assert.True(t, log.Logger.Core().Enabled(zap.WarnLevel))
+}
+
+func TestInitErrorLoggerSuccess(t *testing.T) {
+       log, err := InitLogger(ErrorLevel)
+       assert.Nil(t, err)
+       assert.NotNil(t, log)
+       assert.True(t, log.Logger.Core().Enabled(zap.ErrorLevel))
+}
+
+func TestInitDPanicLoggerSuccess(t *testing.T) {
+       log, err := InitLogger(DPanicLevel)
+       assert.Nil(t, err)
+       assert.NotNil(t, log)
+       assert.True(t, log.Logger.Core().Enabled(zap.DPanicLevel))
+}
+
+func TestInitPanicLoggerSuccess(t *testing.T) {
+       log, err := InitLogger(PanicLevel)
+       assert.Nil(t, err)
+       assert.NotNil(t, log)
+       assert.True(t, log.Logger.Core().Enabled(zap.PanicLevel))
+}
+
 func TestInitInfoLoggerFailure(t *testing.T) {
        log, err := InitLogger(99)
        assert.NotNil(t, err)
 func TestInitInfoLoggerFailure(t *testing.T) {
        log, err := InitLogger(99)
        assert.NotNil(t, err)
@@ -63,7 +91,7 @@ func TestSyncSuccess(t *testing.T){
        }
        err = log.Sync()
        assert.Nil(t, err)
        }
        err = log.Sync()
        assert.Nil(t, err)
-       
+
        os.Stdout = old
        logFile, err = os.Open("./loggerTest.txt")
        if err != nil{
        os.Stdout = old
        logFile, err = os.Open("./loggerTest.txt")
        if err != nil{
@@ -144,6 +172,22 @@ func TestDebugfFatalLevel(t *testing.T)  {
        assert.False(t,validateRecordExists(FatalLevel, zap.DebugLevel, t))
 }
 
        assert.False(t,validateRecordExists(FatalLevel, zap.DebugLevel, t))
 }
 
+func TestWarnfWarnLevel(t *testing.T)  {
+       assert.True(t,validateRecordExists(WarnLevel, zap.WarnLevel, t))
+}
+
+func TestWarnfDebugLevel(t *testing.T)  {
+       assert.True(t,validateRecordExists(DebugLevel, zap.WarnLevel, t))
+}
+
+func TestWarnfInfoLevel(t *testing.T)  {
+       assert.True(t,validateRecordExists(InfoLevel, zap.WarnLevel, t))
+}
+
+func TestWarnfFatalLevel(t *testing.T)  {
+       assert.False(t,validateRecordExists(FatalLevel, zap.WarnLevel, t))
+}
+
 func TestLogLevelTokenToLevel(t *testing.T) {
        level, ok := LogLevelTokenToLevel("deBug")
        assert.True(t, ok)
 func TestLogLevelTokenToLevel(t *testing.T) {
        level, ok := LogLevelTokenToLevel("deBug")
        assert.True(t, ok)
@@ -218,14 +262,16 @@ func validateRecordExists(logLevel LogLevel, recordLevel zapcore.Level, t *testi
                t.Errorf("logger_test.TestSyncFailure - failed to initialize logger, error: %s", err)
        }
        switch recordLevel{
                t.Errorf("logger_test.TestSyncFailure - failed to initialize logger, error: %s", err)
        }
        switch recordLevel{
-               case  zap.DebugLevel:
-                       log.Debugf("%v, %v, %v", 1, "abc", 0.1)
-               case zap.InfoLevel:
-                       log.Infof("%v, %v, %v", 1, "abc", 0.1)
-               case zap.ErrorLevel:
-                       log.Errorf("%v, %v, %v", 1, "abc", 0.1)
-               case zap.DPanicLevel:
-                       log.DPanicf("%v, %v, %v", 1, "abc", 0.1)
+       case  zap.DebugLevel:
+               log.Debugf("%v, %v, %v", 1, "abc", 0.1)
+       case zap.InfoLevel:
+               log.Infof("%v, %v, %v", 1, "abc", 0.1)
+       case zap.WarnLevel:
+               log.Warnf("%v, %v, %v", 1, "abc", 0.1)
+       case zap.ErrorLevel:
+               log.Errorf("%v, %v, %v", 1, "abc", 0.1)
+       case zap.DPanicLevel:
+               log.DPanicf("%v, %v, %v", 1, "abc", 0.1)
        }
        err = w.Close()
        if err != nil {
        }
        err = w.Close()
        if err != nil {
@@ -244,4 +290,4 @@ func validateRecordExists(logLevel LogLevel, recordLevel zapcore.Level, t *testi
                s,_= buf.ReadString('\n')
        }
        return entryNum == 1
                s,_= buf.ReadString('\n')
        }
        return entryNum == 1
-}
+}
\ No newline at end of file
diff --git a/E2Manager/managers/e2t_instances_manager.go b/E2Manager/managers/e2t_instances_manager.go
new file mode 100644 (file)
index 0000000..74f6a51
--- /dev/null
@@ -0,0 +1,359 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package managers
+
+import (
+       "e2mgr/e2managererrors"
+       "e2mgr/logger"
+       "e2mgr/services"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "math"
+       "sync"
+       "time"
+)
+
+type E2TInstancesManager struct {
+       rnibDataService services.RNibDataService
+       logger          *logger.Logger
+       mux             sync.Mutex
+}
+
+type IE2TInstancesManager interface {
+       GetE2TInstance(e2tAddress string) (*entities.E2TInstance, error)
+       GetE2TInstances() ([]*entities.E2TInstance, error)
+       GetE2TInstancesNoLogs() ([]*entities.E2TInstance, error)
+       AddE2TInstance(e2tAddress string) error
+       RemoveE2TInstance(e2tInstance *entities.E2TInstance) error
+       SelectE2TInstance() (string, error)
+       AssociateRan(ranName string, e2tAddress string) error
+       DissociateRan(ranName string, e2tAddress string) error
+       ActivateE2TInstance(e2tInstance *entities.E2TInstance) error
+       ResetKeepAliveTimestamp(e2tAddress string) error
+}
+
+func NewE2TInstancesManager(rnibDataService services.RNibDataService, logger *logger.Logger) *E2TInstancesManager {
+       return &E2TInstancesManager{
+               rnibDataService: rnibDataService,
+               logger:          logger,
+       }
+}
+
+func (m *E2TInstancesManager) GetE2TInstance(e2tAddress string) (*entities.E2TInstance, error) {
+       e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
+
+       if err != nil {
+
+               _, ok := err.(*common.ResourceNotFoundError)
+
+               if !ok {
+                       m.logger.Errorf("#E2TInstancesManager.GetE2TInstance - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
+               } else {
+                       m.logger.Infof("#E2TInstancesManager.GetE2TInstance - E2T Instance address: %s not found on DB", e2tAddress)
+               }
+       }
+
+       return e2tInstance, err
+}
+
+func (m *E2TInstancesManager) GetE2TInstancesNoLogs() ([]*entities.E2TInstance, error) {
+       e2tAddresses, err := m.rnibDataService.GetE2TAddressesNoLogs()
+
+       if err != nil {
+               _, ok := err.(*common.ResourceNotFoundError)
+
+               if !ok {
+                       m.logger.Errorf("#E2TInstancesManager.GetE2TInstancesNoLogs - Failed retrieving E2T addresses. error: %s", err)
+                       return nil, e2managererrors.NewRnibDbError()
+               }
+
+               return []*entities.E2TInstance{}, nil
+       }
+
+       if len(e2tAddresses) == 0 {
+               return []*entities.E2TInstance{}, nil
+       }
+
+       e2tInstances, err := m.rnibDataService.GetE2TInstancesNoLogs(e2tAddresses)
+
+       if err != nil {
+               _, ok := err.(*common.ResourceNotFoundError)
+
+               if !ok {
+                       m.logger.Errorf("#E2TInstancesManager.GetE2TInstancesNoLogs - Failed retrieving E2T instances list. error: %s", err)
+               }
+               return e2tInstances, err
+       }
+
+       return e2tInstances, nil
+}
+
+func (m *E2TInstancesManager) GetE2TInstances() ([]*entities.E2TInstance, error) {
+       e2tAddresses, err := m.rnibDataService.GetE2TAddresses()
+
+       if err != nil {
+
+               _, ok := err.(*common.ResourceNotFoundError)
+
+               if !ok {
+                       m.logger.Errorf("#E2TInstancesManager.GetE2TInstances - Failed retrieving E2T addresses. error: %s", err)
+                       return nil, e2managererrors.NewRnibDbError()
+               }
+
+               m.logger.Infof("#E2TInstancesManager.GetE2TInstances - Empty E2T addresses list")
+               return []*entities.E2TInstance{}, nil
+       }
+
+       if len(e2tAddresses) == 0 {
+               m.logger.Infof("#E2TInstancesManager.GetE2TInstances - Empty E2T addresses list")
+               return []*entities.E2TInstance{}, nil
+       }
+
+       e2tInstances, err := m.rnibDataService.GetE2TInstances(e2tAddresses)
+
+       if err != nil {
+               m.logger.Errorf("#E2TInstancesManager.GetE2TInstances - Failed retrieving E2T instances list. error: %s", err)
+               return e2tInstances, e2managererrors.NewRnibDbError()
+       }
+
+       if len(e2tInstances) == 0 {
+               m.logger.Warnf("#E2TInstancesManager.GetE2TInstances - Empty E2T instances list")
+               return e2tInstances, nil
+       }
+
+       return e2tInstances, nil
+}
+
+func (m *E2TInstancesManager) ResetKeepAliveTimestampsForAllE2TInstances() {
+
+       e2tInstances, err := m.GetE2TInstances()
+
+       if err != nil {
+               m.logger.Errorf("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - Couldn't reset timestamps due to a DB error")
+               return
+       }
+
+       if len(e2tInstances) == 0 {
+               m.logger.Infof("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - No instances, ignoring reset")
+               return
+       }
+
+       for _, v := range e2tInstances {
+
+               if v.State != entities.Active {
+                       continue
+               }
+
+               v.KeepAliveTimestamp = time.Now().UnixNano()
+
+               err := m.rnibDataService.SaveE2TInstance(v)
+
+               if err != nil {
+                       m.logger.Errorf("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - E2T address: %s - failed resetting e2t instance keep alive timestamp. error: %s", v.Address, err)
+               }
+       }
+
+       m.logger.Infof("E2TInstancesManager.ResetKeepAliveTimestampForAllE2TInstances - Done with reset")
+}
+
+func findActiveE2TInstanceWithMinimumAssociatedRans(e2tInstances []*entities.E2TInstance) *entities.E2TInstance {
+       var minInstance *entities.E2TInstance
+       minAssociatedRanCount := math.MaxInt32
+
+       for _, v := range e2tInstances {
+               if v.State == entities.Active && len(v.AssociatedRanList) < minAssociatedRanCount {
+                       minAssociatedRanCount = len(v.AssociatedRanList)
+                       minInstance = v
+               }
+       }
+
+       return minInstance
+}
+
+func (m *E2TInstancesManager) AddE2TInstance(e2tAddress string) error {
+
+       m.mux.Lock()
+       defer m.mux.Unlock()
+
+       e2tInstance := entities.NewE2TInstance(e2tAddress)
+       err := m.rnibDataService.SaveE2TInstance(e2tInstance)
+
+       if err != nil {
+               m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed saving E2T instance. error: %s", e2tInstance.Address, err)
+               return err
+       }
+
+       e2tAddresses, err := m.rnibDataService.GetE2TAddresses()
+
+       if err != nil {
+
+               _, ok := err.(*common.ResourceNotFoundError)
+
+               if !ok {
+                       m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed retrieving E2T addresses list. error: %s", e2tInstance.Address, err)
+                       return err
+               }
+       }
+
+       e2tAddresses = append(e2tAddresses, e2tInstance.Address)
+
+       err = m.rnibDataService.SaveE2TAddresses(e2tAddresses)
+
+       if err != nil {
+               m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed saving E2T addresses list. error: %s", e2tInstance.Address, err)
+               return err
+       }
+
+       m.logger.Infof("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - successfully added E2T instance", e2tInstance.Address)
+       return nil
+}
+
+func (m *E2TInstancesManager) DissociateRan(ranName string, e2tAddress string) error {
+
+       m.mux.Lock()
+       defer m.mux.Unlock()
+
+       e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
+
+       if err != nil {
+               m.logger.Errorf("#E2TInstancesManager.DissociateRan - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
+               return err
+       }
+
+       i := 0 // output index
+       for _, v := range e2tInstance.AssociatedRanList {
+               if v != ranName {
+                       // copy and increment index
+                       e2tInstance.AssociatedRanList[i] = v
+                       i++
+               }
+       }
+
+       e2tInstance.AssociatedRanList = e2tInstance.AssociatedRanList[:i]
+
+       err = m.rnibDataService.SaveE2TInstance(e2tInstance)
+
+       if err != nil {
+               m.logger.Errorf("#E2TInstancesManager.DissociateRan - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
+               return err
+       }
+
+       m.logger.Infof("#E2TInstancesManager.DissociateRan - successfully dissociated RAN %s from E2T %s", ranName, e2tInstance.Address)
+       return nil
+}
+
+func (m *E2TInstancesManager) RemoveE2TInstance(e2tInstance *entities.E2TInstance) error {
+       return nil
+}
+func (m *E2TInstancesManager) SelectE2TInstance() (string, error) {
+
+       e2tInstances, err := m.GetE2TInstances()
+
+       if err != nil {
+               return "", err
+       }
+
+       if len(e2tInstances) == 0 {
+               m.logger.Errorf("#E2TInstancesManager.SelectE2TInstance - No E2T instance found")
+               return "", e2managererrors.NewE2TInstanceAbsenceError()
+       }
+
+       min := findActiveE2TInstanceWithMinimumAssociatedRans(e2tInstances)
+
+       if min == nil {
+               m.logger.Errorf("#E2TInstancesManager.SelectE2TInstance - No active E2T instance found")
+               return "", e2managererrors.NewE2TInstanceAbsenceError()
+       }
+
+       m.logger.Infof("#E2TInstancesManager.SelectE2TInstance - successfully selected E2T instance. address: %s", min.Address)
+       return min.Address, nil
+}
+
+func (m *E2TInstancesManager) AssociateRan(ranName string, e2tAddress string) error {
+
+       m.mux.Lock()
+       defer m.mux.Unlock()
+
+       e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
+
+       if err != nil {
+               m.logger.Errorf("#E2TInstancesManager.AssociateRan - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
+               return e2managererrors.NewRnibDbError()
+       }
+
+       e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, ranName)
+
+       err = m.rnibDataService.SaveE2TInstance(e2tInstance)
+
+       if err != nil {
+               m.logger.Errorf("#E2TInstancesManager.AssociateRan - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
+               return e2managererrors.NewRnibDbError()
+       }
+
+       m.logger.Infof("#E2TInstancesManager.AssociateRan - successfully associated RAN %s with E2T %s", ranName, e2tInstance.Address)
+       return nil
+}
+
+func (h E2TInstancesManager) ActivateE2TInstance(e2tInstance *entities.E2TInstance) error{
+
+       if e2tInstance == nil {
+               h.logger.Errorf("#E2TInstancesManager.ActivateE2TInstance - e2tInstance empty")
+               return e2managererrors.NewInternalError()
+       }
+
+       h.logger.Infof("#E2TInstancesManager.ActivateE2TInstance - E2T Address: %s - activate E2T instance", e2tInstance.Address)
+
+       e2tInstance.State = entities.Active
+       e2tInstance.KeepAliveTimestamp = time.Now().UnixNano()
+
+       err := h.rnibDataService.SaveE2TInstance(e2tInstance)
+       if err != nil {
+               h.logger.Errorf("#E2TInstancesManager.ActivateE2TInstance - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tInstance.Address, err)
+               return err
+       }
+       return nil
+}
+
+func (m *E2TInstancesManager) ResetKeepAliveTimestamp(e2tAddress string) error {
+
+       m.mux.Lock()
+       defer m.mux.Unlock()
+
+       e2tInstance, err := m.rnibDataService.GetE2TInstanceNoLogs(e2tAddress)
+
+       if err != nil {
+               m.logger.Errorf("#E2TInstancesManager.ResetKeepAliveTimestamp - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
+               return err
+       }
+
+       if e2tInstance.State == entities.ToBeDeleted || e2tInstance.State == entities.RoutingManagerFailure {
+               m.logger.Warnf("#E2TInstancesManager.ResetKeepAliveTimestamp - Ignore. This Instance is about to deleted")
+               return nil
+
+       }
+
+       e2tInstance.KeepAliveTimestamp = time.Now().UnixNano()
+       err = m.rnibDataService.SaveE2TInstanceNoLogs(e2tInstance)
+
+       if err != nil {
+               m.logger.Errorf("#E2TInstancesManager.ResetKeepAliveTimestamp - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
+               return err
+       }
+
+       return nil
+}
diff --git a/E2Manager/managers/e2t_instances_manager_test.go b/E2Manager/managers/e2t_instances_manager_test.go
new file mode 100644 (file)
index 0000000..fb564e5
--- /dev/null
@@ -0,0 +1,459 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package managers
+
+import (
+       "e2mgr/configuration"
+       "e2mgr/logger"
+       "e2mgr/mocks"
+       "e2mgr/services"
+       "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/pkg/errors"
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/mock"
+       "testing"
+)
+
+const E2TAddress = "10.10.2.15:9800"
+const E2TAddress2 = "10.10.2.16:9800"
+
+func initE2TInstancesManagerTest(t *testing.T) (*mocks.RnibReaderMock, *mocks.RnibWriterMock, *E2TInstancesManager) {
+       logger, err := logger.InitLogger(logger.DebugLevel)
+       if err != nil {
+               t.Errorf("#... - failed to initialize logger, error: %s", err)
+       }
+       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
+
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+       e2tInstancesManager := NewE2TInstancesManager(rnibDataService, logger)
+       return readerMock, writerMock, e2tInstancesManager
+}
+
+func TestAddNewE2TInstanceSaveE2TInstanceFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(common.NewInternalError(errors.New("Error")))
+       err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+       assert.NotNil(t, err)
+       rnibReaderMock.AssertNotCalled(t, "GetE2TAddresses")
+}
+
+func TestAddNewE2TInstanceGetE2TAddressesInternalFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+       e2tAddresses := []string{}
+       rnibReaderMock.On("GetE2TAddresses").Return(e2tAddresses, common.NewInternalError(errors.New("Error")))
+       err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+       assert.NotNil(t, err)
+       rnibReaderMock.AssertNotCalled(t, "SaveE2TAddresses")
+}
+
+func TestAddNewE2TInstanceSaveE2TAddressesFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+       E2TAddresses := []string{}
+       rnibReaderMock.On("GetE2TAddresses").Return(E2TAddresses, nil)
+       E2TAddresses = append(E2TAddresses, E2TAddress)
+       rnibWriterMock.On("SaveE2TAddresses", E2TAddresses).Return(common.NewResourceNotFoundError(""))
+       err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+       assert.NotNil(t, err)
+}
+
+func TestAddNewE2TInstanceNoE2TAddressesSuccess(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+       e2tAddresses := []string{}
+       rnibReaderMock.On("GetE2TAddresses").Return(e2tAddresses, common.NewResourceNotFoundError(""))
+       e2tAddresses = append(e2tAddresses, E2TAddress)
+       rnibWriterMock.On("SaveE2TAddresses", e2tAddresses).Return(nil)
+       err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+       assert.Nil(t, err)
+       rnibWriterMock.AssertCalled(t, "SaveE2TAddresses", e2tAddresses)
+}
+
+func TestAddNewE2TInstanceEmptyE2TAddressesSuccess(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+       e2tAddresses := []string{}
+       rnibReaderMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
+       e2tAddresses = append(e2tAddresses, E2TAddress)
+       rnibWriterMock.On("SaveE2TAddresses", e2tAddresses).Return(nil)
+       err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+       assert.Nil(t, err)
+       rnibWriterMock.AssertCalled(t, "SaveE2TAddresses", e2tAddresses)
+}
+
+func TestAddNewE2TInstanceExistingE2TAddressesSuccess(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+       E2TAddresses := []string{"10.0.1.15:3030"}
+       rnibReaderMock.On("GetE2TAddresses").Return(E2TAddresses, nil)
+       E2TAddresses = append(E2TAddresses, E2TAddress)
+       rnibWriterMock.On("SaveE2TAddresses", E2TAddresses).Return(nil)
+       err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+       assert.Nil(t, err)
+}
+
+func TestGetE2TInstanceFailure(t *testing.T) {
+       rnibReaderMock, _, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       var e2tInstance *entities.E2TInstance
+       rnibReaderMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, common.NewInternalError(fmt.Errorf("for test")))
+       res, err := e2tInstancesManager.GetE2TInstance(E2TAddress)
+       assert.NotNil(t, err)
+       assert.Nil(t, res)
+}
+
+func TestGetE2TInstanceSuccess(t *testing.T) {
+       rnibReaderMock, _, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       address := "10.10.2.15:9800"
+       e2tInstance := entities.NewE2TInstance(address)
+       rnibReaderMock.On("GetE2TInstance", address).Return(e2tInstance, nil)
+       res, err := e2tInstancesManager.GetE2TInstance(address)
+       assert.Nil(t, err)
+       assert.Equal(t, e2tInstance, res)
+}
+
+func TestAssociateRanGetInstanceFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       var e2tInstance1 *entities.E2TInstance
+       rnibReaderMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance1, common.NewInternalError(fmt.Errorf("for test")))
+
+       err := e2tInstancesManager.AssociateRan("test1", E2TAddress)
+       assert.NotNil(t, err)
+       rnibWriterMock.AssertNotCalled(t, "SaveE2TInstance")
+}
+
+func TestAssociateRanSaveInstanceFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       rnibReaderMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance1, nil)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(common.NewInternalError(fmt.Errorf("for test")))
+
+       err := e2tInstancesManager.AssociateRan("test1", E2TAddress)
+       assert.NotNil(t, err)
+       rnibReaderMock.AssertExpectations(t)
+       rnibWriterMock.AssertExpectations(t)
+}
+
+func TestAssociateRanSuccess(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       e2tInstance := entities.NewE2TInstance(E2TAddress)
+       rnibReaderMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
+
+       updateE2TInstance := *e2tInstance
+       updateE2TInstance.AssociatedRanList = append(updateE2TInstance.AssociatedRanList, "test1")
+
+       rnibWriterMock.On("SaveE2TInstance", &updateE2TInstance).Return(nil)
+
+       err := e2tInstancesManager.AssociateRan("test1", E2TAddress)
+       assert.Nil(t, err)
+       rnibReaderMock.AssertExpectations(t)
+       rnibWriterMock.AssertExpectations(t)
+}
+
+func TestDissociateRanGetInstanceFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       var e2tInstance1 *entities.E2TInstance
+       rnibReaderMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance1, common.NewInternalError(fmt.Errorf("for test")))
+       err := e2tInstancesManager.DissociateRan("test1", E2TAddress)
+       assert.NotNil(t, err)
+       rnibWriterMock.AssertNotCalled(t, "SaveE2TInstance")
+}
+
+func TestDissociateRanSaveInstanceFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       rnibReaderMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance1, nil)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(common.NewInternalError(fmt.Errorf("for test")))
+
+       err := e2tInstancesManager.DissociateRan("test1", E2TAddress)
+       assert.NotNil(t, err)
+       rnibReaderMock.AssertExpectations(t)
+       rnibWriterMock.AssertExpectations(t)
+}
+
+func TestDissociateRanSuccess(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       e2tInstance := entities.NewE2TInstance(E2TAddress)
+       e2tInstance.AssociatedRanList = []string{"test0", "test1"}
+       updatedE2TInstance := *e2tInstance
+       updatedE2TInstance.AssociatedRanList = []string{"test0"}
+       rnibReaderMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
+       rnibWriterMock.On("SaveE2TInstance", &updatedE2TInstance).Return(nil)
+
+       err := e2tInstancesManager.DissociateRan("test1", E2TAddress)
+       assert.Nil(t, err)
+       rnibReaderMock.AssertExpectations(t)
+       rnibWriterMock.AssertExpectations(t)
+}
+
+func TestSelectE2TInstancesGetE2TAddressesFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       rnibReaderMock.On("GetE2TAddresses").Return([]string{}, common.NewInternalError(fmt.Errorf("for test")))
+       address, err := e2tInstancesManager.SelectE2TInstance()
+       assert.NotNil(t, err)
+       assert.Empty(t, address)
+       rnibReaderMock.AssertExpectations(t)
+       rnibWriterMock.AssertNotCalled(t, "GetE2TInstances")
+}
+
+func TestSelectE2TInstancesEmptyE2TAddressList(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       rnibReaderMock.On("GetE2TAddresses").Return([]string{}, nil)
+       address, err := e2tInstancesManager.SelectE2TInstance()
+       assert.NotNil(t, err)
+       assert.Empty(t, address)
+       rnibReaderMock.AssertExpectations(t)
+       rnibWriterMock.AssertNotCalled(t, "GetE2TInstances")
+}
+
+func TestSelectE2TInstancesGetE2TInstancesFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       addresses := []string{E2TAddress}
+       rnibReaderMock.On("GetE2TAddresses").Return(addresses, nil)
+       rnibReaderMock.On("GetE2TInstances", addresses).Return([]*entities.E2TInstance{}, common.NewInternalError(fmt.Errorf("for test")))
+       address, err := e2tInstancesManager.SelectE2TInstance()
+       assert.NotNil(t, err)
+       assert.Empty(t, address)
+       rnibReaderMock.AssertExpectations(t)
+       rnibWriterMock.AssertExpectations(t)
+}
+
+func TestSelectE2TInstancesEmptyE2TInstancesList(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       addresses := []string{E2TAddress}
+       rnibReaderMock.On("GetE2TAddresses").Return(addresses, nil)
+       rnibReaderMock.On("GetE2TInstances", addresses).Return([]*entities.E2TInstance{}, nil)
+       address, err := e2tInstancesManager.SelectE2TInstance()
+       assert.NotNil(t, err)
+       assert.Empty(t, address)
+       rnibReaderMock.AssertExpectations(t)
+       rnibWriterMock.AssertExpectations(t)
+}
+
+func TestSelectE2TInstancesNoActiveE2TInstance(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       addresses := []string{E2TAddress, E2TAddress2}
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.State = entities.ToBeDeleted
+       e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test3"}
+       e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
+       e2tInstance2.State = entities.ToBeDeleted
+       e2tInstance2.AssociatedRanList = []string{"test4", "test5", "test6", "test7"}
+
+       rnibReaderMock.On("GetE2TAddresses").Return(addresses, nil)
+       rnibReaderMock.On("GetE2TInstances", addresses).Return([]*entities.E2TInstance{e2tInstance1, e2tInstance2}, nil)
+       address, err := e2tInstancesManager.SelectE2TInstance()
+       assert.NotNil(t, err)
+       assert.Equal(t, "", address)
+       rnibReaderMock.AssertExpectations(t)
+       rnibWriterMock.AssertExpectations(t)
+}
+
+func TestSelectE2TInstancesSuccess(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       addresses := []string{E2TAddress, E2TAddress2}
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test3"}
+       e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
+       e2tInstance2.AssociatedRanList = []string{"test4", "test5", "test6", "test7"}
+
+       rnibReaderMock.On("GetE2TAddresses").Return(addresses, nil)
+       rnibReaderMock.On("GetE2TInstances", addresses).Return([]*entities.E2TInstance{e2tInstance1, e2tInstance2}, nil)
+       address, err := e2tInstancesManager.SelectE2TInstance()
+       assert.Nil(t, err)
+       assert.Equal(t, E2TAddress, address)
+       rnibReaderMock.AssertExpectations(t)
+       rnibWriterMock.AssertExpectations(t)
+}
+
+func TestActivateE2TInstanceSuccess(t *testing.T) {
+       _, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.State = entities.RoutingManagerFailure
+       e2tInstance1.AssociatedRanList = []string{"test1","test2","test3"}
+
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+
+       err := e2tInstancesManager.ActivateE2TInstance(e2tInstance1)
+       assert.Nil(t, err)
+       assert.Equal(t, entities.Active, e2tInstance1.State)
+       rnibWriterMock.AssertExpectations(t)
+}
+
+func TestActivateE2TInstance_RnibError(t *testing.T) {
+       _, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.State = entities.RoutingManagerFailure
+       e2tInstance1.AssociatedRanList = []string{"test1","test2","test3"}
+
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(common.NewInternalError(errors.New("Error")))
+
+       err := e2tInstancesManager.ActivateE2TInstance(e2tInstance1)
+       assert.NotNil(t, err)
+}
+
+func TestActivateE2TInstance_NoInstance(t *testing.T) {
+       _, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       err := e2tInstancesManager.ActivateE2TInstance(nil)
+
+       assert.NotNil(t, err)
+       rnibWriterMock.AssertNotCalled(t, "SaveE2TInstance")
+}
+
+func TestResetKeepAliveTimestampGetInternalFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       address := "10.10.2.15:9800"
+       e2tInstance := entities.NewE2TInstance(address)
+       rnibReaderMock.On("GetE2TInstance", address).Return(e2tInstance, common.NewInternalError(errors.New("Error")))
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+
+       err := e2tInstancesManager.ResetKeepAliveTimestamp(address)
+       assert.NotNil(t, err)
+       rnibReaderMock.AssertNotCalled(t, "SaveE2TInstance")
+}
+
+func TestAResetKeepAliveTimestampSaveInternalFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       address := "10.10.2.15:9800"
+       e2tInstance := entities.NewE2TInstance(address)
+       rnibReaderMock.On("GetE2TInstance", address).Return(e2tInstance, nil)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(common.NewInternalError(errors.New("Error")))
+
+       err := e2tInstancesManager.ResetKeepAliveTimestamp(address)
+       assert.NotNil(t, err)
+}
+
+func TestResetKeepAliveTimestampSuccess(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       address := "10.10.2.15:9800"
+       e2tInstance := entities.NewE2TInstance(address)
+       rnibReaderMock.On("GetE2TInstance", address).Return(e2tInstance, nil)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+
+       err := e2tInstancesManager.ResetKeepAliveTimestamp(address)
+       assert.Nil(t, err)
+       rnibReaderMock.AssertCalled(t, "GetE2TInstance", address)
+       rnibWriterMock.AssertNumberOfCalls(t, "SaveE2TInstance", 1)
+}
+
+func TestResetKeepAliveTimestampToBeDeleted(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       address := "10.10.2.15:9800"
+       e2tInstance := entities.NewE2TInstance(address)
+       e2tInstance.State = entities.ToBeDeleted
+       rnibReaderMock.On("GetE2TInstance", address).Return(e2tInstance, nil)
+
+       err := e2tInstancesManager.ResetKeepAliveTimestamp(address)
+       assert.Nil(t, err)
+       rnibReaderMock.AssertCalled(t, "GetE2TInstance", address)
+       rnibWriterMock.AssertNotCalled(t, "SaveE2TInstance")
+}
+
+func TestResetKeepAliveTimestampRoutingManagerFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+
+       address := "10.10.2.15:9800"
+       e2tInstance := entities.NewE2TInstance(address)
+       e2tInstance.State = entities.RoutingManagerFailure
+       rnibReaderMock.On("GetE2TInstance", address).Return(e2tInstance, nil)
+
+       err := e2tInstancesManager.ResetKeepAliveTimestamp(address)
+       assert.Nil(t, err)
+       rnibReaderMock.AssertCalled(t, "GetE2TInstance", address)
+       rnibWriterMock.AssertNotCalled(t, "SaveE2TInstance")
+}
+
+func TestRemoveE2TInstance(t *testing.T) {
+       _, _, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       err := e2tInstancesManager.RemoveE2TInstance(e2tInstance1)
+       assert.Nil(t, err)
+}
+
+func TestResetKeepAliveTimestampsForAllE2TInstancesGetE2TInstancesFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       rnibReaderMock.On("GetE2TAddresses").Return([]string{}, common.NewInternalError(errors.New("Error")))
+       e2tInstancesManager.ResetKeepAliveTimestampsForAllE2TInstances()
+       rnibWriterMock.AssertNotCalled(t, "SaveE2TInstance")
+}
+
+func TestResetKeepAliveTimestampsForAllE2TInstancesNoInstances(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       rnibReaderMock.On("GetE2TAddresses").Return([]string{}, nil)
+       e2tInstancesManager.ResetKeepAliveTimestampsForAllE2TInstances()
+       rnibWriterMock.AssertNotCalled(t, "SaveE2TInstance")
+}
+
+func TestResetKeepAliveTimestampsForAllE2TInstancesNoActiveInstances(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       e2tAddresses := []string{E2TAddress, E2TAddress2}
+       rnibReaderMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.State = entities.ToBeDeleted
+       e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
+       e2tInstance2.State = entities.RoutingManagerFailure
+       rnibReaderMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{e2tInstance1, e2tInstance2}, nil)
+       e2tInstancesManager.ResetKeepAliveTimestampsForAllE2TInstances()
+       rnibWriterMock.AssertNotCalled(t, "SaveE2TInstance")
+}
+
+func TestResetKeepAliveTimestampsForAllE2TInstancesOneActiveInstance(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       e2tAddresses := []string{E2TAddress, E2TAddress2}
+       rnibReaderMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.State = entities.Active
+       e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
+       e2tInstance2.State = entities.ToBeDeleted
+       rnibReaderMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{e2tInstance1, e2tInstance2}, nil)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+       e2tInstancesManager.ResetKeepAliveTimestampsForAllE2TInstances()
+       rnibWriterMock.AssertNumberOfCalls(t, "SaveE2TInstance",1)
+}
+
+func TestResetKeepAliveTimestampsForAllE2TInstancesSaveE2TInstanceFailure(t *testing.T) {
+       rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+       e2tAddresses := []string{E2TAddress, E2TAddress2}
+       rnibReaderMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.State = entities.Active
+       e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
+       e2tInstance2.State = entities.ToBeDeleted
+       rnibReaderMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{e2tInstance1, e2tInstance2}, nil)
+       rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(common.NewInternalError(errors.New("Error")))
+       e2tInstancesManager.ResetKeepAliveTimestampsForAllE2TInstances()
+       rnibWriterMock.AssertNumberOfCalls(t, "SaveE2TInstance",1)
+}
diff --git a/E2Manager/managers/e2t_keep_alive_worker.go b/E2Manager/managers/e2t_keep_alive_worker.go
new file mode 100644 (file)
index 0000000..45c5c08
--- /dev/null
@@ -0,0 +1,85 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package managers
+
+import (
+       "e2mgr/configuration"
+       "e2mgr/logger"
+       "e2mgr/models"
+       "e2mgr/rmrCgo"
+       "e2mgr/services/rmrsender"
+       "time"
+)
+
+type E2TKeepAliveWorker struct {
+       logger              *logger.Logger
+       e2tShutdownManager  IE2TShutdownManager
+       e2TInstancesManager IE2TInstancesManager
+       rmrSender           *rmrsender.RmrSender
+       config              *configuration.Configuration
+}
+
+func NewE2TKeepAliveWorker(logger *logger.Logger, rmrSender *rmrsender.RmrSender, e2TInstancesManager IE2TInstancesManager, e2tShutdownManager IE2TShutdownManager, config *configuration.Configuration) E2TKeepAliveWorker {
+       return E2TKeepAliveWorker{
+               logger:              logger,
+               e2tShutdownManager:  e2tShutdownManager,
+               e2TInstancesManager: e2TInstancesManager,
+               rmrSender:           rmrSender,
+               config:              config,
+       }
+}
+
+func (h E2TKeepAliveWorker) Execute() {
+
+       h.logger.Infof("#E2TKeepAliveWorker.Execute - keep alive started")
+
+       ticker := time.NewTicker(time.Duration(h.config.KeepAliveDelayMs) * time.Millisecond)
+
+       for _= range ticker.C {
+
+               h.SendKeepAliveRequest()
+               h.E2TKeepAliveExpired()
+       }
+}
+
+func (h E2TKeepAliveWorker) E2TKeepAliveExpired() {
+
+       e2tInstances, err := h.e2TInstancesManager.GetE2TInstancesNoLogs()
+
+       if err != nil || len(e2tInstances) == 0 {
+               return
+       }
+
+       for _, e2tInstance := range e2tInstances {
+
+               delta := int64(time.Now().UnixNano()) - e2tInstance.KeepAliveTimestamp
+               timestampNanosec := int64(time.Duration(h.config.KeepAliveResponseTimeoutMs) * time.Millisecond)
+
+               if delta > timestampNanosec {
+
+                       h.logger.Warnf("#E2TKeepAliveWorker.E2TKeepAliveExpired - e2t address: %s time expired, shutdown e2 instance", e2tInstance.Address)
+
+                       h.e2tShutdownManager.Shutdown(e2tInstance)
+               }
+       }
+}
+
+func (h E2TKeepAliveWorker) SendKeepAliveRequest() {
+
+       request := models.RmrMessage{MsgType: rmrCgo.E2_TERM_KEEP_ALIVE_REQ}
+       h.rmrSender.SendWithoutLogs(&request)
+}
\ No newline at end of file
diff --git a/E2Manager/managers/e2t_keep_alive_worker_test.go b/E2Manager/managers/e2t_keep_alive_worker_test.go
new file mode 100644 (file)
index 0000000..00714ca
--- /dev/null
@@ -0,0 +1,198 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package managers
+
+import (
+       "e2mgr/configuration"
+       "e2mgr/logger"
+       "e2mgr/mocks"
+       "e2mgr/rmrCgo"
+       "e2mgr/services"
+       "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/pkg/errors"
+       "github.com/stretchr/testify/mock"
+       "testing"
+       "time"
+)
+
+func initE2TKeepAliveTest(t *testing.T) (*mocks.RmrMessengerMock, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.E2TShutdownManagerMock, *E2TKeepAliveWorker) {
+       logger, err := logger.InitLogger(logger.DebugLevel)
+       if err != nil {
+               t.Errorf("#... - failed to initialize logger, error: %s", err)
+       }
+       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3, KeepAliveResponseTimeoutMs: 400, KeepAliveDelayMs: 100}
+
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
+       e2tShutdownManagerMock := &mocks.E2TShutdownManagerMock{}
+
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+       e2tInstancesManager := NewE2TInstancesManager(rnibDataService, logger)
+
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
+       rmrSender := initRmrSender(rmrMessengerMock, logger)
+
+       e2tKeepAliveWorker := NewE2TKeepAliveWorker(logger, rmrSender, e2tInstancesManager, e2tShutdownManagerMock, config)
+
+       return rmrMessengerMock, readerMock, writerMock, e2tShutdownManagerMock, &e2tKeepAliveWorker
+}
+
+func TestSendKeepAliveRequest(t *testing.T) {
+       rmrMessengerMock, _, _, _, e2tKeepAliveWorker := initE2TKeepAliveTest(t)
+
+       rmrMessengerMock.On("SendMsg", mock.Anything, false).Return(&rmrCgo.MBuf{}, nil)
+
+       e2tKeepAliveWorker.SendKeepAliveRequest()
+
+       var payload, xAction []byte
+       req := rmrCgo.NewMBuf(rmrCgo.E2_TERM_KEEP_ALIVE_REQ, 0, "", &payload, &xAction)
+
+       rmrMessengerMock.AssertCalled(t, "SendMsg", req, false)
+}
+
+func TestShutdownExpiredE2T_InternalError(t *testing.T) {
+       rmrMessengerMock, readerMock, _, _, e2tKeepAliveWorker := initE2TKeepAliveTest(t)
+
+       readerMock.On("GetE2TAddresses").Return([]string{}, common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")))
+
+       e2tKeepAliveWorker.E2TKeepAliveExpired()
+
+       rmrMessengerMock.AssertNotCalled(t, "Shutdown")
+}
+
+func TestShutdownExpiredE2T_NoAddresses(t *testing.T) {
+       rmrMessengerMock, readerMock, _, _, e2tKeepAliveWorker := initE2TKeepAliveTest(t)
+
+       addresses := []string{}
+
+       readerMock.On("GetE2TAddresses").Return(addresses, nil)
+
+       e2tKeepAliveWorker.E2TKeepAliveExpired()
+
+       rmrMessengerMock.AssertNotCalled(t, "Shutdown")
+}
+
+func TestShutdownExpiredE2T_NotExpired_InternalError(t *testing.T) {
+       rmrMessengerMock, readerMock, _, _, e2tKeepAliveWorker := initE2TKeepAliveTest(t)
+
+       addresses := []string{E2TAddress,E2TAddress2}
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.AssociatedRanList = []string{"test1","test2","test3"}
+       e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
+       e2tInstance2.AssociatedRanList = []string{"test4","test5","test6", "test7"}
+
+       readerMock.On("GetE2TAddresses").Return(addresses, nil)
+       readerMock.On("GetE2TInstances",addresses).Return([]*entities.E2TInstance{e2tInstance1, e2tInstance2}, common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")))
+
+       e2tKeepAliveWorker.E2TKeepAliveExpired()
+
+       rmrMessengerMock.AssertNotCalled(t, "Shutdown")
+}
+
+func TestShutdownExpiredE2T_NoE2T(t *testing.T) {
+       rmrMessengerMock, readerMock, _, _, e2tKeepAliveWorker := initE2TKeepAliveTest(t)
+
+       readerMock.On("GetE2TAddresses").Return([]string{}, common.NewResourceNotFoundError("not found"))
+
+       e2tKeepAliveWorker.E2TKeepAliveExpired()
+
+       rmrMessengerMock.AssertNotCalled(t, "Shutdown")
+}
+
+func TestShutdownExpiredE2T_NotExpired(t *testing.T) {
+       rmrMessengerMock, readerMock, _, _, e2tKeepAliveWorker := initE2TKeepAliveTest(t)
+
+       addresses := []string{E2TAddress,E2TAddress2}
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.AssociatedRanList = []string{"test1","test2","test3"}
+       e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
+       e2tInstance2.AssociatedRanList = []string{"test4","test5","test6", "test7"}
+
+       readerMock.On("GetE2TAddresses").Return(addresses, nil)
+       readerMock.On("GetE2TInstances",addresses).Return([]*entities.E2TInstance{e2tInstance1, e2tInstance2}, nil)
+
+       e2tKeepAliveWorker.E2TKeepAliveExpired()
+
+       rmrMessengerMock.AssertNotCalled(t, "Shutdown")
+}
+
+func TestShutdownExpiredE2T_One_E2TExpired(t *testing.T) {
+       _, readerMock, _, e2tShutdownManagerMock, e2tKeepAliveWorker := initE2TKeepAliveTest(t)
+
+       addresses := []string{E2TAddress,E2TAddress2}
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.AssociatedRanList = []string{"test1","test2","test3"}
+
+       time.Sleep(time.Duration(400) * time.Millisecond)
+
+       e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
+       e2tInstance2.AssociatedRanList = []string{"test4","test5","test6", "test7"}
+
+       readerMock.On("GetE2TAddresses").Return(addresses, nil)
+       readerMock.On("GetE2TInstances",addresses).Return([]*entities.E2TInstance{e2tInstance1, e2tInstance2}, nil)
+       e2tShutdownManagerMock.On("Shutdown", e2tInstance1).Return(nil)
+
+       e2tKeepAliveWorker.E2TKeepAliveExpired()
+
+       e2tShutdownManagerMock.AssertNumberOfCalls(t, "Shutdown", 1)
+}
+
+func TestShutdownExpiredE2T_Two_E2TExpired(t *testing.T) {
+       _, readerMock, _, e2tShutdownManagerMock, e2tKeepAliveWorker := initE2TKeepAliveTest(t)
+
+       addresses := []string{E2TAddress,E2TAddress2}
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.AssociatedRanList = []string{"test1","test2","test3"}
+
+       e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
+       e2tInstance2.AssociatedRanList = []string{"test4","test5","test6", "test7"}
+
+       time.Sleep(time.Duration(400) * time.Millisecond)
+
+       readerMock.On("GetE2TAddresses").Return(addresses, nil)
+       readerMock.On("GetE2TInstances",addresses).Return([]*entities.E2TInstance{e2tInstance1, e2tInstance2}, nil)
+       e2tShutdownManagerMock.On("Shutdown", e2tInstance1).Return(nil)
+       e2tShutdownManagerMock.On("Shutdown", e2tInstance2).Return(nil)
+
+       e2tKeepAliveWorker.E2TKeepAliveExpired()
+
+       e2tShutdownManagerMock.AssertNumberOfCalls(t, "Shutdown", 2)
+}
+
+func TestExecute_Two_E2TExpired(t *testing.T) {
+       rmrMessengerMock, readerMock, _, e2tShutdownManagerMock, e2tKeepAliveWorker := initE2TKeepAliveTest(t)
+
+       addresses := []string{E2TAddress,E2TAddress2}
+       e2tInstance1 := entities.NewE2TInstance(E2TAddress)
+       e2tInstance1.AssociatedRanList = []string{"test1","test2","test3"}
+
+       readerMock.On("GetE2TAddresses").Return(addresses, nil)
+       readerMock.On("GetE2TInstances",addresses).Return([]*entities.E2TInstance{e2tInstance1}, nil)
+       e2tShutdownManagerMock.On("Shutdown", e2tInstance1).Return(nil)
+       rmrMessengerMock.On("SendMsg", mock.Anything, false).Return(&rmrCgo.MBuf{}, nil)
+
+       go e2tKeepAliveWorker.Execute()
+
+       time.Sleep(time.Duration(500) * time.Millisecond)
+
+       var payload, xAction []byte
+       req := rmrCgo.NewMBuf(rmrCgo.E2_TERM_KEEP_ALIVE_REQ, 0, "", &payload, &xAction)
+
+       rmrMessengerMock.AssertCalled(t, "SendMsg", req, false)
+       e2tShutdownManagerMock.AssertCalled(t, "Shutdown", e2tInstance1)
+}
\ No newline at end of file
diff --git a/E2Manager/managers/e2t_shutdown_manager.go b/E2Manager/managers/e2t_shutdown_manager.go
new file mode 100644 (file)
index 0000000..e789689
--- /dev/null
@@ -0,0 +1,48 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package managers
+
+import (
+       "e2mgr/logger"
+       "e2mgr/services"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+)
+
+
+type IE2TShutdownManager interface {
+       Shutdown(e2tInstance *entities.E2TInstance) error
+}
+
+type E2TShutdownManager struct {
+       logger              *logger.Logger
+       rnibDataService     services.RNibDataService
+       e2TInstancesManager IE2TInstancesManager
+}
+
+func NewE2TShutdownManager(logger *logger.Logger, rnibDataService services.RNibDataService, e2TInstancesManager IE2TInstancesManager) E2TShutdownManager {
+       return E2TShutdownManager{
+               logger:              logger,
+               rnibDataService:     rnibDataService,
+               e2TInstancesManager: e2TInstancesManager,
+       }
+}
+
+func (h E2TShutdownManager) Shutdown(e2tInstance *entities.E2TInstance) error{
+       h.logger.Infof("#E2TShutdownManager.Shutdown - E2T %s is Dead, RIP", e2tInstance.Address)
+
+       return nil
+}
index 1b7a34a..8ef22c9 100644 (file)
@@ -22,20 +22,23 @@ package managers
 
 import (
        "e2mgr/converters"
 
 import (
        "e2mgr/converters"
-       "e2mgr/e2pdus"
        "e2mgr/logger"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
 )
 
        "e2mgr/logger"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
 )
 
-type EndcSetupFailureResponseManager struct{}
+type EndcSetupFailureResponseManager struct {
+       converter converters.IEndcSetupFailureResponseConverter
+}
 
 
-func NewEndcSetupFailureResponseManager() *EndcSetupFailureResponseManager {
-       return &EndcSetupFailureResponseManager{}
+func NewEndcSetupFailureResponseManager(converter converters.IEndcSetupFailureResponseConverter) *EndcSetupFailureResponseManager {
+       return &EndcSetupFailureResponseManager{
+               converter: converter,
+       }
 }
 
 func (m *EndcSetupFailureResponseManager) PopulateNodebByPdu(logger *logger.Logger, nbIdentity *entities.NbIdentity, nodebInfo *entities.NodebInfo, payload []byte) error {
 
 }
 
 func (m *EndcSetupFailureResponseManager) PopulateNodebByPdu(logger *logger.Logger, nbIdentity *entities.NbIdentity, nodebInfo *entities.NodebInfo, payload []byte) error {
 
-       failureResponse, err := converters.UnpackEndcX2SetupFailureResponseAndExtract(logger, e2pdus.MaxAsn1CodecAllocationBufferSize, len(payload), payload, e2pdus.MaxAsn1CodecMessageBufferSize)
+       failureResponse, err := m.converter.UnpackEndcSetupFailureResponseAndExtract(payload)
 
        if err != nil {
                logger.Errorf("#EndcSetupFailureResponseManager.PopulateNodebByPdu - RAN name: %s - Unpack and extract failed. Error: %v", nodebInfo.RanName, err)
 
        if err != nil {
                logger.Errorf("#EndcSetupFailureResponseManager.PopulateNodebByPdu - RAN name: %s - Unpack and extract failed. Error: %v", nodebInfo.RanName, err)
diff --git a/E2Manager/managers/endc_setup_failure_response_manager_test.go b/E2Manager/managers/endc_setup_failure_response_manager_test.go
new file mode 100644 (file)
index 0000000..4bdc9fa
--- /dev/null
@@ -0,0 +1,66 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package managers
+
+import (
+       "e2mgr/converters"
+       "e2mgr/tests"
+       "fmt"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/stretchr/testify/assert"
+       "math/rand"
+       "testing"
+)
+
+func TestPopulateNodebByPduFailure(t *testing.T) {
+       logger := tests.InitLog(t)
+       nodebInfo := &entities.NodebInfo{}
+       nodebIdentity := &entities.NbIdentity{}
+       converter := converters.NewEndcSetupFailureResponseConverter(logger)
+       handler := NewEndcSetupFailureResponseManager(converter)
+       err := handler.PopulateNodebByPdu(logger, nodebIdentity, nodebInfo, createRandomPayload())
+       assert.NotNil(t, err)
+}
+
+func TestPopulateNodebByPduSuccess(t *testing.T) {
+       logger := tests.InitLog(t)
+       nodebInfo := &entities.NodebInfo{}
+       nodebIdentity := &entities.NbIdentity{}
+       converter := converters.NewEndcSetupFailureResponseConverter(logger)
+       handler := NewEndcSetupFailureResponseManager(converter)
+       err := handler.PopulateNodebByPdu(logger, nodebIdentity, nodebInfo, createSetupFailureResponsePayload(t))
+       assert.Nil(t, err)
+       assert.Equal(t, entities.ConnectionStatus_CONNECTED_SETUP_FAILED, nodebInfo.ConnectionStatus)
+       assert.Equal(t, entities.Failure_ENDC_X2_SETUP_FAILURE, nodebInfo.FailureType)
+
+}
+
+func createSetupFailureResponsePayload(t *testing.T) []byte {
+       packedPdu := "4024001a0000030005400200000016400100001140087821a00000008040"
+       var payload []byte
+       _, err := fmt.Sscanf(packedPdu, "%x", &payload)
+       if err != nil {
+               t.Errorf("convert inputPayloadAsStr to payloadAsByte. Error: %v\n", err)
+       }
+       return payload
+}
+
+func createRandomPayload() []byte {
+       payload := make([]byte, 20)
+       rand.Read(payload)
+       return payload
+}
index 60da306..a6118c4 100644 (file)
@@ -22,20 +22,23 @@ package managers
 
 import (
        "e2mgr/converters"
 
 import (
        "e2mgr/converters"
-       "e2mgr/e2pdus"
        "e2mgr/logger"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
 )
 
        "e2mgr/logger"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
 )
 
-type EndcSetupResponseManager struct{}
+type EndcSetupResponseManager struct{
+       converter converters.IEndcSetupResponseConverter
+}
 
 
-func NewEndcSetupResponseManager() *EndcSetupResponseManager {
-       return &EndcSetupResponseManager{}
+func NewEndcSetupResponseManager(converter converters.IEndcSetupResponseConverter) *EndcSetupResponseManager {
+       return &EndcSetupResponseManager{
+               converter: converter,
+       }
 }
 
 func (m *EndcSetupResponseManager) PopulateNodebByPdu(logger *logger.Logger, nbIdentity *entities.NbIdentity, nodebInfo *entities.NodebInfo, payload []byte) error {
 
 }
 
 func (m *EndcSetupResponseManager) PopulateNodebByPdu(logger *logger.Logger, nbIdentity *entities.NbIdentity, nodebInfo *entities.NodebInfo, payload []byte) error {
 
-       gnbId, gnb, err := converters.UnpackEndcX2SetupResponseAndExtract(logger, e2pdus.MaxAsn1CodecAllocationBufferSize, len(payload), payload, e2pdus.MaxAsn1CodecMessageBufferSize)
+       gnbId, gnb, err := m.converter.UnpackEndcSetupResponseAndExtract(payload)
 
        if err != nil {
                logger.Errorf("#EndcSetupResponseManager.PopulateNodebByPdu - RAN name: %s - Unpack and extract failed. Error: %v", nodebInfo.RanName, err)
 
        if err != nil {
                logger.Errorf("#EndcSetupResponseManager.PopulateNodebByPdu - RAN name: %s - Unpack and extract failed. Error: %v", nodebInfo.RanName, err)
diff --git a/E2Manager/managers/endc_setup_response_manager_test.go b/E2Manager/managers/endc_setup_response_manager_test.go
new file mode 100644 (file)
index 0000000..55726c2
--- /dev/null
@@ -0,0 +1,59 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package managers
+
+import (
+       "e2mgr/converters"
+       "e2mgr/tests"
+       "fmt"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/stretchr/testify/assert"
+       "testing"
+)
+
+func TestSetupResponsePopulateNodebByPduFailure(t *testing.T) {
+       logger := tests.InitLog(t)
+       nodebInfo := &entities.NodebInfo{}
+       nodebIdentity := &entities.NbIdentity{}
+       converter:= converters.NewEndcSetupResponseConverter(logger)
+       handler := NewEndcSetupResponseManager(converter)
+       err := handler.PopulateNodebByPdu(logger, nodebIdentity, nodebInfo, createRandomPayload())
+       assert.NotNil(t, err)
+}
+
+func TestSetupResponsePopulateNodebByPduSuccess(t *testing.T) {
+       logger := tests.InitLog(t)
+       nodebInfo := &entities.NodebInfo{}
+       nodebIdentity := &entities.NbIdentity{}
+       converter:= converters.NewEndcSetupResponseConverter(logger)
+       handler := NewEndcSetupResponseManager(converter)
+       err := handler.PopulateNodebByPdu(logger, nodebIdentity, nodebInfo, createSetupResponsePayload(t))
+       assert.Nil(t, err)
+       assert.Equal(t, entities.ConnectionStatus_CONNECTED, nodebInfo.ConnectionStatus)
+       assert.Equal(t, entities.Node_GNB, nodebInfo.NodeType)
+
+}
+
+func createSetupResponsePayload(t *testing.T) []byte {
+       packedPdu := "202400808e00000100f600808640000200fc00090002f829504a952a0a00fd007200010c0005001e3f271f2e3d4ff03d44d34e4f003e4e5e4400010000150400000a000211e148033e4e5e4c0005001e3f271f2e3d4ff03d44d34e4f003e4e5e4400010000150400000a00021a0044033e4e5e000000002c001e3f271f2e3d4ff0031e3f274400010000150400000a00020000"
+       var payload []byte
+       _, err := fmt.Sscanf(packedPdu, "%x", &payload)
+       if err != nil {
+               t.Errorf("convert inputPayloadAsStr to payloadAsByte. Error: %v\n", err)
+       }
+       return payload
+}
index 9583ea2..a44608b 100644 (file)
@@ -49,7 +49,7 @@ func (m NotificationManager) HandleMessage(mbuf *rmrCgo.MBuf) error {
                return err
        }
 
                return err
        }
 
-       notificationRequest := models.NewNotificationRequest(mbuf.Meid, *mbuf.Payload, time.Now(), string(*mbuf.XAction))
+       notificationRequest := models.NewNotificationRequest(mbuf.Meid, *mbuf.Payload, time.Now(), *mbuf.XAction)
        go notificationHandler.Handle(notificationRequest)
        return nil
 }
        go notificationHandler.Handle(notificationRequest)
        return nil
 }
index 770ed02..5bce096 100644 (file)
@@ -1,20 +1,18 @@
 package notificationmanager
 
 import (
 package notificationmanager
 
 import (
+       "e2mgr/clients"
        "e2mgr/configuration"
        "e2mgr/configuration"
-       "e2mgr/converters"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/providers/rmrmsghandlerprovider"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/providers/rmrmsghandlerprovider"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/tests"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/tests"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/assert"
        "testing"
 )
        "github.com/stretchr/testify/assert"
        "testing"
 )
@@ -24,24 +22,16 @@ func initNotificationManagerTest(t *testing.T) (*logger.Logger, *mocks.RnibReade
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
 
        readerMock := &mocks.RnibReaderMock{}
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
 
        readerMock := &mocks.RnibReaderMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
        writerMock := &mocks.RnibWriterMock{}
        writerMock := &mocks.RnibWriterMock{}
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
+       httpClient := &mocks.HttpClientMock{}
 
        rmrSender := initRmrSender(&mocks.RmrMessengerMock{}, logger)
 
        rmrSender := initRmrSender(&mocks.RmrMessengerMock{}, logger)
-       rnibDataService := services.NewRnibDataService(logger, config, rnibReaderProvider, rnibWriterProvider)
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
-       ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, ranSetupManager)
-       ranStatusChangeManager := managers.NewRanStatusChangeManager(logger, rmrSender)
-       x2SetupResponseConverter := converters.NewX2SetupResponseConverter(logger)
-       x2SetupResponseManager := managers.NewX2SetupResponseManager(x2SetupResponseConverter)
-       x2SetupFailureResponseConverter := converters.NewX2SetupFailureResponseConverter(logger)
-       x2SetupFailureResponseManager := managers.NewX2SetupFailureResponseManager(x2SetupFailureResponseConverter)
-       rmrNotificationHandlerProvider := rmrmsghandlerprovider.NewNotificationHandlerProvider(logger, rnibDataService, ranReconnectionManager, ranStatusChangeManager, rmrSender, x2SetupResponseManager, x2SetupFailureResponseManager)
+       e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, logger)
+       routingManagerClient := clients.NewRoutingManagerClient(logger, config, httpClient)
+       rmrNotificationHandlerProvider := rmrmsghandlerprovider.NewNotificationHandlerProvider()
+       rmrNotificationHandlerProvider.Init(logger, config, rnibDataService, rmrSender, ranSetupManager, e2tInstancesManager,routingManagerClient)
        notificationManager := NewNotificationManager(logger, rmrNotificationHandlerProvider )
        return logger, readerMock, notificationManager
 }
        notificationManager := NewNotificationManager(logger, rmrNotificationHandlerProvider )
        return logger, readerMock, notificationManager
 }
@@ -69,7 +59,7 @@ func TestHandleMessageExistingMessageType(t *testing.T) {
 func initRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
 func initRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
-       return rmrsender.NewRmrSender(log, &rmrMessenger)
+       return rmrsender.NewRmrSender(log, rmrMessenger)
 }
 
 // TODO: extract to test_utils
 }
 
 // TODO: extract to test_utils
index 8e2ff8d..530a2cf 100644 (file)
@@ -32,21 +32,27 @@ type IRanReconnectionManager interface {
 }
 
 type RanReconnectionManager struct {
 }
 
 type RanReconnectionManager struct {
-       logger          *logger.Logger
-       config          *configuration.Configuration
-       rnibDataService services.RNibDataService
-       ranSetupManager *RanSetupManager
+       logger              *logger.Logger
+       config              *configuration.Configuration
+       rnibDataService     services.RNibDataService
+       ranSetupManager     *RanSetupManager
+       e2tInstancesManager IE2TInstancesManager
 }
 
 }
 
-func NewRanReconnectionManager(logger *logger.Logger, config *configuration.Configuration, rnibDataService services.RNibDataService, ranSetupManager *RanSetupManager) *RanReconnectionManager {
+func NewRanReconnectionManager(logger *logger.Logger, config *configuration.Configuration, rnibDataService services.RNibDataService, ranSetupManager *RanSetupManager, e2tInstancesManager IE2TInstancesManager) *RanReconnectionManager {
        return &RanReconnectionManager{
        return &RanReconnectionManager{
-               logger:          logger,
-               config:          config,
-               rnibDataService: rnibDataService,
-               ranSetupManager: ranSetupManager,
+               logger:              logger,
+               config:              config,
+               rnibDataService:     rnibDataService,
+               ranSetupManager:     ranSetupManager,
+               e2tInstancesManager: e2tInstancesManager,
        }
 }
 
        }
 }
 
+func (m *RanReconnectionManager) isRanExceededConnectionAttempts(nodebInfo *entities.NodebInfo) bool {
+       return int(nodebInfo.GetConnectionAttempts()) >= m.config.MaxConnectionAttempts
+}
+
 func (m *RanReconnectionManager) ReconnectRan(inventoryName string) error {
        nodebInfo, rnibErr := m.rnibDataService.GetNodeb(inventoryName)
 
 func (m *RanReconnectionManager) ReconnectRan(inventoryName string) error {
        nodebInfo, rnibErr := m.rnibDataService.GetNodeb(inventoryName)
 
@@ -58,7 +64,18 @@ func (m *RanReconnectionManager) ReconnectRan(inventoryName string) error {
        m.logger.Infof("#RanReconnectionManager.ReconnectRan - RAN name: %s - RAN's connection status: %s, RAN's connection attempts: %d", nodebInfo.RanName, nodebInfo.ConnectionStatus, nodebInfo.ConnectionAttempts)
 
        if !m.canReconnectRan(nodebInfo) {
        m.logger.Infof("#RanReconnectionManager.ReconnectRan - RAN name: %s - RAN's connection status: %s, RAN's connection attempts: %d", nodebInfo.RanName, nodebInfo.ConnectionStatus, nodebInfo.ConnectionAttempts)
 
        if !m.canReconnectRan(nodebInfo) {
-               return m.setConnectionStatusOfUnconnectableRan(nodebInfo)
+               e2tAddress := nodebInfo.AssociatedE2TInstanceAddress
+               err := m.updateUnconnectableRan(nodebInfo)
+
+               if err != nil {
+                       return err
+               }
+
+               if m.isRanExceededConnectionAttempts(nodebInfo) {
+                       return m.e2tInstancesManager.DissociateRan(nodebInfo.RanName, e2tAddress)
+               }
+
+               return nil
        }
 
        err := m.ranSetupManager.ExecuteSetup(nodebInfo, entities.ConnectionStatus_CONNECTING)
        }
 
        err := m.ranSetupManager.ExecuteSetup(nodebInfo, entities.ConnectionStatus_CONNECTING)
@@ -77,39 +94,41 @@ func (m *RanReconnectionManager) canReconnectRan(nodebInfo *entities.NodebInfo)
                int(nodebInfo.GetConnectionAttempts()) < m.config.MaxConnectionAttempts
 }
 
                int(nodebInfo.GetConnectionAttempts()) < m.config.MaxConnectionAttempts
 }
 
-func (m *RanReconnectionManager) updateNodebInfoStatus(nodebInfo *entities.NodebInfo, connectionStatus entities.ConnectionStatus) error {
-       if nodebInfo.ConnectionStatus == connectionStatus {
-               return nil
-       }
+func (m *RanReconnectionManager) updateNodebInfo(nodebInfo *entities.NodebInfo, connectionStatus entities.ConnectionStatus, resetE2tAddress bool) error {
 
        nodebInfo.ConnectionStatus = connectionStatus;
 
        nodebInfo.ConnectionStatus = connectionStatus;
+
+       if resetE2tAddress {
+               nodebInfo.AssociatedE2TInstanceAddress = ""
+       }
+
        err := m.rnibDataService.UpdateNodebInfo(nodebInfo)
 
        if err != nil {
        err := m.rnibDataService.UpdateNodebInfo(nodebInfo)
 
        if err != nil {
-               m.logger.Errorf("#RanReconnectionManager.updateNodebInfoStatus - RAN name: %s - Failed updating RAN's connection status to %s in rNib. Error: %v", nodebInfo.RanName, connectionStatus, err)
+               m.logger.Errorf("#RanReconnectionManager.updateNodebInfo - RAN name: %s - Failed updating RAN's connection status to %s in rNib. Error: %v", nodebInfo.RanName, connectionStatus, err)
                return err
        }
 
                return err
        }
 
-       m.logger.Infof("#RanReconnectionManager.updateNodebInfoStatus - RAN name: %s - Successfully updated rNib. RAN's current connection status: %s", nodebInfo.RanName, nodebInfo.ConnectionStatus)
+       m.logger.Infof("#RanReconnectionManager.updateNodebInfo - RAN name: %s - Successfully updated rNib. RAN's current connection status: %s", nodebInfo.RanName, nodebInfo.ConnectionStatus)
        return nil
 }
 
        return nil
 }
 
-func (m *RanReconnectionManager) setConnectionStatusOfUnconnectableRan(nodebInfo *entities.NodebInfo) error {
+func (m *RanReconnectionManager) updateUnconnectableRan(nodebInfo *entities.NodebInfo) error {
        connectionStatus := nodebInfo.GetConnectionStatus()
 
        if connectionStatus == entities.ConnectionStatus_SHUT_DOWN {
        connectionStatus := nodebInfo.GetConnectionStatus()
 
        if connectionStatus == entities.ConnectionStatus_SHUT_DOWN {
-               m.logger.Warnf("#RanReconnectionManager.ReconnectRan - RAN name: %s - Cannot reconnect RAN. Reason: connection status is SHUT_DOWN", nodebInfo.RanName)
+               m.logger.Warnf("#RanReconnectionManager.updateUnconnectableRan - RAN name: %s - Cannot reconnect RAN. Reason: connection status is SHUT_DOWN", nodebInfo.RanName)
                return nil
        }
 
        if connectionStatus == entities.ConnectionStatus_SHUTTING_DOWN {
                return nil
        }
 
        if connectionStatus == entities.ConnectionStatus_SHUTTING_DOWN {
-               m.logger.Warnf("#RanReconnectionManager.ReconnectRan - RAN name: %s - Cannot reconnect RAN. Reason: connection status is SHUTTING_DOWN", nodebInfo.RanName)
-               return m.updateNodebInfoStatus(nodebInfo, entities.ConnectionStatus_SHUT_DOWN)
+               m.logger.Warnf("#RanReconnectionManager.updateUnconnectableRan - RAN name: %s - Cannot reconnect RAN. Reason: connection status is SHUTTING_DOWN", nodebInfo.RanName)
+               return m.updateNodebInfo(nodebInfo, entities.ConnectionStatus_SHUT_DOWN, false)
        }
 
        }
 
-       if int(nodebInfo.GetConnectionAttempts()) >= m.config.MaxConnectionAttempts {
-               m.logger.Warnf("#RanReconnectionManager.ReconnectRan - RAN name: %s - Cannot reconnect RAN. Reason: RAN's connection attempts exceeded the limit (%d)", nodebInfo.RanName, m.config.MaxConnectionAttempts)
-               return m.updateNodebInfoStatus(nodebInfo, entities.ConnectionStatus_DISCONNECTED)
+       if m.isRanExceededConnectionAttempts(nodebInfo) {
+               m.logger.Warnf("#RanReconnectionManager.updateUnconnectableRan - RAN name: %s - Cannot reconnect RAN. Reason: RAN's connection attempts exceeded the limit (%d)", nodebInfo.RanName, m.config.MaxConnectionAttempts)
+               return m.updateNodebInfo(nodebInfo, entities.ConnectionStatus_DISCONNECTED, true)
        }
 
        return nil
        }
 
        return nil
index 9ccb1fd..44a3c78 100644 (file)
@@ -24,14 +24,12 @@ import (
        "e2mgr/configuration"
        "e2mgr/logger"
        "e2mgr/mocks"
        "e2mgr/configuration"
        "e2mgr/logger"
        "e2mgr/mocks"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/tests"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/tests"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/pkg/errors"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
        "github.com/pkg/errors"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
@@ -49,19 +47,37 @@ func initRanLostConnectionTest(t *testing.T) (*logger.Logger, *mocks.RmrMessenge
        rmrSender := initRmrSender(rmrMessengerMock, logger)
 
        readerMock := &mocks.RnibReaderMock{}
        rmrSender := initRmrSender(rmrMessengerMock, logger)
 
        readerMock := &mocks.RnibReaderMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
+
        writerMock := &mocks.RnibWriterMock{}
        writerMock := &mocks.RnibWriterMock{}
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
-       rnibDataService := services.NewRnibDataService(logger, config, rnibReaderProvider, rnibWriterProvider)
+
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+       e2tInstancesManager := NewE2TInstancesManager(rnibDataService, logger)
        ranSetupManager := NewRanSetupManager(logger, rmrSender, rnibDataService)
        ranSetupManager := NewRanSetupManager(logger, rmrSender, rnibDataService)
-       ranReconnectionManager := NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, ranSetupManager)
+       ranReconnectionManager := NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, ranSetupManager, e2tInstancesManager)
        return logger, rmrMessengerMock, readerMock, writerMock, ranReconnectionManager
 }
 
        return logger, rmrMessengerMock, readerMock, writerMock, ranReconnectionManager
 }
 
+func initRanLostConnectionTestBasicMocks(t *testing.T) (*logger.Logger, *mocks.RmrMessengerMock, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *RanReconnectionManager, *mocks.E2TInstancesManagerMock) {
+       logger, err := logger.InitLogger(logger.DebugLevel)
+       if err != nil {
+               t.Errorf("#... - failed to initialize logger, error: %s", err)
+       }
+       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
+
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
+       rmrSender := initRmrSender(rmrMessengerMock, logger)
+
+       readerMock := &mocks.RnibReaderMock{}
+
+       writerMock := &mocks.RnibWriterMock{}
+
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+       e2tInstancesManagerMock := &mocks.E2TInstancesManagerMock{}
+       ranSetupManager := NewRanSetupManager(logger, rmrSender, rnibDataService)
+       ranReconnectionManager := NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, ranSetupManager, e2tInstancesManagerMock)
+       return logger, rmrMessengerMock, readerMock, writerMock, ranReconnectionManager, e2tInstancesManagerMock
+}
+
 func TestRanReconnectionGetNodebFailure(t *testing.T) {
        _, _, readerMock, writerMock, ranReconnectionManager := initRanLostConnectionTest(t)
        ranName := "test"
 func TestRanReconnectionGetNodebFailure(t *testing.T) {
        _, _, readerMock, writerMock, ranReconnectionManager := initRanLostConnectionTest(t)
        ranName := "test"
@@ -100,21 +116,48 @@ func TestShuttingdownRanReconnection(t *testing.T) {
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
 }
 
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
 }
 
-func TestConnectingRanWithMaxAttemptsReconnection(t *testing.T) {
+func TestConnectingRanWithMaxAttemptsReconnectionDissociateSucceeds(t *testing.T) {
        _, _, readerMock, writerMock, ranReconnectionManager := initRanLostConnectionTest(t)
        ranName := "test"
        _, _, readerMock, writerMock, ranReconnectionManager := initRanLostConnectionTest(t)
        ranName := "test"
-       origNodebInfo := &entities.NodebInfo{RanName: ranName, GlobalNbId: &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"}, ConnectionStatus: entities.ConnectionStatus_CONNECTING, ConnectionAttempts: 20}
+       e2tAddress := "10.0.2.15"
+       origNodebInfo := &entities.NodebInfo{RanName: ranName, GlobalNbId: &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"}, ConnectionStatus: entities.ConnectionStatus_CONNECTING, ConnectionAttempts: 20, AssociatedE2TInstanceAddress: e2tAddress}
        var rnibErr error
        readerMock.On("GetNodeb", ranName).Return(origNodebInfo, rnibErr)
        updatedNodebInfo := *origNodebInfo
        updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
        var rnibErr error
        readerMock.On("GetNodeb", ranName).Return(origNodebInfo, rnibErr)
        updatedNodebInfo := *origNodebInfo
        updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+       updatedNodebInfo.AssociatedE2TInstanceAddress = ""
        writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(rnibErr)
        writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(rnibErr)
+       e2tInstance := &entities.E2TInstance{Address:e2tAddress, AssociatedRanList:[]string{ranName}}
+       readerMock.On("GetE2TInstance",e2tAddress).Return(e2tInstance, nil)
+       e2tInstanceToSave := * e2tInstance
+       e2tInstanceToSave .AssociatedRanList = []string{}
+       writerMock.On("SaveE2TInstance", &e2tInstanceToSave).Return(nil)
        err := ranReconnectionManager.ReconnectRan(ranName)
        assert.Nil(t, err)
        readerMock.AssertCalled(t, "GetNodeb", ranName)
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
 }
 
        err := ranReconnectionManager.ReconnectRan(ranName)
        assert.Nil(t, err)
        readerMock.AssertCalled(t, "GetNodeb", ranName)
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
 }
 
+func TestConnectingRanWithMaxAttemptsReconnectionDissociateFails(t *testing.T) {
+       _, _, readerMock, writerMock, ranReconnectionManager := initRanLostConnectionTest(t)
+       ranName := "test"
+       e2tAddress := "10.0.2.15"
+       origNodebInfo := &entities.NodebInfo{RanName: ranName, GlobalNbId: &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"}, ConnectionStatus: entities.ConnectionStatus_CONNECTING, ConnectionAttempts: 20, AssociatedE2TInstanceAddress: e2tAddress}
+       var rnibErr error
+       readerMock.On("GetNodeb", ranName).Return(origNodebInfo, rnibErr)
+       updatedNodebInfo := *origNodebInfo
+       updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+       updatedNodebInfo.AssociatedE2TInstanceAddress = ""
+       writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(rnibErr)
+       e2tInstance := &entities.E2TInstance{Address:e2tAddress, AssociatedRanList:[]string{ranName}}
+       readerMock.On("GetE2TInstance",e2tAddress).Return(e2tInstance, common.NewInternalError(errors.New("Error")))
+       err := ranReconnectionManager.ReconnectRan(ranName)
+       assert.NotNil(t, err)
+       readerMock.AssertCalled(t, "GetNodeb", ranName)
+       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
+       writerMock.AssertNotCalled(t, "SaveE2TInstance", )
+}
+
 func TestUnconnectableRanUpdateNodebInfoFailure(t *testing.T) {
        _, _, readerMock, writerMock, ranReconnectionManager := initRanLostConnectionTest(t)
        ranName := "test"
 func TestUnconnectableRanUpdateNodebInfoFailure(t *testing.T) {
        _, _, readerMock, writerMock, ranReconnectionManager := initRanLostConnectionTest(t)
        ranName := "test"
@@ -140,7 +183,7 @@ func TestConnectedRanExecuteSetupSuccess(t *testing.T) {
        updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTING
        updatedNodebInfo.ConnectionAttempts++
        writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(nil)
        updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTING
        updatedNodebInfo.ConnectionAttempts++
        writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(nil)
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(&rmrCgo.MBuf{}, nil)
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(&rmrCgo.MBuf{}, nil)
        err := ranReconnectionManager.ReconnectRan(ranName)
        assert.Nil(t, err)
        readerMock.AssertCalled(t, "GetNodeb", ranName)
        err := ranReconnectionManager.ReconnectRan(ranName)
        assert.Nil(t, err)
        readerMock.AssertCalled(t, "GetNodeb", ranName)
@@ -164,8 +207,15 @@ func TestConnectedRanExecuteSetupFailure(t *testing.T) {
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
 }
 
        writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
 }
 
+func TestNoSetConnectionStatus(t *testing.T) {
+       _, _, _, _, ranReconnectionManager := initRanLostConnectionTest(t)
+       nodebInfo := &entities.NodebInfo{RanName: "ranName", GlobalNbId: &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"}, ConnectionStatus: entities.ConnectionStatus_CONNECTED}
+       err := ranReconnectionManager.updateUnconnectableRan(nodebInfo)
+       assert.Nil(t, err)
+}
+
 func initRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
 func initRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
-       return rmrsender.NewRmrSender(log, &rmrMessenger)
+       return rmrsender.NewRmrSender(log, rmrMessenger)
 }
 }
index 40b4d00..de54308 100644 (file)
@@ -37,6 +37,10 @@ type RanSetupManager struct {
        rmrSender       *rmrsender.RmrSender
 }
 
        rmrSender       *rmrsender.RmrSender
 }
 
+type IRanSetupManager interface {
+       ExecuteSetup(nodebInfo *entities.NodebInfo, status entities.ConnectionStatus) error
+}
+
 func NewRanSetupManager(logger *logger.Logger, rmrSender *rmrsender.RmrSender, rnibDataService services.RNibDataService) *RanSetupManager {
        return &RanSetupManager{
                logger:          logger,
 func NewRanSetupManager(logger *logger.Logger, rmrSender *rmrsender.RmrSender, rnibDataService services.RNibDataService) *RanSetupManager {
        return &RanSetupManager{
                logger:          logger,
@@ -105,7 +109,8 @@ func (m *RanSetupManager) ExecuteSetup(nodebInfo *entities.NodebInfo, status ent
        }
 
        // Send the endc/x2 setup request
        }
 
        // Send the endc/x2 setup request
-       msg := models.NewRmrMessage(rmrMsgType, nodebInfo.RanName, request.GetMessageAsBytes(m.logger))
+       var xAction []byte
+       msg := models.NewRmrMessage(rmrMsgType, nodebInfo.RanName, request.GetMessageAsBytes(m.logger), xAction)
 
        err = m.rmrSender.Send(msg)
 
 
        err = m.rmrSender.Send(msg)
 
index 4ea7919..4178062 100644 (file)
@@ -26,13 +26,11 @@ import (
        "e2mgr/e2pdus"
        "e2mgr/logger"
        "e2mgr/mocks"
        "e2mgr/e2pdus"
        "e2mgr/logger"
        "e2mgr/mocks"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "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"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "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"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
        "testing"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
        "testing"
@@ -49,14 +47,10 @@ func initRanSetupManagerTest(t *testing.T) (*mocks.RmrMessengerMock, *mocks.Rnib
        rmrSender := initRmrSender(rmrMessengerMock, logger)
 
        readerMock := &mocks.RnibReaderMock{}
        rmrSender := initRmrSender(rmrMessengerMock, logger)
 
        readerMock := &mocks.RnibReaderMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
+
        writerMock := &mocks.RnibWriterMock{}
        writerMock := &mocks.RnibWriterMock{}
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
-       rnibDataService := services.NewRnibDataService(logger, config, rnibReaderProvider, rnibWriterProvider)
+
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
        ranSetupManager := NewRanSetupManager(logger, rmrSender, rnibDataService)
        return rmrMessengerMock, writerMock, ranSetupManager
 }
        ranSetupManager := NewRanSetupManager(logger, rmrSender, rnibDataService)
        return rmrMessengerMock, writerMock, ranSetupManager
 }
@@ -74,7 +68,7 @@ func TestExecuteSetupConnectingX2Setup(t *testing.T) {
        payload := e2pdus.PackedX2setupRequest
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
        payload := e2pdus.PackedX2setupRequest
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err != nil {
                t.Errorf("want: success, got: error: %s", err)
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err != nil {
                t.Errorf("want: success, got: error: %s", err)
@@ -97,7 +91,7 @@ func TestExecuteSetupConnectingEndcX2Setup(t *testing.T) {
        payload := e2pdus.PackedEndcX2setupRequest
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
        payload := e2pdus.PackedEndcX2setupRequest
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err != nil {
                t.Errorf("want: success, got: error: %s", err)
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err != nil {
                t.Errorf("want: success, got: error: %s", err)
@@ -122,7 +116,7 @@ func TestExecuteSetupDisconnected(t *testing.T) {
        payload := []byte{0}
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
        payload := []byte{0}
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, fmt.Errorf("send failure"))
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, fmt.Errorf("send failure"))
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err == nil {
                t.Errorf("want: failure, got: success")
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err == nil {
                t.Errorf("want: failure, got: success")
@@ -147,7 +141,7 @@ func TestExecuteSetupConnectingRnibError(t *testing.T) {
        payload := []byte{0}
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
        payload := []byte{0}
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, fmt.Errorf("send failure"))
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, fmt.Errorf("send failure"))
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err == nil {
                t.Errorf("want: failure, got: success")
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err == nil {
                t.Errorf("want: failure, got: success")
@@ -174,7 +168,7 @@ func TestExecuteSetupDisconnectedRnibError(t *testing.T) {
        payload := []byte{0}
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
        payload := []byte{0}
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, fmt.Errorf("send failure"))
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, fmt.Errorf("send failure"))
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err == nil {
                t.Errorf("want: failure, got: success")
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err == nil {
                t.Errorf("want: failure, got: success")
@@ -199,7 +193,7 @@ func TestExecuteSetupUnsupportedProtocol(t *testing.T) {
        payload := e2pdus.PackedX2setupRequest
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
        payload := e2pdus.PackedX2setupRequest
        xaction := []byte(ranName)
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(msg, nil)
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err == nil {
                t.Errorf("want: error, got: success")
 
        if err := mgr.ExecuteSetup(initialNodeb, entities.ConnectionStatus_CONNECTING); err == nil {
                t.Errorf("want: error, got: success")
index 153255a..049cc86 100644 (file)
@@ -35,6 +35,7 @@ func (m *RanStatusChangeManager) Execute(msgType int, msgDirection enums.Message
                return err
        }
 
                return err
        }
 
-       rmrMessage := models.NewRmrMessage(msgType, nodebInfo.RanName, resourceStatusJson)
+       var xAction []byte
+       rmrMessage := models.NewRmrMessage(msgType, nodebInfo.RanName, resourceStatusJson, xAction)
        return m.rmrSender.Send(rmrMessage)
 }
        return m.rmrSender.Send(rmrMessage)
 }
index be8642e..ea9bfcd 100644 (file)
@@ -40,7 +40,7 @@ func TestMarshalSuccess(t *testing.T) {
 
        nodebInfo := entities.NodebInfo{NodeType: entities.Node_ENB}
        var err error
 
        nodebInfo := entities.NodebInfo{NodeType: entities.Node_ENB}
        var err error
-       rmrMessengerMock.On("SendMsg", mock.Anything).Return(&rmrCgo.MBuf{}, err)
+       rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(&rmrCgo.MBuf{}, err)
        err  = m.Execute(rmrCgo.RAN_CONNECTED, enums.RIC_TO_RAN, &nodebInfo)
 
        assert.Nil(t, err)
        err  = m.Execute(rmrCgo.RAN_CONNECTED, enums.RIC_TO_RAN, &nodebInfo)
 
        assert.Nil(t, err)
diff --git a/E2Manager/managers/x2_setup_failure_response_manager_test.go b/E2Manager/managers/x2_setup_failure_response_manager_test.go
new file mode 100644 (file)
index 0000000..b5e1849
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package managers
+
+import (
+       "e2mgr/converters"
+       "e2mgr/tests"
+       "fmt"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/stretchr/testify/assert"
+       "testing"
+)
+
+func TestPopulateX2NodebByPduFailure(t *testing.T) {
+       logger := tests.InitLog(t)
+       nodebInfo := &entities.NodebInfo{}
+       nodebIdentity := &entities.NbIdentity{}
+       handler := NewX2SetupFailureResponseManager(converters.NewX2SetupFailureResponseConverter(logger))
+       err := handler.PopulateNodebByPdu(logger, nodebIdentity, nodebInfo, createRandomPayload())
+       assert.NotNil(t, err)
+}
+
+func TestPopulateX2NodebByPduSuccess(t *testing.T) {
+       logger := tests.InitLog(t)
+       nodebInfo := &entities.NodebInfo{}
+       nodebIdentity := &entities.NbIdentity{}
+       handler := NewX2SetupFailureResponseManager(converters.NewX2SetupFailureResponseConverter(logger))
+       err := handler.PopulateNodebByPdu(logger, nodebIdentity, nodebInfo, createX2SetupFailureResponsePayload(t))
+       assert.Nil(t, err)
+       assert.Equal(t, entities.ConnectionStatus_CONNECTED_SETUP_FAILED, nodebInfo.ConnectionStatus)
+       assert.Equal(t, entities.Failure_X2_SETUP_FAILURE, nodebInfo.FailureType)
+
+}
+
+func createX2SetupFailureResponsePayload(t *testing.T) []byte {
+       packedPdu := "4006001a0000030005400200000016400100001140087821a00000008040"
+       var payload []byte
+       _, err := fmt.Sscanf(packedPdu, "%x", &payload)
+       if err != nil {
+               t.Errorf("convert inputPayloadAsStr to payloadAsByte. Error: %v\n", err)
+       }
+       return payload
+}
diff --git a/E2Manager/mocks/controllerMock.go b/E2Manager/mocks/controllerMock.go
deleted file mode 100644 (file)
index 7575f72..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-package mocks
-
-import (
-       "github.com/gorilla/mux"
-       "github.com/stretchr/testify/mock"
-       "net/http"
-)
-
-type ControllerMock struct {
-       mock.Mock
-}
-
-func (c *ControllerMock) GetNodeb(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 *ControllerMock) GetNodebIdList(writer http.ResponseWriter, r *http.Request){
-       c.Called()
-}
-
-
-func (c *ControllerMock) Shutdown(writer http.ResponseWriter, r *http.Request){
-       c.Called()
-}
-
-func (c *ControllerMock) X2Reset(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 *ControllerMock) X2Setup(writer http.ResponseWriter, r *http.Request){
-       writer.Header().Set("Content-Type", "application/json")
-       writer.WriteHeader(http.StatusOK)
-
-       c.Called()
-}
-
-func (c *ControllerMock) EndcSetup(writer http.ResponseWriter, r *http.Request){
-       writer.Header().Set("Content-Type", "application/json")
-       writer.WriteHeader(http.StatusOK)
-
-       c.Called()
-}
\ No newline at end of file
diff --git a/E2Manager/mocks/e2t_controller_mock.go b/E2Manager/mocks/e2t_controller_mock.go
new file mode 100644 (file)
index 0000000..d72c292
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package mocks
+
+import (
+       "github.com/stretchr/testify/mock"
+       "net/http"
+)
+
+type E2TControllerMock struct {
+       mock.Mock
+}
+
+func (m *E2TControllerMock) HandleRequest(writer http.ResponseWriter, request *http.Request) {
+       m.Called()
+}
+
+func (m *E2TControllerMock) GetE2TInstances(writer http.ResponseWriter, request *http.Request) {
+       m.Called()
+}
diff --git a/E2Manager/mocks/e2t_instances_manager_mock.go b/E2Manager/mocks/e2t_instances_manager_mock.go
new file mode 100644 (file)
index 0000000..235c76a
--- /dev/null
@@ -0,0 +1,82 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package mocks
+
+import (
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/stretchr/testify/mock"
+)
+
+type E2TInstancesManagerMock struct {
+       mock.Mock
+}
+
+func (m *E2TInstancesManagerMock) GetE2TInstance(e2tAddress string) (*entities.E2TInstance, error) {
+       args := m.Called(e2tAddress)
+
+       return args.Get(0).(*entities.E2TInstance), args.Error(1)
+}
+
+func (m *E2TInstancesManagerMock) AddE2TInstance(e2tInstanceAddress string) error {
+       args := m.Called(e2tInstanceAddress)
+       return args.Error(0)
+}
+
+func (m *E2TInstancesManagerMock) RemoveE2TInstance(e2tInstance *entities.E2TInstance) error {
+       args := m.Called(e2tInstance)
+       return args.Error(0)
+}
+
+func (m *E2TInstancesManagerMock) SelectE2TInstance() (string, error) {
+       args := m.Called()
+       return args.String(0), args.Error(1)
+}
+
+func (m *E2TInstancesManagerMock) AssociateRan(ranName string, e2tAddress string) error {
+       args := m.Called(ranName, e2tAddress)
+       return args.Error(0)
+
+}
+func (m *E2TInstancesManagerMock) DissociateRan(ranName string, e2tAddress string) error {
+       args := m.Called(ranName, e2tAddress)
+       return args.Error(0)
+
+}
+
+func (m *E2TInstancesManagerMock) GetE2TInstances() ([]*entities.E2TInstance, error) {
+       args := m.Called()
+
+       return args.Get(0).([]*entities.E2TInstance), args.Error(1)
+}
+
+func (m *E2TInstancesManagerMock) GetE2TInstancesNoLogs() ([]*entities.E2TInstance, error) {
+       args := m.Called()
+
+       return args.Get(0).([]*entities.E2TInstance), args.Error(1)
+}
+
+func (m *E2TInstancesManagerMock) ResetKeepAliveTimestamp(e2tAddress string) error {
+       args := m.Called(e2tAddress)
+       return args.Error(0)
+
+}
+
+func (m *E2TInstancesManagerMock) ActivateE2TInstance(e2tInstance *entities.E2TInstance) error {
+       args := m.Called(e2tInstance)
+       return args.Error(0)
+
+}
\ No newline at end of file
similarity index 56%
rename from E2Manager/rnibBuilders/node_info_builder.go
rename to E2Manager/mocks/e2t_shutdown_manager_mock.go
index bfee4f6..c560f1d 100644 (file)
 //  platform project (RICP).
 
 
 //  platform project (RICP).
 
 
-package rnibBuilders
+package mocks
 
 import (
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
 
 import (
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-       "e2mgr/models"
+       "github.com/stretchr/testify/mock"
 )
 
 )
 
-func CreateInitialNodeInfo(requestDetails *models.SetupRequest, protocol entities.E2ApplicationProtocol) (*entities.NodebInfo, *entities.NbIdentity) {
-       nodebInfo := &entities.NodebInfo{}
-       nodebInfo.Ip = requestDetails.RanIp
-       nodebInfo.Port = uint32(requestDetails.RanPort)
-       nodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTING
-       nodebInfo.E2ApplicationProtocol = protocol
-       nodebInfo.RanName = requestDetails.RanName
-       nodebInfo.ConnectionAttempts = 0
+type E2TShutdownManagerMock struct {
+       mock.Mock
+}
 
 
-       nodebIdentity := &entities.NbIdentity{}
-       nodebIdentity.InventoryName = requestDetails.RanName
-       return nodebInfo, nodebIdentity
+func (m *E2TShutdownManagerMock) Shutdown(e2tInstance *entities.E2TInstance) error {
+       args := m.Called(e2tInstance)
+       return args.Error(0)
 }
\ No newline at end of file
 }
\ No newline at end of file
diff --git a/E2Manager/mocks/http_client_mock.go b/E2Manager/mocks/http_client_mock.go
new file mode 100644 (file)
index 0000000..1294c48
--- /dev/null
@@ -0,0 +1,41 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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 mocks
+
+import (
+       "github.com/stretchr/testify/mock"
+       "io"
+       "net/http"
+)
+
+type HttpClientMock struct {
+       mock.Mock
+}
+
+func (c *HttpClientMock) Post(url, contentType string, body io.Reader) (resp *http.Response, err error) {
+               args := c.Called(url, contentType, body)
+               return args.Get(0).(*http.Response), args.Error(1)
+}
+
+//func (c *HttpClientMock) Do(req *http.Request) (*http.Response, error) {
+//     args := c.Called(req)
+//     return args.Get(0).(*http.Response), args.Error(1)
+//}
diff --git a/E2Manager/mocks/nodebControllerMock.go b/E2Manager/mocks/nodebControllerMock.go
deleted file mode 100644 (file)
index 51b5bf0..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package mocks
-
-import (
-       "github.com/gorilla/mux"
-       "github.com/stretchr/testify/mock"
-       "net/http"
-)
-
-type NodebControllerMock struct {
-       mock.Mock
-}
-
-func (rc *NodebControllerMock) HandleRequest(writer http.ResponseWriter, request *http.Request) {
-       rc.Called()
-}
-
-func (rc *NodebControllerMock) GetNodebIdList (writer http.ResponseWriter, request *http.Request) {
-       rc.Called()
-}
-
-func (rc *NodebControllerMock) GetNodeb(writer http.ResponseWriter, request *http.Request) {
-       writer.Header().Set("Content-Type", "application/json")
-       writer.WriteHeader(http.StatusOK)
-
-       vars := mux.Vars(request)
-       ranName := vars["ranName"]
-
-       writer.Write([]byte(ranName))
-
-       rc.Called()
-}
-
-func (rc *NodebControllerMock) HandleHealthCheckRequest(writer http.ResponseWriter, request *http.Request) {
-       rc.Called()
-}
diff --git a/E2Manager/mocks/nodeb_controller_mock.go b/E2Manager/mocks/nodeb_controller_mock.go
new file mode 100644 (file)
index 0000000..eafc935
--- /dev/null
@@ -0,0 +1,73 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package mocks
+
+import (
+       "github.com/gorilla/mux"
+       "github.com/stretchr/testify/mock"
+       "net/http"
+)
+
+type NodebControllerMock struct {
+       mock.Mock
+}
+
+func (c *NodebControllerMock) GetNodeb(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) GetNodebIdList(writer http.ResponseWriter, r *http.Request) {
+       c.Called()
+}
+
+func (c *NodebControllerMock) Shutdown(writer http.ResponseWriter, r *http.Request) {
+       c.Called()
+}
+
+func (c *NodebControllerMock) X2Reset(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) X2Setup(writer http.ResponseWriter, r *http.Request) {
+       writer.Header().Set("Content-Type", "application/json")
+       writer.WriteHeader(http.StatusOK)
+
+       c.Called()
+}
+
+func (c *NodebControllerMock) EndcSetup(writer http.ResponseWriter, r *http.Request) {
+       writer.Header().Set("Content-Type", "application/json")
+       writer.WriteHeader(http.StatusOK)
+
+       c.Called()
+}
diff --git a/E2Manager/mocks/ran_setup_manager_mock.go b/E2Manager/mocks/ran_setup_manager_mock.go
new file mode 100644 (file)
index 0000000..656657c
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package mocks
+
+import (
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/stretchr/testify/mock"
+)
+
+type RanSetupManagerMock struct {
+       mock.Mock
+}
+
+func (m *RanSetupManagerMock) ExecuteSetup(nodebInfo *entities.NodebInfo, status entities.ConnectionStatus) error {
+       args := m.Called(nodebInfo, status)
+
+       return args.Error(0)
+}
index dccd7d0..b517fe9 100644 (file)
@@ -30,13 +30,13 @@ type RmrMessengerMock struct {
        mock.Mock
 }
 
        mock.Mock
 }
 
-func (m *RmrMessengerMock) Init(port string, maxMsgSize int, flags int, logger *logger.Logger) *rmrCgo.RmrMessenger{
+func (m *RmrMessengerMock) Init(port string, maxMsgSize int, flags int, logger *logger.Logger) rmrCgo.RmrMessenger{
        args := m.Called(port, maxMsgSize, flags, logger)
        args := m.Called(port, maxMsgSize, flags, logger)
-       return args.Get(0).(*rmrCgo.RmrMessenger)
+       return args.Get(0).(rmrCgo.RmrMessenger)
 }
 
 }
 
-func (m *RmrMessengerMock) SendMsg(msg *rmrCgo.MBuf) (*rmrCgo.MBuf, error){
-       args := m.Called(msg)
+func (m *RmrMessengerMock) SendMsg(msg *rmrCgo.MBuf, printLogs bool) (*rmrCgo.MBuf, error){
+       args := m.Called(msg, printLogs)
        return args.Get(0).(*rmrCgo.MBuf), args.Error(1)
 }
 
        return args.Get(0).(*rmrCgo.MBuf), args.Error(1)
 }
 
index 237cdac..59c635e 100644 (file)
@@ -32,7 +32,6 @@ func (m *RnibReaderMock) GetNodeb(inventoryName string) (*entities.NodebInfo, er
        args := m.Called(inventoryName)
 
        errArg := args.Get(1);
        args := m.Called(inventoryName)
 
        errArg := args.Get(1);
-
        if errArg != nil {
                return args.Get(0).(*entities.NodebInfo), errArg.(error);
        }
        if errArg != nil {
                return args.Get(0).(*entities.NodebInfo), errArg.(error);
        }
@@ -44,7 +43,6 @@ func (m *RnibReaderMock) GetNodebByGlobalNbId(nodeType entities.Node_Type, globa
        args := m.Called(nodeType, globalNbId)
 
        errArg := args.Get(1);
        args := m.Called(nodeType, globalNbId)
 
        errArg := args.Get(1);
-
        if errArg != nil {
                return args.Get(0).(*entities.NodebInfo), errArg.(error);
        }
        if errArg != nil {
                return args.Get(0).(*entities.NodebInfo), errArg.(error);
        }
@@ -56,7 +54,6 @@ func (m *RnibReaderMock) GetCellList(inventoryName string) (*entities.Cells, err
        args := m.Called(inventoryName)
 
        errArg := args.Get(1);
        args := m.Called(inventoryName)
 
        errArg := args.Get(1);
-
        if errArg != nil {
                return args.Get(0).(*entities.Cells), errArg.(error);
        }
        if errArg != nil {
                return args.Get(0).(*entities.Cells), errArg.(error);
        }
@@ -68,7 +65,6 @@ func (m *RnibReaderMock) GetListGnbIds() ([]*entities.NbIdentity, error) {
        args := m.Called()
 
        errArg := args.Get(1);
        args := m.Called()
 
        errArg := args.Get(1);
-
        if errArg != nil {
                return args.Get(0).([]*entities.NbIdentity), errArg.(error);
        }
        if errArg != nil {
                return args.Get(0).([]*entities.NbIdentity), errArg.(error);
        }
@@ -80,7 +76,6 @@ func (m *RnibReaderMock) GetListEnbIds() ([]*entities.NbIdentity, error) {
        args := m.Called()
 
        errArg := args.Get(1);
        args := m.Called()
 
        errArg := args.Get(1);
-
        if errArg != nil {
                return args.Get(0).([]*entities.NbIdentity), errArg.(error);
        }
        if errArg != nil {
                return args.Get(0).([]*entities.NbIdentity), errArg.(error);
        }
@@ -93,7 +88,6 @@ func (m *RnibReaderMock) GetCountGnbList() (int, error) {
        args := m.Called()
 
        errArg := args.Get(1);
        args := m.Called()
 
        errArg := args.Get(1);
-
        if errArg != nil {
                return args.Int(0), errArg.(error);
        }
        if errArg != nil {
                return args.Int(0), errArg.(error);
        }
@@ -106,7 +100,6 @@ func (m *RnibReaderMock) GetCell(inventoryName string, pci uint32) (*entities.Ce
        args := m.Called(inventoryName, pci)
 
        errArg := args.Get(1);
        args := m.Called(inventoryName, pci)
 
        errArg := args.Get(1);
-
        if errArg != nil {
                return args.Get(0).(*entities.Cell), errArg.(error);
        }
        if errArg != nil {
                return args.Get(0).(*entities.Cell), errArg.(error);
        }
@@ -118,7 +111,6 @@ func (m *RnibReaderMock) GetCellById(cellType entities.Cell_Type, cellId string)
        args := m.Called(cellType, cellId)
 
        errArg := args.Get(1);
        args := m.Called(cellType, cellId)
 
        errArg := args.Get(1);
-
        if errArg != nil {
                return args.Get(0).(*entities.Cell), errArg.(error);
        }
        if errArg != nil {
                return args.Get(0).(*entities.Cell), errArg.(error);
        }
@@ -149,3 +141,18 @@ func (m *RnibReaderMock) GetRanLoadInformation(inventoryName string) (*entities.
 
        return args.Get(0).(*entities.RanLoadInformation), nil
 }
 
        return args.Get(0).(*entities.RanLoadInformation), nil
 }
+
+func (m *RnibReaderMock) GetE2TInstance(e2taddress string) (*entities.E2TInstance, error) {
+       args := m.Called(e2taddress)
+       return args.Get(0).(*entities.E2TInstance), args.Error(1)
+}
+
+func (m *RnibReaderMock) GetE2TInstances(addresses []string) ([]*entities.E2TInstance, error) {
+       args := m.Called(addresses)
+       return args.Get(0).([]*entities.E2TInstance), args.Error(1)
+}
+
+func (m *RnibReaderMock) GetE2TAddresses() ([]string, error) {
+       args := m.Called()
+       return args.Get(0).([]string), args.Error(1)
+}
index 53ec47a..5ca925f 100644 (file)
@@ -64,3 +64,15 @@ func (rnibWriterMock *RnibWriterMock) SaveRanLoadInformation(inventoryName strin
 
        return nil
 }
 
        return nil
 }
+
+func (rnibWriterMock *RnibWriterMock) SaveE2TInstance(e2tInstance *entities.E2TInstance) error {
+       args := rnibWriterMock.Called(e2tInstance)
+
+       return args.Error(0)
+}
+
+func (rnibWriterMock *RnibWriterMock) SaveE2TAddresses(addresses []string) error {
+       args := rnibWriterMock.Called(addresses)
+
+       return args.Error(0)
+}
diff --git a/E2Manager/mocks/root_controller_mock.go b/E2Manager/mocks/root_controller_mock.go
new file mode 100644 (file)
index 0000000..df58b61
--- /dev/null
@@ -0,0 +1,31 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package mocks
+
+import (
+       "github.com/stretchr/testify/mock"
+       "net/http"
+)
+
+type RootControllerMock struct {
+       mock.Mock
+}
+
+func (rc *RootControllerMock) HandleHealthCheckRequest(writer http.ResponseWriter, request *http.Request) {
+       rc.Called()
+}
diff --git a/E2Manager/mocks/routing_manager_client_mock.go b/E2Manager/mocks/routing_manager_client_mock.go
new file mode 100644 (file)
index 0000000..24edd55
--- /dev/null
@@ -0,0 +1,46 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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 mocks
+
+import (
+       "github.com/stretchr/testify/mock"
+)
+
+type RoutingManagerClientMock struct {
+       mock.Mock
+}
+
+func (m *RoutingManagerClientMock) AddE2TInstance(e2tAddress string) error {
+
+       args := m.Called(e2tAddress)
+       return args.Error(0)
+}
+
+func (m *RoutingManagerClientMock) AssociateRanToE2TInstance(e2tAddress string, ranName string) error {
+
+       args := m.Called(e2tAddress, ranName)
+       return args.Error(0)
+}
+
+func (m *RoutingManagerClientMock) DissociateRanE2TInstance(e2tAddress string, ranName string) error {
+
+       args := m.Called(e2tAddress, ranName)
+       return args.Error(0)
+}
\ No newline at end of file
index eac92b0..e7ca8c7 100644 (file)
 //  platform project (RICP).
 
 
 //  platform project (RICP).
 
 
-package models
+package models_test
 
 import (
        "e2mgr/logger"
 
 import (
        "e2mgr/logger"
+       "e2mgr/models"
        "e2mgr/tests"
        "encoding/hex"
        "github.com/stretchr/testify/assert"
        "e2mgr/tests"
        "encoding/hex"
        "github.com/stretchr/testify/assert"
@@ -29,12 +30,12 @@ import (
 )
 
 const transactionId = "transactionId"
 )
 
 const transactionId = "transactionId"
-const expectedMessageAsBytesHex = "31302e302e302e337c353535357c746573747c347c01020304"
+const expectedMessageAsBytesHex = "31302e302e302e337c333830317c746573747c347c01020304"
 
 func TestNewE2RequestMessage(t *testing.T){
 
 func TestNewE2RequestMessage(t *testing.T){
-       e2 :=NewE2RequestMessage(transactionId, tests.RanIp, uint16(tests.Port), tests.RanName, tests.DummyPayload)
+       e2 :=models.NewE2RequestMessage(transactionId, tests.RanIp, uint16(tests.Port), tests.RanName, tests.DummyPayload)
        assert.NotNil(t, e2)
        assert.NotNil(t, e2)
-       assert.IsType(t, *e2, E2RequestMessage{})
+       assert.IsType(t, *e2, models.E2RequestMessage{})
        assert.Equal(t, tests.RanName, e2.RanName())
        assert.Equal(t, transactionId, e2.TransactionId())
 }
        assert.Equal(t, tests.RanName, e2.RanName())
        assert.Equal(t, transactionId, e2.TransactionId())
 }
@@ -45,7 +46,7 @@ func TestGetMessageAsBytes(t *testing.T){
                t.Errorf("#nodeb_controller_test.TestHandleRequestSuccess - failed to initialize logger, error: %s", err)
        }
 
                t.Errorf("#nodeb_controller_test.TestHandleRequestSuccess - failed to initialize logger, error: %s", err)
        }
 
-       e2 :=NewE2RequestMessage(transactionId, tests.RanIp, uint16(tests.Port), tests.RanName, tests.DummyPayload)
+       e2 := models.NewE2RequestMessage(transactionId, tests.RanIp, uint16(tests.Port), tests.RanName, tests.DummyPayload)
        bytes := e2.GetMessageAsBytes(log)
        assert.Equal(t, expectedMessageAsBytesHex, hex.EncodeToString(bytes))
 }
\ No newline at end of file
        bytes := e2.GetMessageAsBytes(log)
        assert.Equal(t, expectedMessageAsBytesHex, hex.EncodeToString(bytes))
 }
\ No newline at end of file
diff --git a/E2Manager/models/e2_term_init_payload.go b/E2Manager/models/e2_term_init_payload.go
new file mode 100644 (file)
index 0000000..e533582
--- /dev/null
@@ -0,0 +1,22 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package models
+
+type E2TermInitPayload struct {
+       Address string     `json:"address"`
+       Fqdn string     `json:"fqdn"`
+}
\ No newline at end of file
diff --git a/E2Manager/models/e2t_keep_alive_payload.go b/E2Manager/models/e2t_keep_alive_payload.go
new file mode 100644 (file)
index 0000000..cdc8ba6
--- /dev/null
@@ -0,0 +1,21 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package models
+
+type E2TKeepAlivePayload struct {
+       Address string     `json:"address"`
+}
\ No newline at end of file
diff --git a/E2Manager/models/get_e2t_instances_response.go b/E2Manager/models/get_e2t_instances_response.go
new file mode 100644 (file)
index 0000000..f39c1ff
--- /dev/null
@@ -0,0 +1,49 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package models
+
+import (
+       "e2mgr/e2managererrors"
+       "encoding/json"
+)
+
+type E2TInstancesResponse []*E2TInstanceResponseModel
+
+type E2TInstanceResponseModel struct {
+       E2TAddress string   `json:"e2tAddress"`
+       RanNames   []string `json:"ranNames"`
+}
+
+func NewE2TInstanceResponseModel(e2tAddress string, ranNames []string) *E2TInstanceResponseModel {
+       return &E2TInstanceResponseModel{
+               E2TAddress: e2tAddress,
+               RanNames:   ranNames,
+       }
+}
+
+func (response E2TInstancesResponse) Marshal() ([]byte, error) {
+
+       data, err := json.Marshal(response)
+
+       if err != nil {
+               return nil, e2managererrors.NewInternalError()
+       }
+
+       return data, nil
+
+}
index dfafab5..7ed83aa 100644 (file)
@@ -36,13 +36,13 @@ func NewGetNodebIdListResponse(nodebIdList []*entities.NbIdentity) *GetNodebIdLi
        }
 }
 
        }
 }
 
-func (response *GetNodebIdListResponse) Marshal() (string, error) {
+func (response *GetNodebIdListResponse) Marshal() ([]byte, error) {
        pmList := utils.ConvertNodebIdListToProtoMessageList(response.nodebIdList)
        result, err := utils.MarshalProtoMessageListToJsonArray(pmList)
 
        if err != nil {
        pmList := utils.ConvertNodebIdListToProtoMessageList(response.nodebIdList)
        result, err := utils.MarshalProtoMessageListToJsonArray(pmList)
 
        if err != nil {
-               return "", e2managererrors.NewInternalError();
+               return nil, e2managererrors.NewInternalError();
        }
 
        }
 
-       return result, nil
+       return []byte(result), nil
 }
 }
index 9474465..1eaa32a 100644 (file)
@@ -36,14 +36,14 @@ func NewGetNodebResponse(nodebInfo *entities.NodebInfo) *GetNodebResponse {
        }
 }
 
        }
 }
 
-func (response *GetNodebResponse) Marshal() (string, error) {
+func (response *GetNodebResponse) Marshal() ([]byte, error) {
        m := jsonpb.Marshaler{}
        result, err := m.MarshalToString(response.nodebInfo)
 
        if err != nil {
        m := jsonpb.Marshaler{}
        result, err := m.MarshalToString(response.nodebInfo)
 
        if err != nil {
-               return "", e2managererrors.NewInternalError()
+               return nil, e2managererrors.NewInternalError()
        }
 
        }
 
-       return result, nil
+       return []byte(result), nil
 
 }
 
 }
index 531fbbd..9620297 100644 (file)
@@ -21,5 +21,5 @@
 package models
 
 type IResponse interface {
 package models
 
 type IResponse interface {
-       Marshal() (string, error)
+       Marshal() ([]byte, error)
 }
 }
index 7e3892a..b275587 100644 (file)
@@ -27,10 +27,10 @@ type NotificationRequest struct {
        Len           int
        Payload       []byte
        StartTime     time.Time
        Len           int
        Payload       []byte
        StartTime     time.Time
-       TransactionId string
+       TransactionId []byte
 }
 
 }
 
-func NewNotificationRequest(ranName string, payload []byte, startTime time.Time, transactionId string) *NotificationRequest {
+func NewNotificationRequest(ranName string, payload []byte, startTime time.Time, transactionId []byte) *NotificationRequest {
        return &NotificationRequest{
                ranName,
                len(payload),
        return &NotificationRequest{
                ranName,
                len(payload),
index 5fd39f8..1971b1e 100644 (file)
 
 package models
 
 
 package models
 
-import (
-       "e2mgr/logger"
-)
-
 type RmrMessage struct {
        MsgType int
        RanName string
        Payload []byte
 type RmrMessage struct {
        MsgType int
        RanName string
        Payload []byte
+       XAction []byte
 }
 
 }
 
-func NewRmrMessage(msgType int, ranName string, payload []byte) *RmrMessage {
+func NewRmrMessage(msgType int, ranName string, payload []byte, xAction []byte) *RmrMessage {
        return &RmrMessage{
                MsgType: msgType,
                RanName: ranName,
                Payload: payload,
        return &RmrMessage{
                MsgType: msgType,
                RanName: ranName,
                Payload: payload,
+               XAction: xAction,
        }
 }
        }
 }
-
-func (response RmrMessage) GetMessageAsBytes(logger *logger.Logger) []byte {
-       return response.Payload
-}
diff --git a/E2Manager/models/routing_manager_e2t_data.go b/E2Manager/models/routing_manager_e2t_data.go
new file mode 100644 (file)
index 0000000..9e8e313
--- /dev/null
@@ -0,0 +1,41 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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 RoutingManagerE2TData struct {
+       E2TAddress  string   `json:"E2TAddress"`
+       RanNamelist []string `json:"ranNamelist,omitempty"`
+}
+
+func NewRoutingManagerE2TData (e2tAddress string, ranNameList ...string) *RoutingManagerE2TData {
+       data := &RoutingManagerE2TData{
+               E2TAddress: e2tAddress,
+       }
+
+       if len(ranNameList) == 0 {
+               return data
+       }
+
+       for _, ranName := range ranNameList {
+               data.RanNamelist = append(data.RanNamelist, ranName)
+       }
+
+       return data
+}
index 70c2327..1e601f9 100644 (file)
@@ -33,12 +33,13 @@ import (
 type IncomingRequest string
 
 const (
 type IncomingRequest string
 
 const (
-       ShutdownRequest       IncomingRequest = "Shutdown"
-       ResetRequest          IncomingRequest = "Reset"
-       X2SetupRequest        IncomingRequest = "X2SetupRequest"
-       EndcSetupRequest      IncomingRequest = "EndcSetupRequest"
-       GetNodebRequest       IncomingRequest = "GetNodebRequest"
-       GetNodebIdListRequest IncomingRequest = "GetNodebIdListRequest"
+       ShutdownRequest        IncomingRequest = "Shutdown"
+       ResetRequest           IncomingRequest = "Reset"
+       X2SetupRequest         IncomingRequest = "X2SetupRequest"
+       EndcSetupRequest       IncomingRequest = "EndcSetupRequest"
+       GetNodebRequest        IncomingRequest = "GetNodebRequest"
+       GetNodebIdListRequest  IncomingRequest = "GetNodebIdListRequest"
+       GetE2TInstancesRequest IncomingRequest = "GetE2TInstancesRequest"
 )
 
 type IncomingRequestHandlerProvider struct {
 )
 
 type IncomingRequestHandlerProvider struct {
@@ -46,23 +47,24 @@ type IncomingRequestHandlerProvider struct {
        logger     *logger.Logger
 }
 
        logger     *logger.Logger
 }
 
-func NewIncomingRequestHandlerProvider(logger *logger.Logger, rmrSender *rmrsender.RmrSender, config *configuration.Configuration, rNibDataService services.RNibDataService, ranSetupManager *managers.RanSetupManager) *IncomingRequestHandlerProvider {
+func NewIncomingRequestHandlerProvider(logger *logger.Logger, rmrSender *rmrsender.RmrSender, config *configuration.Configuration, rNibDataService services.RNibDataService, ranSetupManager *managers.RanSetupManager, e2tInstancesManager managers.IE2TInstancesManager) *IncomingRequestHandlerProvider {
 
        return &IncomingRequestHandlerProvider{
 
        return &IncomingRequestHandlerProvider{
-               requestMap: initRequestHandlerMap(logger, rmrSender, config, rNibDataService, ranSetupManager),
+               requestMap: initRequestHandlerMap(logger, rmrSender, config, rNibDataService, ranSetupManager, e2tInstancesManager),
                logger:     logger,
        }
 }
 
                logger:     logger,
        }
 }
 
-func initRequestHandlerMap(logger *logger.Logger, rmrSender *rmrsender.RmrSender, config *configuration.Configuration, rNibDataService services.RNibDataService, ranSetupManager *managers.RanSetupManager) map[IncomingRequest]httpmsghandlers.RequestHandler {
+func initRequestHandlerMap(logger *logger.Logger, rmrSender *rmrsender.RmrSender, config *configuration.Configuration, rNibDataService services.RNibDataService, ranSetupManager *managers.RanSetupManager, e2tInstancesManager managers.IE2TInstancesManager) map[IncomingRequest]httpmsghandlers.RequestHandler {
 
        return map[IncomingRequest]httpmsghandlers.RequestHandler{
 
        return map[IncomingRequest]httpmsghandlers.RequestHandler{
-               ShutdownRequest:  httpmsghandlers.NewDeleteAllRequestHandler(logger, rmrSender, config, rNibDataService), //TODO change to pointer
-               ResetRequest:     httpmsghandlers.NewX2ResetRequestHandler(logger, rmrSender, rNibDataService),
-               X2SetupRequest:   httpmsghandlers.NewSetupRequestHandler(logger, rNibDataService, ranSetupManager, entities.E2ApplicationProtocol_X2_SETUP_REQUEST),
-               EndcSetupRequest: httpmsghandlers.NewSetupRequestHandler(logger, rNibDataService, ranSetupManager, entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST), //TODO change to pointer
-               GetNodebRequest:  httpmsghandlers.NewGetNodebRequestHandler(logger, rNibDataService),
-               GetNodebIdListRequest: httpmsghandlers.NewGetNodebIdListRequestHandler(logger, rNibDataService),
+               ShutdownRequest:        httpmsghandlers.NewDeleteAllRequestHandler(logger, rmrSender, config, rNibDataService), //TODO change to pointer
+               ResetRequest:           httpmsghandlers.NewX2ResetRequestHandler(logger, rmrSender, rNibDataService),
+               X2SetupRequest:         httpmsghandlers.NewSetupRequestHandler(logger, rNibDataService, ranSetupManager, entities.E2ApplicationProtocol_X2_SETUP_REQUEST, e2tInstancesManager),
+               EndcSetupRequest:       httpmsghandlers.NewSetupRequestHandler(logger, rNibDataService, ranSetupManager, entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, e2tInstancesManager),
+               GetNodebRequest:        httpmsghandlers.NewGetNodebRequestHandler(logger, rNibDataService),
+               GetNodebIdListRequest:  httpmsghandlers.NewGetNodebIdListRequestHandler(logger, rNibDataService),
+               GetE2TInstancesRequest: httpmsghandlers.NewGetE2TInstancesRequestHandler(logger, e2tInstancesManager),
        }
 }
 
        }
 }
 
index 73dfbf6..840d9c2 100644 (file)
@@ -27,12 +27,10 @@ import (
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/mocks"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/tests"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/tests"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/assert"
        "reflect"
        "testing"
        "github.com/stretchr/testify/assert"
        "reflect"
        "testing"
@@ -41,23 +39,20 @@ import (
 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
-       return rmrsender.NewRmrSender(log, &rmrMessenger)
+       return rmrsender.NewRmrSender(log, rmrMessenger)
 }
 
 func setupTest(t *testing.T) *IncomingRequestHandlerProvider {
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        log := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
 }
 
 func setupTest(t *testing.T) *IncomingRequestHandlerProvider {
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        log := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
-       readerProvider := func() reader.RNibReader {
-               return &mocks.RnibReaderMock{}
-       }
-       writerProvider := func() rNibWriter.RNibWriter {
-               return &mocks.RnibWriterMock{}
-       }
-       rnibDataService := services.NewRnibDataService(log, config, readerProvider, writerProvider)
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
+       rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
        rmrSender := getRmrSender(rmrMessengerMock, log)
        ranSetupManager := managers.NewRanSetupManager(log, rmrSender, rnibDataService)
        rmrSender := getRmrSender(rmrMessengerMock, log)
        ranSetupManager := managers.NewRanSetupManager(log, rmrSender, rnibDataService)
-       return NewIncomingRequestHandlerProvider(log, rmrSender, configuration.ParseConfiguration(), rnibDataService, ranSetupManager)
+       e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, log)
+       return NewIncomingRequestHandlerProvider(log, rmrSender, configuration.ParseConfiguration(), rnibDataService, ranSetupManager, e2tInstancesManager)
 }
 
 func TestNewIncomingRequestHandlerProvider(t *testing.T) {
 }
 
 func TestNewIncomingRequestHandlerProvider(t *testing.T) {
index 55c786b..b161c93 100644 (file)
@@ -21,6 +21,8 @@
 package rmrmsghandlerprovider
 
 import (
 package rmrmsghandlerprovider
 
 import (
+       "e2mgr/clients"
+       "e2mgr/configuration"
        "e2mgr/converters"
        "e2mgr/handlers/rmrmsghandlers"
        "e2mgr/logger"
        "e2mgr/converters"
        "e2mgr/handlers/rmrmsghandlers"
        "e2mgr/logger"
@@ -35,28 +37,13 @@ type NotificationHandlerProvider struct {
        notificationHandlers map[int]rmrmsghandlers.NotificationHandler
 }
 
        notificationHandlers map[int]rmrmsghandlers.NotificationHandler
 }
 
-func NewNotificationHandlerProvider(logger *logger.Logger, rnibDataService services.RNibDataService, ranReconnectionManager *managers.RanReconnectionManager, ranStatusChangeManager *managers.RanStatusChangeManager, rmrSender *rmrsender.RmrSender, x2SetupResponseManager *managers.X2SetupResponseManager, x2SetupFailureResponseManager *managers.X2SetupFailureResponseManager) *NotificationHandlerProvider {
+func NewNotificationHandlerProvider() *NotificationHandlerProvider {
        return &NotificationHandlerProvider{
        return &NotificationHandlerProvider{
-               notificationHandlers: initNotificationHandlersMap(logger, rnibDataService, ranReconnectionManager, ranStatusChangeManager, rmrSender, x2SetupResponseManager, x2SetupFailureResponseManager),
-       }
-}
-
-func initNotificationHandlersMap(logger *logger.Logger, rnibDataService services.RNibDataService, ranReconnectionManager *managers.RanReconnectionManager, ranStatusChangeManager *managers.RanStatusChangeManager, rmrSender *rmrsender.RmrSender, x2SetupResponseManager *managers.X2SetupResponseManager, x2SetupFailureResponseManager *managers.X2SetupFailureResponseManager) map[int]rmrmsghandlers.NotificationHandler {
-       return map[int]rmrmsghandlers.NotificationHandler{
-               rmrCgo.RIC_X2_SETUP_RESP:           rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, x2SetupResponseManager, ranStatusChangeManager, rmrCgo.RIC_X2_SETUP_RESP),
-               rmrCgo.RIC_X2_SETUP_FAILURE:        rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, x2SetupFailureResponseManager, nil, rmrCgo.RIC_X2_SETUP_FAILURE),
-               rmrCgo.RIC_ENDC_X2_SETUP_RESP:      rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, managers.NewEndcSetupResponseManager(), ranStatusChangeManager, rmrCgo.RIC_ENDC_X2_SETUP_RESP),
-               rmrCgo.RIC_ENDC_X2_SETUP_FAILURE:   rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, managers.NewEndcSetupFailureResponseManager(), nil, rmrCgo.RIC_ENDC_X2_SETUP_FAILURE),
-               rmrCgo.RIC_SCTP_CONNECTION_FAILURE: rmrmsghandlers.NewRanLostConnectionHandler(logger, ranReconnectionManager),
-               rmrCgo.RIC_ENB_LOAD_INFORMATION:    rmrmsghandlers.NewEnbLoadInformationNotificationHandler(logger, rnibDataService, converters.NewEnbLoadInformationExtractor(logger)),
-               rmrCgo.RIC_ENB_CONF_UPDATE:         rmrmsghandlers.NewX2EnbConfigurationUpdateHandler(logger, rmrSender),
-               rmrCgo.RIC_ENDC_CONF_UPDATE:        rmrmsghandlers.NewEndcConfigurationUpdateHandler(logger, rmrSender),
-               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_E2_TERM_INIT:            rmrmsghandlers.NewE2TermInitNotificationHandler(logger, ranReconnectionManager, rnibDataService),
+               notificationHandlers: map[int]rmrmsghandlers.NotificationHandler{},
        }
 }
 
        }
 }
 
+// TODO: check whether it has been initialized
 func (provider NotificationHandlerProvider) GetNotificationHandler(messageType int) (rmrmsghandlers.NotificationHandler, error) {
        handler, ok := provider.notificationHandlers[messageType]
 
 func (provider NotificationHandlerProvider) GetNotificationHandler(messageType int) (rmrmsghandlers.NotificationHandler, error) {
        handler, ok := provider.notificationHandlers[messageType]
 
@@ -66,3 +53,53 @@ func (provider NotificationHandlerProvider) GetNotificationHandler(messageType i
 
        return handler, nil
 }
 
        return handler, nil
 }
+
+func (provider *NotificationHandlerProvider) Register(msgType int, handler rmrmsghandlers.NotificationHandler) {
+       provider.notificationHandlers[msgType] = handler
+}
+
+func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config *configuration.Configuration, rnibDataService services.RNibDataService, rmrSender *rmrsender.RmrSender, ranSetupManager *managers.RanSetupManager, e2tInstancesManager managers.IE2TInstancesManager, routingManagerClient clients.IRoutingManagerClient) {
+
+       // Init converters
+       x2SetupResponseConverter := converters.NewX2SetupResponseConverter(logger)
+       x2SetupFailureResponseConverter := converters.NewX2SetupFailureResponseConverter(logger)
+       endcSetupResponseConverter := converters.NewEndcSetupResponseConverter(logger)
+       endcSetupFailureResponseConverter := converters.NewEndcSetupFailureResponseConverter(logger)
+       enbLoadInformationExtractor := converters.NewEnbLoadInformationExtractor(logger)
+       x2ResetResponseExtractor := converters.NewX2ResetResponseExtractor(logger)
+
+       // Init managers
+       ranReconnectionManager := managers.NewRanReconnectionManager(logger, config, rnibDataService, ranSetupManager, e2tInstancesManager)
+       ranStatusChangeManager := managers.NewRanStatusChangeManager(logger, rmrSender)
+       x2SetupResponseManager := managers.NewX2SetupResponseManager(x2SetupResponseConverter)
+       x2SetupFailureResponseManager := managers.NewX2SetupFailureResponseManager(x2SetupFailureResponseConverter)
+       endcSetupResponseManager := managers.NewEndcSetupResponseManager(endcSetupResponseConverter)
+       endcSetupFailureResponseManager := managers.NewEndcSetupFailureResponseManager(endcSetupFailureResponseConverter)
+
+       // Init handlers
+       x2SetupResponseHandler := rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, x2SetupResponseManager, ranStatusChangeManager, rmrCgo.RIC_X2_SETUP_RESP)
+       x2SetupFailureResponseHandler := rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, x2SetupFailureResponseManager, nil, rmrCgo.RIC_X2_SETUP_FAILURE)
+       endcSetupResponseHandler := rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, endcSetupResponseManager, ranStatusChangeManager, rmrCgo.RIC_ENDC_X2_SETUP_RESP)
+       endcSetupFailureResponseHandler := rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, endcSetupFailureResponseManager, nil, rmrCgo.RIC_ENDC_X2_SETUP_FAILURE)
+       ranLostConnectionHandler := rmrmsghandlers.NewRanLostConnectionHandler(logger, ranReconnectionManager)
+       enbLoadInformationNotificationHandler := rmrmsghandlers.NewEnbLoadInformationNotificationHandler(logger, rnibDataService, enbLoadInformationExtractor)
+       x2EnbConfigurationUpdateHandler := rmrmsghandlers.NewX2EnbConfigurationUpdateHandler(logger, rmrSender)
+       endcConfigurationUpdateHandler := rmrmsghandlers.NewEndcConfigurationUpdateHandler(logger, rmrSender)
+       x2ResetResponseHandler := rmrmsghandlers.NewX2ResetResponseHandler(logger, rnibDataService, ranStatusChangeManager, x2ResetResponseExtractor)
+       x2ResetRequestNotificationHandler := rmrmsghandlers.NewX2ResetRequestNotificationHandler(logger, rnibDataService, ranStatusChangeManager, rmrSender)
+       e2TermInitNotificationHandler := rmrmsghandlers.NewE2TermInitNotificationHandler(logger, ranReconnectionManager, rnibDataService, e2tInstancesManager, routingManagerClient)
+       e2TKeepAliveResponseHandler := rmrmsghandlers.NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManager)
+
+       provider.Register(rmrCgo.RIC_X2_SETUP_RESP, x2SetupResponseHandler)
+       provider.Register(rmrCgo.RIC_X2_SETUP_FAILURE, x2SetupFailureResponseHandler)
+       provider.Register(rmrCgo.RIC_ENDC_X2_SETUP_RESP, endcSetupResponseHandler)
+       provider.Register(rmrCgo.RIC_ENDC_X2_SETUP_FAILURE, endcSetupFailureResponseHandler)
+       provider.Register(rmrCgo.RIC_SCTP_CONNECTION_FAILURE, ranLostConnectionHandler)
+       provider.Register(rmrCgo.RIC_ENB_LOAD_INFORMATION, enbLoadInformationNotificationHandler)
+       provider.Register(rmrCgo.RIC_ENB_CONF_UPDATE, x2EnbConfigurationUpdateHandler)
+       provider.Register(rmrCgo.RIC_ENDC_CONF_UPDATE, endcConfigurationUpdateHandler)
+       provider.Register(rmrCgo.RIC_X2_RESET_RESP, x2ResetResponseHandler)
+       provider.Register(rmrCgo.RIC_X2_RESET, x2ResetRequestNotificationHandler)
+       provider.Register(rmrCgo.RIC_E2_TERM_INIT, e2TermInitNotificationHandler)
+       provider.Register(rmrCgo.E2_TERM_KEEP_ALIVE_RESP, e2TKeepAliveResponseHandler)
+}
index d86b55d..fb5dadb 100644 (file)
 package rmrmsghandlerprovider
 
 import (
 package rmrmsghandlerprovider
 
 import (
+       "e2mgr/clients"
        "e2mgr/configuration"
        "e2mgr/converters"
        "e2mgr/handlers/rmrmsghandlers"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/configuration"
        "e2mgr/converters"
        "e2mgr/handlers/rmrmsghandlers"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/mocks"
-       "e2mgr/rNibWriter"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/tests"
        "fmt"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/tests"
        "fmt"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "strings"
        "testing"
 
        "strings"
        "testing"
 
@@ -43,23 +42,28 @@ import (
  * Verify support for known providers.
  */
 
  * Verify support for known providers.
  */
 
-func initTestCase(t *testing.T) (*logger.Logger, services.RNibDataService, *managers.RanReconnectionManager, *managers.RanStatusChangeManager, *rmrsender.RmrSender, *managers.X2SetupResponseManager, *managers.X2SetupFailureResponseManager) {
+func initTestCase(t *testing.T) (*logger.Logger, *configuration.Configuration, services.RNibDataService, *rmrsender.RmrSender, *managers.RanSetupManager, managers.IE2TInstancesManager, clients.IRoutingManagerClient) {
        logger := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
 
        readerMock := &mocks.RnibReaderMock{}
        logger := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
 
        readerMock := &mocks.RnibReaderMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
        writerMock := &mocks.RnibWriterMock{}
        writerMock := &mocks.RnibWriterMock{}
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
+       httpClient := &mocks.HttpClientMock{}
 
        rmrSender := initRmrSender(&mocks.RmrMessengerMock{}, logger)
 
        rmrSender := initRmrSender(&mocks.RmrMessengerMock{}, logger)
-       rnibDataService := services.NewRnibDataService(logger, config, rnibReaderProvider, rnibWriterProvider)
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
-       ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, ranSetupManager)
+       e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, logger)
+       routingManagerClient := clients.NewRoutingManagerClient(logger, config, httpClient)
+
+       return logger, config, rnibDataService, rmrSender, ranSetupManager, e2tInstancesManager, routingManagerClient
+}
+
+func TestGetNotificationHandlerSuccess(t *testing.T) {
+
+       logger, config, rnibDataService, rmrSender, ranSetupManager, e2tInstancesManager, routingManagerClient := initTestCase(t)
+
+       ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, ranSetupManager, e2tInstancesManager)
        ranStatusChangeManager := managers.NewRanStatusChangeManager(logger, rmrSender)
 
        x2SetupResponseConverter := converters.NewX2SetupResponseConverter(logger)
        ranStatusChangeManager := managers.NewRanStatusChangeManager(logger, rmrSender)
 
        x2SetupResponseConverter := converters.NewX2SetupResponseConverter(logger)
@@ -68,34 +72,36 @@ func initTestCase(t *testing.T) (*logger.Logger, services.RNibDataService, *mana
        x2SetupFailureResponseConverter := converters.NewX2SetupFailureResponseConverter(logger)
        x2SetupFailureResponseManager := managers.NewX2SetupFailureResponseManager(x2SetupFailureResponseConverter)
 
        x2SetupFailureResponseConverter := converters.NewX2SetupFailureResponseConverter(logger)
        x2SetupFailureResponseManager := managers.NewX2SetupFailureResponseManager(x2SetupFailureResponseConverter)
 
+       endcSetupResponseConverter := converters.NewEndcSetupResponseConverter(logger)
+       endcSetupResponseManager := managers.NewEndcSetupResponseManager(endcSetupResponseConverter)
 
 
-       return logger, rnibDataService, ranReconnectionManager, ranStatusChangeManager, rmrSender, x2SetupResponseManager, x2SetupFailureResponseManager
-}
 
 
-func TestGetNotificationHandlerSuccess(t *testing.T) {
+       endcSetupFailureResponseConverter := converters.NewEndcSetupFailureResponseConverter(logger)
+       endcSetupFailureResponseManager := managers.NewEndcSetupFailureResponseManager(endcSetupFailureResponseConverter)
 
 
-       logger, rnibDataService, ranReconnectionManager, ranStatusChangeManager, rmrSender, x2SetupResponseManager, x2SetupFailureResponseManager := initTestCase(t)
 
        var testCases = []struct {
                msgType int
                handler rmrmsghandlers.NotificationHandler
        }{
 
        var testCases = []struct {
                msgType int
                handler rmrmsghandlers.NotificationHandler
        }{
-               {rmrCgo.RIC_X2_SETUP_RESP, rmrmsghandlers.NewSetupResponseNotificationHandler(logger,rnibDataService, x2SetupResponseManager, ranStatusChangeManager, rmrCgo.RIC_X2_SETUP_RESP)},
-               {rmrCgo.RIC_X2_SETUP_FAILURE, rmrmsghandlers.NewSetupResponseNotificationHandler(logger,rnibDataService, x2SetupFailureResponseManager, ranStatusChangeManager, rmrCgo.RIC_X2_SETUP_FAILURE)},
-               {rmrCgo.RIC_ENDC_X2_SETUP_RESP, rmrmsghandlers.NewSetupResponseNotificationHandler(logger,rnibDataService, managers.NewEndcSetupResponseManager(), ranStatusChangeManager, rmrCgo.RIC_ENDC_X2_SETUP_RESP)},
-               {rmrCgo.RIC_ENDC_X2_SETUP_FAILURE, rmrmsghandlers.NewSetupResponseNotificationHandler(logger,rnibDataService, managers.NewEndcSetupFailureResponseManager(), ranStatusChangeManager, rmrCgo.RIC_ENDC_X2_SETUP_FAILURE),},
-               {rmrCgo.RIC_SCTP_CONNECTION_FAILURE, rmrmsghandlers.NewRanLostConnectionHandler(logger,ranReconnectionManager)},
-               {rmrCgo.RIC_ENB_LOAD_INFORMATION, rmrmsghandlers.NewEnbLoadInformationNotificationHandler(logger,rnibDataService, converters.NewEnbLoadInformationExtractor(logger))},
+               {rmrCgo.RIC_X2_SETUP_RESP, rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, x2SetupResponseManager, ranStatusChangeManager, rmrCgo.RIC_X2_SETUP_RESP)},
+               {rmrCgo.RIC_X2_SETUP_FAILURE, rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, x2SetupFailureResponseManager, ranStatusChangeManager, rmrCgo.RIC_X2_SETUP_FAILURE)},
+               {rmrCgo.RIC_ENDC_X2_SETUP_RESP, rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, endcSetupResponseManager, ranStatusChangeManager, rmrCgo.RIC_ENDC_X2_SETUP_RESP)},
+               {rmrCgo.RIC_ENDC_X2_SETUP_FAILURE, rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, endcSetupFailureResponseManager, ranStatusChangeManager, rmrCgo.RIC_ENDC_X2_SETUP_FAILURE),},
+               {rmrCgo.RIC_SCTP_CONNECTION_FAILURE, rmrmsghandlers.NewRanLostConnectionHandler(logger, ranReconnectionManager)},
+               {rmrCgo.RIC_ENB_LOAD_INFORMATION, rmrmsghandlers.NewEnbLoadInformationNotificationHandler(logger, rnibDataService, converters.NewEnbLoadInformationExtractor(logger))},
                {rmrCgo.RIC_ENB_CONF_UPDATE, rmrmsghandlers.NewX2EnbConfigurationUpdateHandler(logger, rmrSender)},
                {rmrCgo.RIC_ENDC_CONF_UPDATE, rmrmsghandlers.NewEndcConfigurationUpdateHandler(logger, rmrSender)},
                {rmrCgo.RIC_ENB_CONF_UPDATE, rmrmsghandlers.NewX2EnbConfigurationUpdateHandler(logger, rmrSender)},
                {rmrCgo.RIC_ENDC_CONF_UPDATE, rmrmsghandlers.NewEndcConfigurationUpdateHandler(logger, rmrSender)},
-               {rmrCgo.RIC_E2_TERM_INIT, rmrmsghandlers.NewE2TermInitNotificationHandler(logger,ranReconnectionManager, rnibDataService)},
+               {rmrCgo.RIC_E2_TERM_INIT, rmrmsghandlers.NewE2TermInitNotificationHandler(logger, ranReconnectionManager, rnibDataService, e2tInstancesManager, routingManagerClient)},
+               {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_RESP, rmrmsghandlers.NewX2ResetResponseHandler(logger, rnibDataService, ranStatusChangeManager, converters.NewX2ResetResponseExtractor(logger))},
-               {rmrCgo.RIC_X2_RESET, rmrmsghandlers.NewX2ResetRequestNotificationHandler(logger,rnibDataService, ranStatusChangeManager, rmrSender)},
+               {rmrCgo.RIC_X2_RESET, rmrmsghandlers.NewX2ResetRequestNotificationHandler(logger, rnibDataService, ranStatusChangeManager, rmrSender)},
        }
 
        for _, tc := range testCases {
 
        }
 
        for _, tc := range testCases {
 
-               provider := NewNotificationHandlerProvider(logger, rnibDataService, ranReconnectionManager, ranStatusChangeManager, rmrSender, x2SetupResponseManager, x2SetupFailureResponseManager)
+               provider := NewNotificationHandlerProvider()
+               provider.Init(logger, config, rnibDataService, rmrSender, ranSetupManager, e2tInstancesManager, routingManagerClient)
                t.Run(fmt.Sprintf("%d", tc.msgType), func(t *testing.T) {
                        handler, err := provider.GetNotificationHandler(tc.msgType)
                        if err != nil {
                t.Run(fmt.Sprintf("%d", tc.msgType), func(t *testing.T) {
                        handler, err := provider.GetNotificationHandler(tc.msgType)
                        if err != nil {
@@ -124,8 +130,9 @@ func TestGetNotificationHandlerFailure(t *testing.T) {
        }
        for _, tc := range testCases {
 
        }
        for _, tc := range testCases {
 
-               logger, rnibDataService, ranReconnectionManager, ranStatusChangeManager, rmrSender, x2SetupResponseManager, x2SetupFailureResponseManager := initTestCase(t)
-               provider := NewNotificationHandlerProvider(logger, rnibDataService, ranReconnectionManager, ranStatusChangeManager, rmrSender, x2SetupResponseManager, x2SetupFailureResponseManager)
+               logger, config, rnibDataService, rmrSender, ranSetupManager, e2tInstancesManager, routingManagerClient := initTestCase(t)
+               provider := NewNotificationHandlerProvider()
+               provider.Init(logger, config, rnibDataService, rmrSender, ranSetupManager, e2tInstancesManager, routingManagerClient)
                t.Run(fmt.Sprintf("%d", tc.msgType), func(t *testing.T) {
                        _, err := provider.GetNotificationHandler(tc.msgType)
                        if err == nil {
                t.Run(fmt.Sprintf("%d", tc.msgType), func(t *testing.T) {
                        _, err := provider.GetNotificationHandler(tc.msgType)
                        if err == nil {
@@ -142,7 +149,7 @@ func TestGetNotificationHandlerFailure(t *testing.T) {
 func initRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
 func initRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
-       return rmrsender.NewRmrSender(log, &rmrMessenger)
+       return rmrsender.NewRmrSender(log, rmrMessenger)
 }
 
 // TODO: extract to test_utils
 }
 
 // TODO: extract to test_utils
index c996a1e..13a31f3 100644 (file)
 package rNibWriter
 
 import (
 package rNibWriter
 
 import (
+       "encoding/json"
        "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"
        "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"
-       "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
        "github.com/golang/protobuf/proto"
 )
 
        "github.com/golang/protobuf/proto"
 )
 
-var writerPool *common.Pool
+const E2TAddressesKey = "E2TAddresses"
 
 type rNibWriterInstance struct {
 
 type rNibWriterInstance struct {
-       sdl       *common.ISdlInstance
-       namespace string
+       sdl common.ISdlInstance
 }
 
 /*
 }
 
 /*
@@ -42,45 +41,27 @@ type RNibWriter interface {
        SaveNodeb(nbIdentity *entities.NbIdentity, nb *entities.NodebInfo) error
        UpdateNodebInfo(nodebInfo *entities.NodebInfo) error
        SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error
        SaveNodeb(nbIdentity *entities.NbIdentity, nb *entities.NodebInfo) error
        UpdateNodebInfo(nodebInfo *entities.NodebInfo) error
        SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error
+       SaveE2TInstance(e2tInstance *entities.E2TInstance) error
+       SaveE2TAddresses(addresses []string) error
 }
 
 }
 
-/*
-Init initializes the infrastructure required for the RNibWriter instance
-*/
-func Init(namespace string, poolSize int) {
-       initPool(poolSize,
-               func() interface{} {
-                       var sdlI common.ISdlInstance = sdlgo.NewSdlInstance(namespace, sdlgo.NewDatabase())
-                       return &rNibWriterInstance{sdl: &sdlI, namespace: namespace}
-               },
-               func(obj interface{}) {
-                       (*obj.(*rNibWriterInstance).sdl).Close()
-               })
-}
-
-/*
-InitPool initializes the writer's instances pool
-*/
-func initPool(poolSize int, newObj func() interface{}, destroyObj func(interface{})) {
-       writerPool = common.NewPool(poolSize, newObj, destroyObj)
-}
 /*
 GetRNibWriter returns reference to RNibWriter
 */
 /*
 GetRNibWriter returns reference to RNibWriter
 */
-func GetRNibWriter() RNibWriter {
-       return &rNibWriterInstance{}
+
+func GetRNibWriter(sdl common.ISdlInstance) RNibWriter {
+       return &rNibWriterInstance{sdl: sdl}
 }
 }
+
 /*
 SaveNodeb saves nodeB entity data in the redis DB according to the specified data model
 */
 /*
 SaveNodeb saves nodeB entity data in the redis DB according to the specified data model
 */
-func (*rNibWriterInstance) SaveNodeb(nbIdentity *entities.NbIdentity, entity *entities.NodebInfo) error {
-       w := writerPool.Get().(*rNibWriterInstance)
+func (w *rNibWriterInstance) SaveNodeb(nbIdentity *entities.NbIdentity, entity *entities.NodebInfo) error {
        isNotEmptyIdentity := isNotEmpty(nbIdentity)
 
        if isNotEmptyIdentity && entity.GetNodeType() == entities.Node_UNKNOWN {
                return common.NewValidationError(fmt.Sprintf("#rNibWriter.saveNodeB - Unknown responding node type, entity: %v", entity))
        }
        isNotEmptyIdentity := isNotEmpty(nbIdentity)
 
        if isNotEmptyIdentity && entity.GetNodeType() == entities.Node_UNKNOWN {
                return common.NewValidationError(fmt.Sprintf("#rNibWriter.saveNodeB - Unknown responding node type, entity: %v", entity))
        }
-       defer writerPool.Put(w)
        data, err := proto.Marshal(entity)
        if err != nil {
                return common.NewInternalError(err)
        data, err := proto.Marshal(entity)
        if err != nil {
                return common.NewInternalError(err)
@@ -112,7 +93,7 @@ func (*rNibWriterInstance) SaveNodeb(nbIdentity *entities.NbIdentity, entity *en
                        return rNibErr
                }
        }
                        return rNibErr
                }
        }
-       err = (*w.sdl).Set(pairs)
+       err = w.sdl.Set(pairs)
        if err != nil {
                return common.NewInternalError(err)
        }
        if err != nil {
                return common.NewInternalError(err)
        }
@@ -124,7 +105,7 @@ func (*rNibWriterInstance) SaveNodeb(nbIdentity *entities.NbIdentity, entity *en
                if err != nil {
                        return common.NewInternalError(err)
                }
                if err != nil {
                        return common.NewInternalError(err)
                }
-               err = (*w.sdl).RemoveMember(entities.Node_UNKNOWN.String(), nbIdData)
+               err = w.sdl.RemoveMember(entities.Node_UNKNOWN.String(), nbIdData)
                if err != nil {
                        return common.NewInternalError(err)
                }
                if err != nil {
                        return common.NewInternalError(err)
                }
@@ -136,7 +117,7 @@ func (*rNibWriterInstance) SaveNodeb(nbIdentity *entities.NbIdentity, entity *en
        if err != nil {
                return common.NewInternalError(err)
        }
        if err != nil {
                return common.NewInternalError(err)
        }
-       err = (*w.sdl).AddMember(entity.GetNodeType().String(), nbIdData)
+       err = w.sdl.AddMember(entity.GetNodeType().String(), nbIdData)
        if err != nil {
                return common.NewInternalError(err)
        }
        if err != nil {
                return common.NewInternalError(err)
        }
@@ -146,9 +127,7 @@ func (*rNibWriterInstance) SaveNodeb(nbIdentity *entities.NbIdentity, entity *en
 /*
 UpdateNodebInfo...
 */
 /*
 UpdateNodebInfo...
 */
-func (*rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error {
-       w := writerPool.Get().(*rNibWriterInstance)
-       defer writerPool.Put(w)
+func (w *rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error {
 
        nodebNameKey, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.GetRanName())
 
 
        nodebNameKey, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.GetRanName())
 
@@ -171,7 +150,7 @@ func (*rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error
                pairs = append(pairs, nodebIdKey, data)
        }
 
                pairs = append(pairs, nodebIdKey, data)
        }
 
-       err = (*w.sdl).Set(pairs)
+       err = w.sdl.Set(pairs)
 
        if err != nil {
                return common.NewInternalError(err)
 
        if err != nil {
                return common.NewInternalError(err)
@@ -183,9 +162,7 @@ func (*rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error
 /*
 SaveRanLoadInformation stores ran load information for the provided ran
 */
 /*
 SaveRanLoadInformation stores ran load information for the provided ran
 */
-func (*rNibWriterInstance) SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error {
-       w := writerPool.Get().(*rNibWriterInstance)
-       defer writerPool.Put(w)
+func (w *rNibWriterInstance) SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error {
 
        key, rnibErr := common.ValidateAndBuildRanLoadInformationKey(inventoryName)
 
 
        key, rnibErr := common.ValidateAndBuildRanLoadInformationKey(inventoryName)
 
@@ -202,7 +179,53 @@ func (*rNibWriterInstance) SaveRanLoadInformation(inventoryName string, ranLoadI
        var pairs []interface{}
        pairs = append(pairs, key, data)
 
        var pairs []interface{}
        pairs = append(pairs, key, data)
 
-       err = (*w.sdl).Set(pairs)
+       err = w.sdl.Set(pairs)
+
+       if err != nil {
+               return common.NewInternalError(err)
+       }
+
+       return nil
+}
+
+func (w *rNibWriterInstance) SaveE2TInstance(e2tInstance *entities.E2TInstance) error {
+
+       key, rnibErr := common.ValidateAndBuildE2TInstanceKey(e2tInstance.Address)
+
+       if rnibErr != nil {
+               return rnibErr
+       }
+
+       data, err := json.Marshal(e2tInstance)
+
+       if err != nil {
+               return common.NewInternalError(err)
+       }
+
+       var pairs []interface{}
+       pairs = append(pairs, key, data)
+
+       err = w.sdl.Set(pairs)
+
+       if err != nil {
+               return common.NewInternalError(err)
+       }
+
+       return nil
+}
+
+func (w *rNibWriterInstance) SaveE2TAddresses(addresses []string) error {
+
+       data, err := json.Marshal(addresses)
+
+       if err != nil {
+               return common.NewInternalError(err)
+       }
+
+       var pairs []interface{}
+       pairs = append(pairs, E2TAddressesKey, data)
+
+       err = w.sdl.Set(pairs)
 
        if err != nil {
                return common.NewInternalError(err)
 
        if err != nil {
                return common.NewInternalError(err)
@@ -212,10 +235,10 @@ func (*rNibWriterInstance) SaveRanLoadInformation(inventoryName string, ranLoadI
 }
 
 /*
 }
 
 /*
-Close closes writer's pool
+Close the writer
 */
 func Close() {
 */
 func Close() {
-       writerPool.Close()
+       //Nothing to do
 }
 
 func appendEnbCells(nbIdentity *entities.NbIdentity, cells []*entities.ServedCellInfo, pairs []interface{}) ([]interface{}, error) {
 }
 
 func appendEnbCells(nbIdentity *entities.NbIdentity, cells []*entities.ServedCellInfo, pairs []interface{}) ([]interface{}, error) {
index f16228b..34ef4c8 100644 (file)
@@ -22,6 +22,7 @@ package rNibWriter
 
 import (
        "e2mgr/mocks"
 
 import (
        "e2mgr/mocks"
+       "encoding/json"
        "errors"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "errors"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
@@ -32,55 +33,19 @@ import (
        "time"
 )
 
        "time"
 )
 
-func TestInitRNibWriter(t *testing.T) {
-       writerPool = nil
-       initSdlInstanceMock(namespace, 1)
-       available, created := writerPool.Stats()
-       assert.Equal(t, available, 0, "number of available objects in the writerPool should be 0")
-       assert.Equal(t, created, 0, "number of created objects in the writerPool should be 0")
-       w := GetRNibWriter()
-       assert.NotNil(t, w)
-}
-
-func TestInitPool(t *testing.T) {
-       writerPool = nil
-       sdlInstanceMock := new(mocks.MockSdlInstance)
-       initPool(1, func() interface{} {
-               sdlI := common.ISdlInstance(sdlInstanceMock)
-               return &rNibWriterInstance{sdl: &sdlI, namespace: namespace}
-       },
-               func(obj interface{}) {
-               },
-       )
-       assert.NotNil(t, writerPool)
-       assert.NotNil(t, writerPool.New)
-       assert.NotNil(t, writerPool.Destroy)
-       available, created := writerPool.Stats()
-       assert.Equal(t, 0, available, "number of available objects in the writerPool should be 0")
-       assert.Equal(t, 0, created, "number of created objects in the writerPool should be 0")
+func initSdlInstanceMock(namespace string) (w RNibWriter, sdlInstanceMock *mocks.MockSdlInstance) {
+       sdlInstanceMock = new(mocks.MockSdlInstance)
+       w = GetRNibWriter(sdlInstanceMock)
+       return
 }
 
 var namespace = "namespace"
 
 }
 
 var namespace = "namespace"
 
-func initSdlInstanceMock(namespace string, poolSize int) *mocks.MockSdlInstance {
-       sdlInstanceMock := new(mocks.MockSdlInstance)
-       initPool(poolSize, func() interface{} {
-               sdlI := common.ISdlInstance(sdlInstanceMock)
-               return &rNibWriterInstance{sdl: &sdlI, namespace: namespace}
-       },
-               func(obj interface{}) {
-               },
-       )
-       return sdlInstanceMock
-}
-
 func TestUpdateNodebInfoSuccess(t *testing.T) {
        inventoryName := "name"
        plmnId := "02f829"
        nbId := "4a952a0a"
 func TestUpdateNodebInfoSuccess(t *testing.T) {
        inventoryName := "name"
        plmnId := "02f829"
        nbId := "4a952a0a"
-       writerPool = nil
-       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
        nodebInfo := &entities.NodebInfo{}
        nodebInfo.RanName = inventoryName
        nodebInfo.GlobalNbId = &entities.GlobalNbId{PlmnId: plmnId, NbId: nbId}
        nodebInfo := &entities.NodebInfo{}
        nodebInfo.RanName = inventoryName
        nodebInfo.GlobalNbId = &entities.GlobalNbId{PlmnId: plmnId, NbId: nbId}
@@ -110,9 +75,7 @@ func TestUpdateNodebInfoMissingInventoryNameFailure(t *testing.T) {
        inventoryName := "name"
        plmnId := "02f829"
        nbId := "4a952a0a"
        inventoryName := "name"
        plmnId := "02f829"
        nbId := "4a952a0a"
-       writerPool = nil
-       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
        nodebInfo := &entities.NodebInfo{}
        data, err := proto.Marshal(nodebInfo)
        if err != nil {
        nodebInfo := &entities.NodebInfo{}
        data, err := proto.Marshal(nodebInfo)
        if err != nil {
@@ -136,9 +99,7 @@ func TestUpdateNodebInfoMissingInventoryNameFailure(t *testing.T) {
 
 func TestUpdateNodebInfoMissingGlobalNbId(t *testing.T) {
        inventoryName := "name"
 
 func TestUpdateNodebInfoMissingGlobalNbId(t *testing.T) {
        inventoryName := "name"
-       writerPool = nil
-       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
        nodebInfo := &entities.NodebInfo{}
        nodebInfo.RanName = inventoryName
        data, err := proto.Marshal(nodebInfo)
        nodebInfo := &entities.NodebInfo{}
        nodebInfo.RanName = inventoryName
        data, err := proto.Marshal(nodebInfo)
@@ -160,9 +121,7 @@ func TestUpdateNodebInfoMissingGlobalNbId(t *testing.T) {
 func TestSaveEnb(t *testing.T) {
        name := "name"
        ranName := "RAN:" + name
 func TestSaveEnb(t *testing.T) {
        name := "name"
        ranName := "RAN:" + name
-       writerPool = nil
-       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
        nb := entities.NodebInfo{}
        nb.NodeType = entities.Node_ENB
        nb.ConnectionStatus = 1
        nb := entities.NodebInfo{}
        nb.NodeType = entities.Node_ENB
        nb.ConnectionStatus = 1
@@ -210,9 +169,7 @@ func TestSaveEnb(t *testing.T) {
 
 func TestSaveEnbCellIdValidationFailure(t *testing.T) {
        name := "name"
 
 func TestSaveEnbCellIdValidationFailure(t *testing.T) {
        name := "name"
-       writerPool = nil
-       initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, _ := initSdlInstanceMock(namespace)
        nb := entities.NodebInfo{}
        nb.NodeType = entities.Node_ENB
        nb.ConnectionStatus = 1
        nb := entities.NodebInfo{}
        nb.NodeType = entities.Node_ENB
        nb.ConnectionStatus = 1
@@ -231,9 +188,7 @@ func TestSaveEnbCellIdValidationFailure(t *testing.T) {
 }
 
 func TestSaveEnbInventoryNameValidationFailure(t *testing.T) {
 }
 
 func TestSaveEnbInventoryNameValidationFailure(t *testing.T) {
-       writerPool = nil
-       initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, _ := initSdlInstanceMock(namespace)
        nb := entities.NodebInfo{}
        nb.NodeType = entities.Node_ENB
        nb.ConnectionStatus = 1
        nb := entities.NodebInfo{}
        nb.NodeType = entities.Node_ENB
        nb.ConnectionStatus = 1
@@ -251,35 +206,9 @@ func TestSaveEnbInventoryNameValidationFailure(t *testing.T) {
        assert.Equal(t, "#utils.ValidateAndBuildNodeBNameKey - an empty inventory name received", rNibErr.Error())
 }
 
        assert.Equal(t, "#utils.ValidateAndBuildNodeBNameKey - an empty inventory name received", rNibErr.Error())
 }
 
-func TestSaveEnbOnClosedPool(t *testing.T) {
-       name := "name"
-       writerPool = nil
-       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
-       nb := entities.NodebInfo{}
-       nb.NodeType = entities.Node_ENB
-       nb.ConnectionStatus = 1
-       nb.Ip = "localhost"
-       nb.Port = 5656
-       enb := entities.Enb{}
-       nb.Configuration = &entities.NodebInfo_Enb{Enb: &enb}
-       data, err := proto.Marshal(&nb)
-       if err != nil {
-               t.Errorf("#rNibWriter_test.TestSaveEnbOnClosedPool - Failed to marshal NodeB entity. Error: %v", err)
-       }
-       setExpected := []interface{}{name, data}
-       var e error
-       sdlInstanceMock.On("Set", setExpected).Return(e)
-       writerPool.Close()
-       nbIdentity := &entities.NbIdentity{}
-       assert.Panics(t, func() { w.SaveNodeb(nbIdentity, &nb) })
-}
-
 func TestSaveGnbCellIdValidationFailure(t *testing.T) {
        name := "name"
 func TestSaveGnbCellIdValidationFailure(t *testing.T) {
        name := "name"
-       writerPool = nil
-       initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, _ := initSdlInstanceMock(namespace)
        nb := entities.NodebInfo{}
        nb.NodeType = entities.Node_GNB
        nb.ConnectionStatus = 1
        nb := entities.NodebInfo{}
        nb.NodeType = entities.Node_GNB
        nb.ConnectionStatus = 1
@@ -301,9 +230,7 @@ func TestSaveGnbCellIdValidationFailure(t *testing.T) {
 func TestSaveGnb(t *testing.T) {
        name := "name"
        ranName := "RAN:" + name
 func TestSaveGnb(t *testing.T) {
        name := "name"
        ranName := "RAN:" + name
-       writerPool = nil
-       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
        nb := entities.NodebInfo{}
        nb.NodeType = entities.Node_GNB
        nb.ConnectionStatus = 1
        nb := entities.NodebInfo{}
        nb.NodeType = entities.Node_GNB
        nb.ConnectionStatus = 1
@@ -357,9 +284,7 @@ func TestSaveRanLoadInformationSuccess(t *testing.T) {
                t.Errorf("#rNibWriter_test.TestSaveRanLoadInformationSuccess - Failed to build ran load infromation key. Error: %v", validationErr)
        }
 
                t.Errorf("#rNibWriter_test.TestSaveRanLoadInformationSuccess - Failed to build ran load infromation key. Error: %v", validationErr)
        }
 
-       writerPool = nil
-       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
 
        ranLoadInformation := generateRanLoadInformation()
        data, err := proto.Marshal(ranLoadInformation)
 
        ranLoadInformation := generateRanLoadInformation()
        data, err := proto.Marshal(ranLoadInformation)
@@ -379,9 +304,7 @@ func TestSaveRanLoadInformationSuccess(t *testing.T) {
 
 func TestSaveRanLoadInformationMarshalNilFailure(t *testing.T) {
        inventoryName := "name2"
 
 func TestSaveRanLoadInformationMarshalNilFailure(t *testing.T) {
        inventoryName := "name2"
-       writerPool = nil
-       initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, _ := initSdlInstanceMock(namespace)
 
        expectedErr := common.NewInternalError(errors.New("proto: Marshal called with nil"))
        err := w.SaveRanLoadInformation(inventoryName, nil)
 
        expectedErr := common.NewInternalError(errors.New("proto: Marshal called with nil"))
        err := w.SaveRanLoadInformation(inventoryName, nil)
@@ -390,9 +313,7 @@ func TestSaveRanLoadInformationMarshalNilFailure(t *testing.T) {
 
 func TestSaveRanLoadInformationEmptyInventoryNameFailure(t *testing.T) {
        inventoryName := ""
 
 func TestSaveRanLoadInformationEmptyInventoryNameFailure(t *testing.T) {
        inventoryName := ""
-       writerPool = nil
-       initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, _ := initSdlInstanceMock(namespace)
 
        err := w.SaveRanLoadInformation(inventoryName, nil)
        assert.NotNil(t, err)
 
        err := w.SaveRanLoadInformation(inventoryName, nil)
        assert.NotNil(t, err)
@@ -408,9 +329,7 @@ func TestSaveRanLoadInformationSdlFailure(t *testing.T) {
                t.Errorf("#rNibWriter_test.TestSaveRanLoadInformationSuccess - Failed to build ran load infromation key. Error: %v", validationErr)
        }
 
                t.Errorf("#rNibWriter_test.TestSaveRanLoadInformationSuccess - Failed to build ran load infromation key. Error: %v", validationErr)
        }
 
-       writerPool = nil
-       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
 
        ranLoadInformation := generateRanLoadInformation()
        data, err := proto.Marshal(ranLoadInformation)
 
        ranLoadInformation := generateRanLoadInformation()
        data, err := proto.Marshal(ranLoadInformation)
@@ -503,9 +422,7 @@ func generateRanLoadInformation() *entities.RanLoadInformation {
 }
 
 func TestSaveNilEntityFailure(t *testing.T) {
 }
 
 func TestSaveNilEntityFailure(t *testing.T) {
-       writerPool = nil
-       initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, _ := initSdlInstanceMock(namespace)
        expectedErr := common.NewInternalError(errors.New("proto: Marshal called with nil"))
        nbIdentity := &entities.NbIdentity{}
        actualErr := w.SaveNodeb(nbIdentity, nil)
        expectedErr := common.NewInternalError(errors.New("proto: Marshal called with nil"))
        nbIdentity := &entities.NbIdentity{}
        actualErr := w.SaveNodeb(nbIdentity, nil)
@@ -513,9 +430,7 @@ func TestSaveNilEntityFailure(t *testing.T) {
 }
 
 func TestSaveUnknownTypeEntityFailure(t *testing.T) {
 }
 
 func TestSaveUnknownTypeEntityFailure(t *testing.T) {
-       writerPool = nil
-       initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, _ := initSdlInstanceMock(namespace)
        expectedErr := common.NewValidationError("#rNibWriter.saveNodeB - Unknown responding node type, entity: ip:\"localhost\" port:5656 ")
        nbIdentity := &entities.NbIdentity{InventoryName: "name", GlobalNbId: &entities.GlobalNbId{PlmnId: "02f829", NbId: "4a952a0a"}}
        nb := &entities.NodebInfo{}
        expectedErr := common.NewValidationError("#rNibWriter.saveNodeB - Unknown responding node type, entity: ip:\"localhost\" port:5656 ")
        nbIdentity := &entities.NbIdentity{InventoryName: "name", GlobalNbId: &entities.GlobalNbId{PlmnId: "02f829", NbId: "4a952a0a"}}
        nb := &entities.NodebInfo{}
@@ -530,9 +445,7 @@ func TestSaveEntityFailure(t *testing.T) {
        plmnId := "02f829"
        nbId := "4a952a0a"
 
        plmnId := "02f829"
        nbId := "4a952a0a"
 
-       writerPool = nil
-       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
-       w := GetRNibWriter()
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
        gnb := entities.NodebInfo{}
        gnb.NodeType = entities.Node_GNB
        data, err := proto.Marshal(&gnb)
        gnb := entities.NodebInfo{}
        gnb.NodeType = entities.Node_GNB
        data, err := proto.Marshal(&gnb)
@@ -548,77 +461,120 @@ func TestSaveEntityFailure(t *testing.T) {
        assert.NotEmpty(t, rNibErr)
 }
 
        assert.NotEmpty(t, rNibErr)
 }
 
-func TestGetRNibWriterPoolNotInitializedFailure(t *testing.T) {
-       writerPool = nil
-       assert.Panics(t, func() { GetRNibWriter().SaveNodeb(nil,nil) })
-}
-
 func TestGetRNibWriter(t *testing.T) {
 func TestGetRNibWriter(t *testing.T) {
-       writerPool = nil
-       initSdlInstanceMock(namespace, 1)
-       received := GetRNibWriter()
-       assert.Empty(t, received)
-       available, created := writerPool.Stats()
-       assert.Equal(t, 0, available, "number of available objects in the writerPool should be 0")
-       assert.Equal(t, 0, created, "number of created objects in the writerPool should be 0")
-       writerPool.Close()
+       received, _ := initSdlInstanceMock(namespace)
+       assert.NotEmpty(t, received)
 }
 
 }
 
-func TestClose(t *testing.T) {
-       writerPool = nil
-       instanceMock := initSdlInstanceMock(namespace, 2)
-       w1 := GetRNibWriter()
-       w2 := GetRNibWriter()
-       writerPool.Put(w1)
-       writerPool.Put(w2)
-       available, created := writerPool.Stats()
-       assert.Equal(t, 2, available, "number of available objects in the writerPool should be 2")
-       assert.Equal(t, 0, created, "number of created objects in the writerPool should be 0")
+func TestSaveE2TInstanceSuccess(t *testing.T) {
+       address := "10.10.2.15:9800"
+       loadKey, validationErr := common.ValidateAndBuildE2TInstanceKey(address)
+
+       if validationErr != nil {
+               t.Errorf("#rNibWriter_test.TestSaveE2TInstanceSuccess - Failed to build E2T Instance key. Error: %v", validationErr)
+       }
+
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
+
+       e2tInstance := generateE2tInstance(address)
+       data, err := json.Marshal(e2tInstance)
+
+       if err != nil {
+               t.Errorf("#rNibWriter_test.TestSaveE2TInstanceSuccess - Failed to marshal E2tInstance entity. Error: %v", err)
+       }
+
        var e error
        var e error
-       instanceMock.On("Close").Return(e)
-       Close()
-       available, created = writerPool.Stats()
-       assert.Equal(t, 0, available, "number of available objects in the writerPool should be 0")
+       var setExpected []interface{}
+       setExpected = append(setExpected, loadKey, data)
+       sdlInstanceMock.On("Set", []interface{}{setExpected}).Return(e)
+
+       rNibErr := w.SaveE2TInstance(e2tInstance)
+       assert.Nil(t, rNibErr)
 }
 
 }
 
-func TestCloseOnClosedPoolFailure(t *testing.T) {
-       writerPool = nil
-       instanceMock := initSdlInstanceMock(namespace, 1)
-       w1 := GetRNibWriter()
-       writerPool.Put(w1)
-       available, created := writerPool.Stats()
-       assert.Equal(t, 1, available, "number of available objects in the writerPool should be 1")
-       assert.Equal(t, 0, created, "number of created objects in the writerPool should be 0")
-       var e error
-       instanceMock.On("Close").Return(e)
-       Close()
-       assert.Panics(t, func() { Close() })
+func TestSaveE2TInstanceNullE2tInstanceFailure(t *testing.T) {
+       w, _ := initSdlInstanceMock(namespace)
+       var address string
+       e2tInstance := entities.NewE2TInstance(address)
+       err := w.SaveE2TInstance(e2tInstance)
+       assert.NotNil(t, err)
+       assert.IsType(t, &common.ValidationError{}, err)
 }
 
 }
 
-func TestCloseFailure(t *testing.T) {
-       writerPool = nil
-       instanceMock := initSdlInstanceMock(namespace, 2)
-       w1 := GetRNibWriter()
-       writerPool.Put(w1)
-       available, created := writerPool.Stats()
-       assert.Equal(t, 1, available, "number of available objects in the writerPool should be 1")
-       assert.Equal(t, 0, created, "number of created objects in the writerPool should be 0")
-       e := errors.New("expected error")
-       instanceMock.On("Close").Return(e)
-       Close()
-       available, created = writerPool.Stats()
-       assert.Equal(t, 0, available, "number of available objects in the writerPool should be 0")
+func TestSaveE2TInstanceSdlFailure(t *testing.T) {
+       address := "10.10.2.15:9800"
+       loadKey, validationErr := common.ValidateAndBuildE2TInstanceKey(address)
+
+       if validationErr != nil {
+               t.Errorf("#rNibWriter_test.TestSaveE2TInstanceSdlFailure - Failed to build E2T Instance key. Error: %v", validationErr)
+       }
+
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
+
+       e2tInstance := generateE2tInstance(address)
+       data, err := json.Marshal(e2tInstance)
+
+       if err != nil {
+               t.Errorf("#rNibWriter_test.TestSaveE2TInstanceSdlFailure - Failed to marshal E2tInstance entity. Error: %v", err)
+       }
+
+       expectedErr := errors.New("expected error")
+       var setExpected []interface{}
+       setExpected = append(setExpected, loadKey, data)
+       sdlInstanceMock.On("Set", []interface{}{setExpected}).Return(expectedErr)
+
+       rNibErr := w.SaveE2TInstance(e2tInstance)
+       assert.NotNil(t, rNibErr)
+       assert.IsType(t, &common.InternalError{}, rNibErr)
+}
+
+func generateE2tInstance(address string) *entities.E2TInstance {
+       e2tInstance := entities.NewE2TInstance(address)
+
+       e2tInstance.AssociatedRanList = []string{"test1", "test2"}
+
+       return e2tInstance
 }
 
 }
 
-func TestInit(t *testing.T) {
-       writerPool = nil
-       Init("", 1)
-       assert.NotNil(t, writerPool)
-       assert.NotNil(t, writerPool.New)
-       assert.NotNil(t, writerPool.Destroy)
-       available, created := writerPool.Stats()
-       assert.Equal(t, 0, available, "number of available objects in the writerPool should be 0")
-       assert.Equal(t, 0, created, "number of created objects in the writerPool should be 0")
+func TestSaveE2TAddressesSuccess(t *testing.T) {
+       address := "10.10.2.15:9800"
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
+
+       e2tAddresses := []string{address}
+       data, err := json.Marshal(e2tAddresses)
+
+       if err != nil {
+               t.Errorf("#rNibWriter_test.TestSaveE2TInfoListSuccess - Failed to marshal E2TInfoList. Error: %v", err)
+       }
+
+       var e error
+       var setExpected []interface{}
+       setExpected = append(setExpected, E2TAddressesKey, data)
+       sdlInstanceMock.On("Set", []interface{}{setExpected}).Return(e)
+
+       rNibErr := w.SaveE2TAddresses(e2tAddresses)
+       assert.Nil(t, rNibErr)
+}
+
+func TestSaveE2TAddressesSdlFailure(t *testing.T) {
+       address := "10.10.2.15:9800"
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
+
+       e2tAddresses := []string{address}
+       data, err := json.Marshal(e2tAddresses)
+
+       if err != nil {
+               t.Errorf("#rNibWriter_test.TestSaveE2TInfoListSdlFailure - Failed to marshal E2TInfoList. Error: %v", err)
+       }
+
+       expectedErr := errors.New("expected error")
+       var setExpected []interface{}
+       setExpected = append(setExpected, E2TAddressesKey, data)
+       sdlInstanceMock.On("Set", []interface{}{setExpected}).Return(expectedErr)
+
+       rNibErr := w.SaveE2TAddresses(e2tAddresses)
+       assert.NotNil(t, rNibErr)
+       assert.IsType(t, &common.InternalError{}, rNibErr)
 }
 
 //Integration tests
 }
 
 //Integration tests
index 0b73b60..f10d275 100644 (file)
@@ -5,8 +5,12 @@ http:
 rmr:
   port: 3801
   maxMsgSize: 65536
 rmr:
   port: 3801
   maxMsgSize: 65536
+routingManager:
+  baseUrl: http://10.0.2.15:12020/ric/v1/handles/v1/
 notificationResponseBuffer: 100
 bigRedButtonTimeoutSec: 5
 maxConnectionAttempts: 3
 maxRnibConnectionAttempts: 3
 rnibRetryIntervalMs: 10
 notificationResponseBuffer: 100
 bigRedButtonTimeoutSec: 5
 maxConnectionAttempts: 3
 maxRnibConnectionAttempts: 3
 rnibRetryIntervalMs: 10
+keepAliveResponseTimeoutMs: 1500
+keepAliveDelayMs: 500
index d7d0870..f65d10d 100644 (file)
@@ -34,7 +34,7 @@ import (
        "e2mgr/logger"
 )
 
        "e2mgr/logger"
 )
 
-func (*Context) Init(port string, maxMsgSize int, flags int, logger *logger.Logger) *RmrMessenger {//TODO remove pointer from interface
+func (*Context) Init(port string, maxMsgSize int, flags int, logger *logger.Logger) RmrMessenger {
        pp := C.CString(port)
        defer C.free(unsafe.Pointer(pp))
        logger.Debugf("#rmrCgoApi.Init - Going to initiate RMR router")
        pp := C.CString(port)
        defer C.free(unsafe.Pointer(pp))
        logger.Debugf("#rmrCgoApi.Init - Going to initiate RMR router")
@@ -54,10 +54,10 @@ func (*Context) Init(port string, maxMsgSize int, flags int, logger *logger.Logg
        // Each round is about 1000 attempts with a short sleep between each round.
        C.rmr_set_stimeout(ctx.RmrCtx, C.int(1000))
        r := RmrMessenger(ctx)
        // Each round is about 1000 attempts with a short sleep between each round.
        C.rmr_set_stimeout(ctx.RmrCtx, C.int(1000))
        r := RmrMessenger(ctx)
-       return &r
+       return r
 }
 
 }
 
-func (ctx *Context) SendMsg(msg *MBuf) (*MBuf, error) {
+func (ctx *Context) SendMsg(msg *MBuf, printLogs bool) (*MBuf, error) {
        ctx.checkContextInitialized()
        ctx.Logger.Debugf("#rmrCgoApi.SendMsg - Going to send message. MBuf: %v", *msg)
        allocatedCMBuf := ctx.getAllocatedCRmrMBuf(ctx.Logger, msg, ctx.MaxMsgSize)
        ctx.checkContextInitialized()
        ctx.Logger.Debugf("#rmrCgoApi.SendMsg - Going to send message. MBuf: %v", *msg)
        allocatedCMBuf := ctx.getAllocatedCRmrMBuf(ctx.Logger, msg, ctx.MaxMsgSize)
@@ -68,21 +68,21 @@ func (ctx *Context) SendMsg(msg *MBuf) (*MBuf, error) {
                return nil, errors.New(errorMessage)
        }
 
                return nil, errors.New(errorMessage)
        }
 
-       //TODO: if debug enabled
-       transactionId := string(*msg.XAction)
-       tmpTid := strings.TrimSpace(transactionId)
-       ctx.Logger.Infof("[E2 Manager -> RMR] #rmrCgoApi.SendMsg - Going to send message %v for transaction id: %s", *msg, tmpTid)
+       if printLogs {
+               //TODO: if debug enabled
+               transactionId := string(*msg.XAction)
+               tmpTid := strings.TrimSpace(transactionId)
+               ctx.Logger.Infof("[E2 Manager -> RMR] #rmrCgoApi.SendMsg - Going to send message %v for transaction id: %s", *msg, tmpTid)
+       }
 
        currCMBuf := C.rmr_send_msg(ctx.RmrCtx, allocatedCMBuf)
        state = currCMBuf.state
 
        currCMBuf := C.rmr_send_msg(ctx.RmrCtx, allocatedCMBuf)
        state = currCMBuf.state
-       ctx.Logger.Debugf("#rmrCgoApi.SendMsg - The current message  state: %v, message buffer:%v", state, currCMBuf)
 
        if state != RMR_OK {
                errorMessage := fmt.Sprintf("#rmrCgoApi.SendMsg - Failed to send message. state: %v - %s", state, states[int(state)])
                return nil, errors.New(errorMessage)
        }
 
 
        if state != RMR_OK {
                errorMessage := fmt.Sprintf("#rmrCgoApi.SendMsg - Failed to send message. state: %v - %s", state, states[int(state)])
                return nil, errors.New(errorMessage)
        }
 
-       ctx.Logger.Debugf("#rmrCgoApi.SendMsg - The message has been sent successfully ")
        return convertToMBuf(ctx.Logger, currCMBuf), nil
 }
 
        return convertToMBuf(ctx.Logger, currCMBuf), nil
 }
 
@@ -102,18 +102,14 @@ func (ctx *Context) RecvMsg() (*MBuf, error) {
        }
 
        mbuf := convertToMBuf(ctx.Logger, currCMBuf)
        }
 
        mbuf := convertToMBuf(ctx.Logger, currCMBuf)
-       transactionId := string(*mbuf.XAction)
-       tmpTid := strings.TrimSpace(transactionId)
-       ctx.Logger.Infof("[RMR -> E2 Manager] #rmrCgoApi.RecvMsg - message %v has been received for transaction id: %s", *mbuf, tmpTid)
-       return mbuf, nil
-}
 
 
-func (ctx *Context) RtsMsg(msg *MBuf) {
-       ctx.checkContextInitialized()
-       ctx.Logger.Debugf("#rmrCgoApi.RtsMsg - Going to return message to the sender")
-       allocatedCMBuf := C.rmr_alloc_msg(ctx.RmrCtx, C.int(ctx.MaxMsgSize))
-       defer C.rmr_free_msg(allocatedCMBuf)
-       C.rmr_rts_msg(ctx.RmrCtx, allocatedCMBuf)
+       if mbuf.MType != E2_TERM_KEEP_ALIVE_RESP {
+
+               transactionId := string(*mbuf.XAction)
+               tmpTid := strings.TrimSpace(transactionId)
+               ctx.Logger.Infof("[RMR -> E2 Manager] #rmrCgoApi.RecvMsg - message %v has been received for transaction id: %s", *mbuf, tmpTid)
+       }
+       return mbuf, nil
 }
 
 func (ctx *Context) IsReady() bool {
 }
 
 func (ctx *Context) IsReady() bool {
index f675b5a..5d226a8 100644 (file)
 //  platform project (RICP).
 
 
 //  platform project (RICP).
 
 
-package rmrCgo
+package rmrCgo_test
 
 import (
 
 import (
+       "bytes"
        "e2mgr/logger"
        "e2mgr/logger"
+       "e2mgr/rmrCgo"
        "e2mgr/tests"
        "e2mgr/tests"
-       "bytes"
        "encoding/json"
        "github.com/stretchr/testify/assert"
        "io/ioutil"
        "testing"
        "encoding/json"
        "github.com/stretchr/testify/assert"
        "io/ioutil"
        "testing"
-       "time"
 )
 
 var (
 )
 
 var (
-       log     *logger.Logger
-       msgr *RmrMessenger
+       log  *logger.Logger
+       msgr rmrCgo.RmrMessenger
 )
 
 )
 
-func TestLogger(t *testing.T){
-       var err error
-       log, err = logger.InitLogger(logger.DebugLevel)
-       if err != nil {
-               t.Errorf("#rmrCgoApi_test.TestLogger - failed to initialize logger, error: %s", err)
-       }
-       data :=  map[string]interface{}{"messageType": 1001, "ranIp":"10.0.0.3", "ranPort": 879, "ranName":"test1"}
+func TestLogger(t *testing.T) {
+       log := initLog(t)
+       data := map[string]interface{}{"messageType": 1001, "ranIp": "10.0.0.3", "ranPort": 879, "ranName": "test1"}
        b := new(bytes.Buffer)
        _ = json.NewEncoder(b).Encode(data)
        req := tests.GetHttpRequest()
        boo, _ := ioutil.ReadAll(req.Body)
        b := new(bytes.Buffer)
        _ = json.NewEncoder(b).Encode(data)
        req := tests.GetHttpRequest()
        boo, _ := ioutil.ReadAll(req.Body)
-       log.Debugf("#rmrCgoApi_test.TestLogger - request header: %v\n; request body: %s\n", req.Header, string(boo))
+       log.Debugf("#rmr_c_go_api_test.TestLogger - request header: %v\n; request body: %s\n", req.Header, string(boo))
 }
 
 }
 
-
 func TestNewMBufSuccess(t *testing.T) {
 func TestNewMBufSuccess(t *testing.T) {
-       var err error
-       log, err = logger.InitLogger(logger.DebugLevel)
-       if err != nil {
-               t.Errorf("#rmrCgoApi_test.TestNewMBufSuccess - failed to initialize logger, error: %s", err)
-       }
-       msg := NewMBuf(tests.MessageType, len(tests.DummyPayload),"RanName", &tests.DummyPayload, &tests.DummyXAction)
+       msg := rmrCgo.NewMBuf(tests.MessageType, len(tests.DummyPayload), "RanName", &tests.DummyPayload, &tests.DummyXAction)
        assert.NotNil(t, msg)
        assert.NotEmpty(t, msg.Payload)
        assert.NotEmpty(t, msg.XAction)
        assert.NotNil(t, msg)
        assert.NotEmpty(t, msg.Payload)
        assert.NotEmpty(t, msg.XAction)
@@ -66,80 +56,81 @@ func TestNewMBufSuccess(t *testing.T) {
        assert.Equal(t, msg.Len, len(tests.DummyPayload))
 }
 
        assert.Equal(t, msg.Len, len(tests.DummyPayload))
 }
 
-func TestInitFailure(t *testing.T) {
-       var err error
-       log, err = logger.InitLogger(logger.DebugLevel)
-       if err != nil {
-               t.Errorf("#rmrCgoApi_test.TestInitFailure - failed to initialize logger, error: %s", err)
+/*func TestIsReadySuccess(t *testing.T) {
+       log := initLog(t)
+
+       initRmr(tests.GetPort(), tests.MaxMsgSize, tests.Flags, log)
+       if msgr == nil || !msgr.IsReady() {
+               t.Errorf("#rmr_c_go_api_test.TestIsReadySuccess - The rmr router is not ready")
        }
        }
-       go initRmr(tests.GetPort(), tests.MaxMsgSize, tests.Flags, log)
-       time.Sleep(time.Second)
-       if msgr != nil {
-               t.Errorf("The rmr router is ready, should be not ready")
+       msgr.Close()
+}
+func TestSendRecvMsgSuccess(t *testing.T) {
+       log := initLog(t)
+
+       initRmr(tests.GetPort(), tests.MaxMsgSize, tests.Flags, log)
+       if msgr == nil || !msgr.IsReady() {
+               t.Errorf("#rmr_c_go_api_test.TestSendRecvMsgSuccess - The rmr router is not ready")
+       }
+       msg := rmrCgo.NewMBuf(1, tests.MaxMsgSize, "test 1", &tests.DummyPayload, &tests.DummyXAction)
+       log.Debugf("#rmr_c_go_api_test.TestSendRecvMsgSuccess - Going to send the message: %#v\n", msg)
+       result, err := msgr.SendMsg(msg, true)
+
+       assert.Nil(t, err)
+       assert.NotNil(t, result)
+
+       msgR, err := msgr.RecvMsg()
+
+       assert.Nil(t, err)
+       assert.NotNil(t, msgR)
+       msgr.Close()
+}
+
+func TestSendMsgRmrInvalidMsgNumError(t *testing.T) {
+       log := initLog(t)
+
+       initRmr(tests.GetPort(), tests.MaxMsgSize, tests.Flags, log)
+       if msgr == nil || !msgr.IsReady() {
+               t.Errorf("#rmr_c_go_api_test.TestSendMsgRmrInvalidMsgNumError - The rmr router is not ready")
        }
        }
+
+       msg := rmrCgo.NewMBuf(10, tests.MaxMsgSize, "test 1", &tests.DummyPayload, &tests.DummyXAction)
+       log.Debugf("#rmr_c_go_api_test.TestSendMsgRmrInvalidMsgNumError - Going to send the message: %#v\n", msg)
+       result, err := msgr.SendMsg(msg, true)
+
+       assert.NotNil(t, err)
+       assert.Nil(t, result)
+
+       msgr.Close()
 }
 
 }
 
-//func TestInitSuccess(t *testing.T) {
-//     var err error
-//     log, err = logger.InitLogger(true)
-//     if err != nil {
-//             t.Errorf("#rmrCgoApi_test.TestInitSuccess - failed to initialize logger, error: %s", err)
-//     }
-//     go initRmr(tests.GetPort(), tests.MaxMsgSize, tests.Flags, log)
-//     time.Sleep(time.Second)
-//     if msgr == nil {
-//             t.Errorf("The rmr router is not ready, should be ready")
-//     }
-//}
-
-func TestIsReadyFailure(t *testing.T) {
-       var err error
-       log, err = logger.InitLogger(logger.InfoLevel)
-       if err != nil {
-               t.Errorf("#rmrCgoApi_test.TestIsReadyFailure - failed to initialize logger, error: %s", err)
+func TestSendMsgRmrInvalidPortError(t *testing.T) {
+       log := initLog(t)
+
+       initRmr("tcp:"+strconv.Itoa(5555), tests.MaxMsgSize, tests.Flags, log)
+       if msgr == nil || !msgr.IsReady() {
+               t.Errorf("#rmr_c_go_api_test.TestSendMsgRmrInvalidPortError - The rmr router is not ready")
        }
 
        }
 
-       go initRmr(tests.GetPort(), tests.MaxMsgSize, tests.Flags, log)
-       time.Sleep(time.Second)
-       assert.True(t, msgr == nil || !(*msgr).IsReady())
+       msg := rmrCgo.NewMBuf(1, tests.MaxMsgSize, "test 1", &tests.DummyPayload, &tests.DummyXAction)
+       log.Debugf("#rmr_c_go_api_test.TestSendMsgRmrInvalidPortError - Going to send the message: %#v\n", msg)
+       result, err := msgr.SendMsg(msg, true)
+
+       assert.NotNil(t, err)
+       assert.Nil(t, result)
+
+       msgr.Close()
 }
 
 }
 
-//func TestSendRecvMsgSuccess(t *testing.T) {
-//     var err error
-//     log, err = logger.InitLogger(true)
-//     if err != nil {
-//             t.Errorf("#rmrCgoApi_test.TestSendRecvMsgSuccess - failed to initialize logger, error: %s", err)
-//     }
-//     go initRmr(tests.GetPort(), tests.MaxMsgSize, tests.Flags, log)
-//     time.Sleep(time.Second)
-//     if msgr == nil || !(*msgr).IsReady()  {
-//             t.Errorf("#rmrCgoApi_test.TestSendRecvMsgSuccess - The rmr router is not ready")
-//     }
-//     msg := NewMBuf(1, tests.MaxMsgSize, &tests.DummyPayload, &tests.DummyXAction)
-//     log.Debugf("#rmrCgoApi_test.TestSendRecvMsgSuccess - Going to send the message: %#v\n", msg)
-//     msgR, _ := (*msgr).SendMsg(msg)
-//     log.Debugf("#rmrCgoApi_test.TestSendRecvMsgSuccess - The message has been sent %#v\n", msgR)
-//     log.Debugf("#rmrCgoApi_test.TestSendRecvMsgSuccess - The payload: %#v\n", msgR.Payload)
-//     msgR = (*msgr).RecvMsg()
-//     log.Debugf("#rmrCgoApi_test.TestSendRecvMsgSuccess - The message has been received: %#v\n", msgR)
-//     log.Debugf("#rmrCgoApi_test.TestSendRecvMsgSuccess - The payload: %#v\n", msgR.Payload)
-//     (*msgr).Close()
-//}
-
-//func TestIsReadySuccess(t *testing.T) {
-//     var err error
-//     log, err = logger.InitLogger(true)
-//     if err != nil {
-//             t.Errorf("#rmrCgoApi_test.TestIsReadySuccess - The rmr router is not ready")
-//     }
-//     go initRmr(tests.GetPort(), tests.MaxMsgSize, tests.Flags, log)
-//     time.Sleep(time.Second)
-//     if msgr == nil || !(*msgr).IsReady()  {
-//             t.Errorf("#rmrCgoApi_test.TestIsReadySuccess - The rmr router is not ready")
-//     }
-//}
-
-func initRmr(port string, maxMsgSize int, flags int, log *logger.Logger){
-       var ctx *Context
+func initRmr(port string, maxMsgSize int, flags int, log *logger.Logger) {
+       var ctx *rmrCgo.Context
        msgr = ctx.Init(port, maxMsgSize, flags, log)
        msgr = ctx.Init(port, maxMsgSize, flags, log)
+}*/
+
+func initLog(t *testing.T) *logger.Logger {
+       log, err := logger.InitLogger(logger.DebugLevel)
+       if err != nil {
+               t.Errorf("#rmr_c_go_api_test.initLog - failed to initialize logger, error: %s", err)
+       }
+       return log
 }
 }
index 3f8b189..eff707c 100644 (file)
@@ -74,6 +74,8 @@ const (
        RAN_CONNECTED                                            = C.RAN_CONNECTED
        RAN_RESTARTED                                            = C.RAN_RESTARTED
        RAN_RECONFIGURED                                         = C.RAN_RECONFIGURED
        RAN_CONNECTED                                            = C.RAN_CONNECTED
        RAN_RESTARTED                                            = C.RAN_RESTARTED
        RAN_RECONFIGURED                                         = C.RAN_RECONFIGURED
+       E2_TERM_KEEP_ALIVE_REQ                           = C.E2_TERM_KEEP_ALIVE_REQ
+       E2_TERM_KEEP_ALIVE_RESP                          = C.E2_TERM_KEEP_ALIVE_RESP
 )
 
 const (
 )
 
 const (
@@ -138,10 +140,9 @@ type Context struct {
 }
 
 type RmrMessenger interface {
 }
 
 type RmrMessenger interface {
-       Init(port string, maxMsgSize int, flags int, logger *logger.Logger) *RmrMessenger
-       SendMsg(msg *MBuf) (*MBuf, error)
+       Init(port string, maxMsgSize int, flags int, logger *logger.Logger) RmrMessenger
+       SendMsg(msg *MBuf, printLogs bool) (*MBuf, error)
        RecvMsg() (*MBuf, error)
        RecvMsg() (*MBuf, error)
-       RtsMsg(msg *MBuf)
        IsReady() bool
        Close()
 }
        IsReady() bool
        Close()
 }
diff --git a/E2Manager/rnibBuilders/node_info_builder_test.go b/E2Manager/rnibBuilders/node_info_builder_test.go
deleted file mode 100644 (file)
index fb95f8a..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Copyright 2019 AT&T Intellectual Property
-// Copyright 2019 Nokia
-//
-// 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 rnibBuilders
-
-import (
-       "e2mgr/models"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-       "github.com/stretchr/testify/assert"
-       "testing"
-)
-
-const ranName = "name"
-const ranIP = "ip"
-const ranPort = uint16(30000)
-
-func TestCreateInitialNodeInfo(t *testing.T) {
-       requestDetails :=  &models.SetupRequest{
-               RanName: ranName,
-               RanPort:ranPort,
-               RanIp:ranIP,
-       }
-       nodebInfo, identity := CreateInitialNodeInfo(requestDetails, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
-       assert.Equal(t, identity.InventoryName, ranName)
-       assert.Equal(t, nodebInfo.Ip, ranIP)
-       assert.Equal(t, nodebInfo.ConnectionStatus, entities.ConnectionStatus_CONNECTING)
-       assert.Equal(t, nodebInfo.E2ApplicationProtocol, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
-       assert.Equal(t, nodebInfo.Port, uint32(ranPort))
-}
\ No newline at end of file
index db4c6b0..8dfc5bc 100644 (file)
@@ -20,4 +20,5 @@ rte|1200|10.0.2.15:4801
 rte|1210|10.0.2.15:4801
 rte|1220|10.0.2.15:4801
 rte|10090|10.0.2.15:38000
 rte|1210|10.0.2.15:4801
 rte|1220|10.0.2.15:4801
 rte|10090|10.0.2.15:38000
+rte|1101|10.0.2.15:38000
 newrt|end
 newrt|end
diff --git a/E2Manager/router_test.txt b/E2Manager/router_test.txt
new file mode 100644 (file)
index 0000000..2315519
--- /dev/null
@@ -0,0 +1,3 @@
+newrt|start
+rte|1|127.0.0.1:3801
+newrt|end
index 60f3330..0a8eb8d 100644 (file)
@@ -29,10 +29,10 @@ import (
 type RmrReceiver struct {
        logger    *logger.Logger
        nManager  *notificationmanager.NotificationManager
 type RmrReceiver struct {
        logger    *logger.Logger
        nManager  *notificationmanager.NotificationManager
-       messenger *rmrCgo.RmrMessenger
+       messenger rmrCgo.RmrMessenger
 }
 
 }
 
-func NewRmrReceiver(logger *logger.Logger, messenger *rmrCgo.RmrMessenger, nManager *notificationmanager.NotificationManager) *RmrReceiver {
+func NewRmrReceiver(logger *logger.Logger, messenger rmrCgo.RmrMessenger, nManager *notificationmanager.NotificationManager) *RmrReceiver {
        return &RmrReceiver{
                logger:    logger,
                nManager:  nManager,
        return &RmrReceiver{
                logger:    logger,
                nManager:  nManager,
@@ -43,14 +43,15 @@ func NewRmrReceiver(logger *logger.Logger, messenger *rmrCgo.RmrMessenger, nMana
 func (r *RmrReceiver) ListenAndHandle() {
 
        for {
 func (r *RmrReceiver) ListenAndHandle() {
 
        for {
-               mbuf, err := (*r.messenger).RecvMsg()
-               r.logger.Debugf("#RmrReceiver.ListenAndHandle - Going to handle received message: %#v\n", mbuf)
+               mbuf, err := r.messenger.RecvMsg()
 
                if err != nil {
 
                if err != nil {
-                       // TODO: error handling?
+                       r.logger.Errorf("#RmrReceiver.ListenAndHandle - error: %s", err)
                        continue
                }
 
                        continue
                }
 
+               r.logger.Debugf("#RmrReceiver.ListenAndHandle - Going to handle received message: %#v\n", mbuf)
+
                // TODO: go routine?
                _ = r.nManager.HandleMessage(mbuf)
        }
                // TODO: go routine?
                _ = r.nManager.HandleMessage(mbuf)
        }
index c1729ce..5e766f7 100644 (file)
 package rmrreceiver
 
 import (
 package rmrreceiver
 
 import (
+       "e2mgr/clients"
        "e2mgr/configuration"
        "e2mgr/configuration"
-       "e2mgr/converters"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/managers/notificationmanager"
        "e2mgr/mocks"
        "e2mgr/providers/rmrmsghandlerprovider"
        "e2mgr/logger"
        "e2mgr/managers"
        "e2mgr/managers/notificationmanager"
        "e2mgr/mocks"
        "e2mgr/providers/rmrmsghandlerprovider"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/tests"
        "fmt"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
        "e2mgr/tests"
        "fmt"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "testing"
        "time"
 )
        "testing"
        "time"
 )
@@ -49,7 +47,7 @@ func TestListenAndHandle(t *testing.T) {
        time.Sleep(time.Microsecond * 10)
 }
 
        time.Sleep(time.Microsecond * 10)
 }
 
-func initRmrMessenger(log *logger.Logger) *rmrCgo.RmrMessenger {
+func initRmrMessenger(log *logger.Logger) rmrCgo.RmrMessenger {
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
        rmrMessengerMock := &mocks.RmrMessengerMock{}
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
@@ -58,32 +56,24 @@ func initRmrMessenger(log *logger.Logger) *rmrCgo.RmrMessenger {
        var buf *rmrCgo.MBuf
        e := fmt.Errorf("test error")
        rmrMessengerMock.On("RecvMsg").Return(buf, e)
        var buf *rmrCgo.MBuf
        e := fmt.Errorf("test error")
        rmrMessengerMock.On("RecvMsg").Return(buf, e)
-       return &rmrMessenger
+       return rmrMessenger
 }
 
 func initRmrReceiver(logger *logger.Logger) *RmrReceiver {
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
 
        readerMock := &mocks.RnibReaderMock{}
 }
 
 func initRmrReceiver(logger *logger.Logger) *RmrReceiver {
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
 
        readerMock := &mocks.RnibReaderMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
        writerMock := &mocks.RnibWriterMock{}
        writerMock := &mocks.RnibWriterMock{}
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
+       httpClient := &mocks.HttpClientMock{}
 
 
-       rnibDataService := services.NewRnibDataService(logger, config, rnibReaderProvider, rnibWriterProvider)
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
        rmrMessenger := initRmrMessenger(logger)
        rmrSender := rmrsender.NewRmrSender(logger, rmrMessenger)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
        rmrMessenger := initRmrMessenger(logger)
        rmrSender := rmrsender.NewRmrSender(logger, rmrMessenger)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
-       ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, ranSetupManager)
-       ranStatusChangeManager := managers.NewRanStatusChangeManager(logger, rmrSender)
-       x2SetupResponseConverter := converters.NewX2SetupResponseConverter(logger)
-       x2SetupResponseManager := managers.NewX2SetupResponseManager(x2SetupResponseConverter)
-       x2SetupFailureResponseConverter := converters.NewX2SetupFailureResponseConverter(logger)
-       x2SetupFailureResponseManager := managers.NewX2SetupFailureResponseManager(x2SetupFailureResponseConverter)
-       rmrNotificationHandlerProvider := rmrmsghandlerprovider.NewNotificationHandlerProvider(logger, rnibDataService, ranReconnectionManager, ranStatusChangeManager, rmrSender, x2SetupResponseManager, x2SetupFailureResponseManager )
+       e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, logger)
+       routingManagerClient := clients.NewRoutingManagerClient(logger, config, httpClient)
+       rmrNotificationHandlerProvider := rmrmsghandlerprovider.NewNotificationHandlerProvider()
+       rmrNotificationHandlerProvider.Init(logger, config, rnibDataService, rmrSender, ranSetupManager, e2tInstancesManager, routingManagerClient)
        notificationManager := notificationmanager.NewNotificationManager(logger, rmrNotificationHandlerProvider)
        return NewRmrReceiver(logger, rmrMessenger, notificationManager)
 }
        notificationManager := notificationmanager.NewNotificationManager(logger, rmrNotificationHandlerProvider)
        return NewRmrReceiver(logger, rmrMessenger, notificationManager)
 }
index 1d832d9..10e6a42 100644 (file)
@@ -28,10 +28,10 @@ import (
 
 type RmrSender struct {
        logger    *logger.Logger
 
 type RmrSender struct {
        logger    *logger.Logger
-       messenger *rmrCgo.RmrMessenger
+       messenger rmrCgo.RmrMessenger
 }
 
 }
 
-func NewRmrSender(logger *logger.Logger, messenger *rmrCgo.RmrMessenger) *RmrSender {
+func NewRmrSender(logger *logger.Logger, messenger rmrCgo.RmrMessenger) *RmrSender {
        return &RmrSender{
                logger:    logger,
                messenger: messenger,
        return &RmrSender{
                logger:    logger,
                messenger: messenger,
@@ -39,10 +39,9 @@ func NewRmrSender(logger *logger.Logger, messenger *rmrCgo.RmrMessenger) *RmrSen
 }
 
 func (r *RmrSender) Send(rmrMessage *models.RmrMessage) error {
 }
 
 func (r *RmrSender) Send(rmrMessage *models.RmrMessage) error {
-       transactionIdByteArr := []byte(rmrMessage.RanName)
-       msg := rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &transactionIdByteArr)
+       msg := rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction)
 
 
-       _, err := (*r.messenger).SendMsg(msg)
+       _, err := r.messenger.SendMsg(msg, true)
 
        if err != nil {
                r.logger.Errorf("#RmrSender.Send - RAN name: %s , Message type: %d - Failed sending message. Error: %v", rmrMessage.RanName, rmrMessage.MsgType, err)
 
        if err != nil {
                r.logger.Errorf("#RmrSender.Send - RAN name: %s , Message type: %d - Failed sending message. Error: %v", rmrMessage.RanName, rmrMessage.MsgType, err)
@@ -52,3 +51,16 @@ func (r *RmrSender) Send(rmrMessage *models.RmrMessage) error {
        r.logger.Infof("#RmrSender.Send - RAN name: %s , Message type: %d - Successfully sent RMR message", rmrMessage.RanName, rmrMessage.MsgType)
        return nil
 }
        r.logger.Infof("#RmrSender.Send - RAN name: %s , Message type: %d - Successfully sent RMR message", rmrMessage.RanName, rmrMessage.MsgType)
        return nil
 }
+
+func (r *RmrSender) SendWithoutLogs(rmrMessage *models.RmrMessage) error {
+       msg := rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction)
+
+       _, err := r.messenger.SendMsg(msg, false)
+
+       if err != nil {
+               r.logger.Errorf("#RmrSender.Send - RAN name: %s , Message type: %d - Failed sending message. Error: %v", rmrMessage.RanName, rmrMessage.MsgType, err)
+               return err
+       }
+
+       return nil
+}
index df53959..bc45307 100644 (file)
@@ -53,15 +53,15 @@ func TestRmrSenderSendSuccess(t *testing.T) {
 
        ranName := "test"
        payload := []byte("some payload")
 
        ranName := "test"
        payload := []byte("some payload")
-       xaction := []byte(ranName)
-       mbuf := rmrCgo.NewMBuf(123, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", mbuf).Return(&rmrCgo.MBuf{}, nil)
-       rmrMsg := models.NewRmrMessage(123, ranName, payload)
+       var xAction []byte
+       mbuf := rmrCgo.NewMBuf(123, len(payload), ranName, &payload, &xAction)
+       rmrMessengerMock.On("SendMsg", mbuf, true).Return(&rmrCgo.MBuf{}, nil)
+       rmrMsg := models.NewRmrMessage(123, ranName, payload, xAction)
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
-       rmrSender := NewRmrSender(logger, &rmrMessenger)
+       rmrSender := NewRmrSender(logger, rmrMessenger)
        err := rmrSender.Send(rmrMsg)
        assert.Nil(t, err)
        err := rmrSender.Send(rmrMsg)
        assert.Nil(t, err)
-       rmrMessengerMock.AssertCalled(t, "SendMsg",mbuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg",mbuf, true)
 
 }
 
 
 }
 
@@ -70,14 +70,14 @@ func TestRmrSenderSendFailure(t *testing.T) {
 
        ranName := "test"
        payload := []byte("some payload")
 
        ranName := "test"
        payload := []byte("some payload")
-       xaction := []byte(ranName)
-       mbuf := rmrCgo.NewMBuf(123, len(payload), ranName, &payload, &xaction)
-       rmrMessengerMock.On("SendMsg", mbuf).Return(mbuf, fmt.Errorf("rmr send failure"))
-       rmrMsg := models.NewRmrMessage(123, ranName, payload)
+       var xAction []byte
+       mbuf := rmrCgo.NewMBuf(123, len(payload), ranName, &payload, &xAction)
+       rmrMessengerMock.On("SendMsg", mbuf, true).Return(mbuf, fmt.Errorf("rmr send failure"))
+       rmrMsg := models.NewRmrMessage(123, ranName, payload, xAction)
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
-       rmrSender := NewRmrSender(logger, &rmrMessenger)
+       rmrSender := NewRmrSender(logger, rmrMessenger)
        err := rmrSender.Send(rmrMsg)
        err := rmrSender.Send(rmrMsg)
-       rmrMessengerMock.AssertCalled(t, "SendMsg",mbuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg",mbuf, true)
        assert.NotNil(t, err)
 }
 
        assert.NotNil(t, err)
 }
 
index 38b4723..1274c53 100644 (file)
@@ -24,9 +24,9 @@ import (
        "e2mgr/configuration"
        "e2mgr/logger"
        "e2mgr/rNibWriter"
        "e2mgr/configuration"
        "e2mgr/logger"
        "e2mgr/rNibWriter"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "net"
        "time"
 )
        "net"
        "time"
 )
@@ -38,23 +38,32 @@ type RNibDataService interface {
        GetNodeb(ranName string) (*entities.NodebInfo, error)
        GetListNodebIds() ([]*entities.NbIdentity, error)
        PingRnib() bool
        GetNodeb(ranName string) (*entities.NodebInfo, error)
        GetListNodebIds() ([]*entities.NbIdentity, error)
        PingRnib() bool
+       GetE2TInstance(address string) (*entities.E2TInstance, error)
+       GetE2TInstances(addresses []string) ([]*entities.E2TInstance, error)
+       GetE2TAddresses() ([]string, error)
+       SaveE2TInstance(e2tInstance *entities.E2TInstance) error
+       SaveE2TAddresses(addresses []string) error
+       GetE2TInstanceNoLogs(address string) (*entities.E2TInstance, error)
+       GetE2TInstancesNoLogs(addresses []string) ([]*entities.E2TInstance, error)
+       SaveE2TInstanceNoLogs(e2tInstance *entities.E2TInstance) error
+       GetE2TAddressesNoLogs() ([]string, error)
 }
 
 type rNibDataService struct {
 }
 
 type rNibDataService struct {
-       logger             *logger.Logger
-       rnibReaderProvider func() reader.RNibReader
-       rnibWriterProvider func() rNibWriter.RNibWriter
-       maxAttempts        int
-       retryInterval      time.Duration
+       logger        *logger.Logger
+       rnibReader    reader.RNibReader
+       rnibWriter    rNibWriter.RNibWriter
+       maxAttempts   int
+       retryInterval time.Duration
 }
 
 }
 
-func NewRnibDataService(logger *logger.Logger, config *configuration.Configuration, rnibReaderProvider func() reader.RNibReader, rnibWriterProvider func() rNibWriter.RNibWriter) *rNibDataService {
+func NewRnibDataService(logger *logger.Logger, config *configuration.Configuration, rnibReader reader.RNibReader, rnibWriter rNibWriter.RNibWriter) *rNibDataService {
        return &rNibDataService{
        return &rNibDataService{
-               logger:             logger,
-               rnibReaderProvider: rnibReaderProvider,
-               rnibWriterProvider: rnibWriterProvider,
-               maxAttempts:        config.MaxRnibConnectionAttempts,
-               retryInterval:      time.Duration(config.RnibRetryIntervalMs) * time.Millisecond,
+               logger:        logger,
+               rnibReader:    rnibReader,
+               rnibWriter:    rnibWriter,
+               maxAttempts:   config.MaxRnibConnectionAttempts,
+               retryInterval: time.Duration(config.RnibRetryIntervalMs) * time.Millisecond,
        }
 }
 
        }
 }
 
@@ -62,7 +71,7 @@ func (w *rNibDataService) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error {
        w.logger.Infof("#RnibDataService.UpdateNodebInfo - nodebInfo: %s", nodebInfo)
 
        err := w.retry("UpdateNodebInfo", func() (err error) {
        w.logger.Infof("#RnibDataService.UpdateNodebInfo - nodebInfo: %s", nodebInfo)
 
        err := w.retry("UpdateNodebInfo", func() (err error) {
-               err = w.rnibWriterProvider().UpdateNodebInfo(nodebInfo)
+               err = w.rnibWriter.UpdateNodebInfo(nodebInfo)
                return
        })
 
                return
        })
 
@@ -73,7 +82,7 @@ func (w *rNibDataService) SaveNodeb(nbIdentity *entities.NbIdentity, nb *entitie
        w.logger.Infof("#RnibDataService.SaveNodeb - nbIdentity: %s, nodebInfo: %s", nbIdentity, nb)
 
        err := w.retry("SaveNodeb", func() (err error) {
        w.logger.Infof("#RnibDataService.SaveNodeb - nbIdentity: %s, nodebInfo: %s", nbIdentity, nb)
 
        err := w.retry("SaveNodeb", func() (err error) {
-               err = w.rnibWriterProvider().SaveNodeb(nbIdentity, nb)
+               err = w.rnibWriter.SaveNodeb(nbIdentity, nb)
                return
        })
 
                return
        })
 
@@ -84,7 +93,7 @@ func (w *rNibDataService) SaveRanLoadInformation(inventoryName string, ranLoadIn
        w.logger.Infof("#RnibDataService.SaveRanLoadInformation - inventoryName: %s, ranLoadInformation: %s", inventoryName, ranLoadInformation)
 
        err := w.retry("SaveRanLoadInformation", func() (err error) {
        w.logger.Infof("#RnibDataService.SaveRanLoadInformation - inventoryName: %s, ranLoadInformation: %s", inventoryName, ranLoadInformation)
 
        err := w.retry("SaveRanLoadInformation", func() (err error) {
-               err = w.rnibWriterProvider().SaveRanLoadInformation(inventoryName, ranLoadInformation)
+               err = w.rnibWriter.SaveRanLoadInformation(inventoryName, ranLoadInformation)
                return
        })
 
                return
        })
 
@@ -97,7 +106,7 @@ func (w *rNibDataService) GetNodeb(ranName string) (*entities.NodebInfo, error)
        var nodeb *entities.NodebInfo = nil
 
        err := w.retry("GetNodeb", func() (err error) {
        var nodeb *entities.NodebInfo = nil
 
        err := w.retry("GetNodeb", func() (err error) {
-               nodeb, err = w.rnibReaderProvider().GetNodeb(ranName)
+               nodeb, err = w.rnibReader.GetNodeb(ranName)
                return
        })
 
                return
        })
 
@@ -110,16 +119,121 @@ func (w *rNibDataService) GetListNodebIds() ([]*entities.NbIdentity, error) {
        var nodeIds []*entities.NbIdentity = nil
 
        err := w.retry("GetListNodebIds", func() (err error) {
        var nodeIds []*entities.NbIdentity = nil
 
        err := w.retry("GetListNodebIds", func() (err error) {
-               nodeIds, err = w.rnibReaderProvider().GetListNodebIds()
+               nodeIds, err = w.rnibReader.GetListNodebIds()
                return
        })
 
        return nodeIds, err
 }
 
                return
        })
 
        return nodeIds, err
 }
 
+func (w *rNibDataService) GetE2TInstance(address string) (*entities.E2TInstance, error) {
+       var e2tInstance *entities.E2TInstance = nil
+
+       err := w.retry("GetE2TInstance", func() (err error) {
+               e2tInstance, err = w.rnibReader.GetE2TInstance(address)
+               return
+       })
+
+       if err == nil {
+               w.logger.Infof("#RnibDataService.GetE2TInstance - E2T instance address: %s, state: %s, associated RANs count: %d, keep Alive ts: %d", e2tInstance.Address, e2tInstance.State, len(e2tInstance.AssociatedRanList), e2tInstance.KeepAliveTimestamp)
+       }
+
+       return e2tInstance, err
+}
+
+func (w *rNibDataService) GetE2TInstanceNoLogs(address string) (*entities.E2TInstance, error) {
+       var e2tInstance *entities.E2TInstance = nil
+
+       err := w.retry("GetE2TInstance", func() (err error) {
+               e2tInstance, err = w.rnibReader.GetE2TInstance(address)
+               return
+       })
+
+       return e2tInstance, err
+}
+
+func (w *rNibDataService) GetE2TInstances(addresses []string) ([]*entities.E2TInstance, error) {
+       w.logger.Infof("#RnibDataService.GetE2TInstances - addresses: %s", addresses)
+       var e2tInstances []*entities.E2TInstance = nil
+
+       err := w.retry("GetE2TInstance", func() (err error) {
+               e2tInstances, err = w.rnibReader.GetE2TInstances(addresses)
+               return
+       })
+
+       return e2tInstances, err
+}
+
+func (w *rNibDataService) GetE2TInstancesNoLogs(addresses []string) ([]*entities.E2TInstance, error) {
+
+       var e2tInstances []*entities.E2TInstance = nil
+
+       err := w.retry("GetE2TInstance", func() (err error) {
+               e2tInstances, err = w.rnibReader.GetE2TInstances(addresses)
+               return
+       })
+
+       return e2tInstances, err
+}
+
+func (w *rNibDataService) GetE2TAddresses() ([]string, error) {
+
+       var e2tAddresses []string = nil
+
+       err := w.retry("GetE2TAddresses", func() (err error) {
+               e2tAddresses, err = w.rnibReader.GetE2TAddresses()
+               return
+       })
+
+       if err == nil {
+               w.logger.Infof("#RnibDataService.GetE2TAddresses - addresses: %s", e2tAddresses)
+       }
+
+       return e2tAddresses, err
+}
+
+func (w *rNibDataService) GetE2TAddressesNoLogs() ([]string, error) {
+
+       var e2tAddresses []string = nil
+
+       err := w.retry("GetE2TAddresses", func() (err error) {
+               e2tAddresses, err = w.rnibReader.GetE2TAddresses()
+               return
+       })
+
+       return e2tAddresses, err
+}
+
+func (w *rNibDataService) SaveE2TInstance(e2tInstance *entities.E2TInstance) error {
+       w.logger.Infof("#RnibDataService.SaveE2TInstance - E2T instance address: %s, state: %s, associated RANs count: %d, keep Alive ts: %d", e2tInstance.Address, e2tInstance.State, len(e2tInstance.AssociatedRanList), e2tInstance.KeepAliveTimestamp)
+
+       return w.SaveE2TInstanceNoLogs(e2tInstance)
+}
+
+func (w *rNibDataService) SaveE2TInstanceNoLogs(e2tInstance *entities.E2TInstance) error {
+
+       err := w.retry("SaveE2TInstance", func() (err error) {
+               err = w.rnibWriter.SaveE2TInstance(e2tInstance)
+               return
+       })
+
+       return err
+}
+
+func (w *rNibDataService) SaveE2TAddresses(addresses []string) error {
+       w.logger.Infof("#RnibDataService.SaveE2TAddresses - addresses: %s", addresses)
+
+       err := w.retry("SaveE2TAddresses", func() (err error) {
+               err = w.rnibWriter.SaveE2TAddresses(addresses)
+               return
+       })
+
+       return err
+}
+
 func (w *rNibDataService) PingRnib() bool {
        err := w.retry("GetListNodebIds", func() (err error) {
 func (w *rNibDataService) PingRnib() bool {
        err := w.retry("GetListNodebIds", func() (err error) {
-               _, err = w.rnibReaderProvider().GetListNodebIds()
+               _, err = w.rnibReader.GetListNodebIds()
                return
        })
 
                return
        })
 
@@ -147,7 +261,6 @@ func (w *rNibDataService) retry(rnibFunc string, f func() error) (err error) {
        }
 }
 
        }
 }
 
-
 func isRnibConnectionError(err error) bool {
        internalErr, ok := err.(*common.InternalError)
        if !ok {
 func isRnibConnectionError(err error) bool {
        internalErr, ok := err.(*common.InternalError)
        if !ok {
index fb86fe8..ab67a32 100644 (file)
@@ -24,11 +24,9 @@ import (
        "e2mgr/configuration"
        "e2mgr/logger"
        "e2mgr/mocks"
        "e2mgr/configuration"
        "e2mgr/logger"
        "e2mgr/mocks"
-       "e2mgr/rNibWriter"
        "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"
        "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"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/assert"
        "net"
        "strings"
        "github.com/stretchr/testify/assert"
        "net"
        "strings"
@@ -48,16 +46,12 @@ func setupRnibDataServiceTestWithMaxAttempts(t *testing.T, maxAttempts int) (*rN
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: maxAttempts}
 
        readerMock := &mocks.RnibReaderMock{}
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: maxAttempts}
 
        readerMock := &mocks.RnibReaderMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
+
 
        writerMock := &mocks.RnibWriterMock{}
 
        writerMock := &mocks.RnibWriterMock{}
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
 
 
-       rnibDataService := NewRnibDataService(logger, config, rnibReaderProvider, rnibWriterProvider)
+
+       rnibDataService := NewRnibDataService(logger, config, readerMock, writerMock)
        assert.NotNil(t, rnibDataService)
 
        return rnibDataService, readerMock, writerMock
        assert.NotNil(t, rnibDataService)
 
        return rnibDataService, readerMock, writerMock
@@ -277,3 +271,44 @@ func TestPingRnibOkOtherError(t *testing.T) {
 //     assert.True(t, strings.Contains(err.Error(),"connection failure", ))
 //     assert.Equal(t, nodeIds, res)
 //}
 //     assert.True(t, strings.Contains(err.Error(),"connection failure", ))
 //     assert.Equal(t, nodeIds, res)
 //}
+
+func TestGetE2TInstanceConnFailure(t *testing.T) {
+       rnibDataService, readerMock, _ := setupRnibDataServiceTest(t)
+
+       address := "10.10.5.20:3200"
+       var e2tInstance *entities.E2TInstance = nil
+       mockErr := &common.InternalError{Err: &net.OpError{Err: fmt.Errorf("connection error")}}
+       readerMock.On("GetE2TInstance", address).Return(e2tInstance, mockErr)
+
+       res, err := rnibDataService.GetE2TInstance(address)
+       readerMock.AssertNumberOfCalls(t, "GetE2TInstance", 3)
+       assert.Nil(t, res)
+       assert.NotNil(t, err)
+}
+
+func TestGetE2TInstanceOkNoError(t *testing.T) {
+       rnibDataService, readerMock, _ := setupRnibDataServiceTest(t)
+
+       address := "10.10.5.20:3200"
+       e2tInstance := &entities.E2TInstance{}
+       readerMock.On("GetE2TInstance", address).Return(e2tInstance, nil)
+
+       res, err := rnibDataService.GetE2TInstance(address)
+       readerMock.AssertNumberOfCalls(t, "GetE2TInstance", 1)
+       assert.Nil(t, err)
+       assert.Equal(t, e2tInstance, res)
+}
+
+func TestGetE2TInstanceOkOtherError(t *testing.T) {
+       rnibDataService, readerMock, _ := setupRnibDataServiceTest(t)
+
+       address := "10.10.5.20:3200"
+       var e2tInstance *entities.E2TInstance = nil
+       mockErr := &common.InternalError{Err: fmt.Errorf("non connection error")}
+       readerMock.On("GetE2TInstance", address).Return(e2tInstance, mockErr)
+
+       res, err := rnibDataService.GetE2TInstance(address)
+       readerMock.AssertNumberOfCalls(t, "GetE2TInstance", 1)
+       assert.Nil(t, res)
+       assert.NotNil(t, err)
+}
index 82df174..8095663 100644 (file)
@@ -31,7 +31,7 @@ import (
 
 const (
        MaxMsgSize  int    = 4096
 
 const (
        MaxMsgSize  int    = 4096
-       Port        int    = 5555
+       Port        int    = 3801
        Flags       int    = 0
        MessageType int    = 1001
        RanPort     uint16 = 879
        Flags       int    = 0
        MessageType int    = 1001
        RanPort     uint16 = 879
diff --git a/E2Manager/tests/utils.go b/E2Manager/tests/utils.go
new file mode 100644 (file)
index 0000000..894f554
--- /dev/null
@@ -0,0 +1,59 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package tests
+
+import (
+       "e2mgr/configuration"
+       "e2mgr/logger"
+       "e2mgr/mocks"
+       "e2mgr/rmrCgo"
+       "e2mgr/services"
+       "e2mgr/services/rmrsender"
+       "testing"
+)
+
+func InitLog(t *testing.T) *logger.Logger {
+       log, err := logger.InitLogger(logger.InfoLevel)
+       if err != nil {
+               t.Errorf("#test.utils.InitLog - failed to initialize logger, error: %s", err)
+       }
+       return log
+}
+
+func InitRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
+       rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
+       rmrMessengerMock.On("Init", GetPort(), MaxMsgSize, Flags, log).Return(&rmrMessenger)
+       return rmrsender.NewRmrSender(log, rmrMessenger)
+}
+
+func InitRnibDataService(t *testing.T) services.RNibDataService{
+
+       logger := InitLog(t)
+       config := InitConfiguration()
+
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
+
+       return services.NewRnibDataService(logger, config, readerMock, writerMock)
+}
+
+func InitConfiguration() *configuration.Configuration{
+       return &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
+}
+
+
index 685ac2d..65d5014 100644 (file)
@@ -20,7 +20,7 @@ openapi: 3.0.0
 info:
   title: E2 Manager Service
   description: E2 Manager Service APIs
 info:
   title: E2 Manager Service
   description: E2 Manager Service APIs
-  version: 2.0.5
+  version: 3.0.3
 servers:
   - url: 'http://{apiRoot}/v1'
     variables:
 servers:
   - url: 'http://{apiRoot}/v1'
     variables:
@@ -205,6 +205,26 @@ paths:
       responses:
         '200':
           description: OK
       responses:
         '200':
           description: OK
+  /e2t/list:
+    get:
+      tags:
+        - e2t
+      summary: Gets a list of all E2T Instances address and their associated RANs
+      responses:
+        '200':
+          description: Successful operation
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: '#/components/schemas/E2tIdentity'
+        '500':
+          description: Internal Error
+          content:
+            application/problem+json:
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
 components:
   schemas:
     SetupRequest:
 components:
   schemas:
     SetupRequest:
@@ -919,3 +939,27 @@ radioNetwork:pDCP-Overload]
         errorMessage:
           type: string
           description: Human readable text
         errorMessage:
           type: string
           description: Human readable text
+    E2tIdentity:
+      type: object
+      required:
+        - e2tAddress
+        - ranNames
+      properties:
+        e2tAddress:
+          type: string
+        ranNames:
+          items:
+            type: string
+          type: array
+    E2tErrorResponse:
+      type: object
+      required:
+        - errorCode
+        - errorMessage
+      properties:
+        errorCode:
+          type: string
+          description: '500 - RNIB error, 501 - internal problem'
+        errorMessage:
+          type: string
+          description: Human readable text
\ No newline at end of file
index 81c71b6..09e3399 100644 (file)
@@ -20,7 +20,7 @@ Release-Notes
 =============
 
 
 =============
 
 
-This document provides the release notes for the Amber Release of E2Manager
+This document provides the release notes for the Amber release of E2Manager
 
 .. contents::
    :depth: 3
 
 .. contents::
    :depth: 3
@@ -44,7 +44,7 @@ Version history
 
 Summary
 -------
 
 Summary
 -------
-The Amber release of E2Manager supports The following flows:
+The Amber release of E2Manager supports the following flows:
        - ENDC Setup
        - X2 Setup
        - ENDC Configuration Update
        - ENDC Setup
        - X2 Setup
        - ENDC Configuration Update
diff --git a/tools/RoutingManagerSimulator/Dockerfile b/tools/RoutingManagerSimulator/Dockerfile
new file mode 100644 (file)
index 0000000..66bff79
--- /dev/null
@@ -0,0 +1,34 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   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.
+#
+##############################################################################
+
+FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu16-c-go:2-u16.04-nng as ubuntu
+
+WORKDIR /opt/rmsimulator
+COPY . . 
+ENV PATH=$PATH:/usr/local/go/bin:/usr/lib/go-1.12/bin
+
+RUN go build main.go
+
+
+FROM ubuntu:16.04
+COPY --from=ubuntu /opt/rmsimulator/main /opt/rmsimulator/main
+COPY --from=ubuntu /opt/rmsimulator/resources /opt/rmsimulator/resources
+
+WORKDIR /opt/rmsimulator
+#CMD mkdir -p resources/conf  exec ./xappmock
+CMD exec ./main
diff --git a/tools/RoutingManagerSimulator/api/swagger.yaml b/tools/RoutingManagerSimulator/api/swagger.yaml
new file mode 100755 (executable)
index 0000000..db343d7
--- /dev/null
@@ -0,0 +1,363 @@
+---
+swagger: "2.0"
+info:
+  description: "This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound\
+    \ API."
+  version: "0.4.0"
+  title: "Routing Manager"
+  license:
+    name: "Apache 2.0"
+    url: "http://www.apache.org/licenses/LICENSE-2.0.html"
+host: "rtmgr"
+basePath: "/ric/v1"
+tags:
+- name: "handle"
+  description: "Available handles"
+- name: "health"
+  description: "Health of the system"
+schemes:
+- "http"
+paths:
+  /health:
+    get:
+      tags:
+      - "health"
+      summary: "Retrive the health of Routing Manager"
+      description: "By performing a GET method on the health resource, the API caller\
+        \ is able to retrieve the health of Routing Manager"
+      operationId: "get_health"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters: []
+      responses:
+        "200":
+          description: "The health of the system"
+          schema:
+            $ref: "#/definitions/health-status"
+  /handles:
+    get:
+      tags:
+      - "handle"
+      summary: "Placeholder for further usage"
+      description: "Placeholder for further usage."
+      operationId: "get_handles"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters: []
+      responses:
+        "200":
+          description: "Dummy response"
+  /handles/xapp-handle:
+    post:
+      tags:
+      - "handle"
+      summary: "Provide callback"
+      description: "By performing a POST method on the xapp-handle resource, the API\
+        \ caller is able to perform a callback on Routing Manager."
+      operationId: "provide_xapp_handle"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - in: "body"
+        name: "xapp-callback-data"
+        description: "xApp related callback data"
+        required: true
+        schema:
+          $ref: "#/definitions/xapp-callback-data"
+        x-exportParamName: "XappCallbackData"
+      responses:
+        "201":
+          description: "Callback received"
+        "400":
+          description: "Invalid data"
+  /handles/xapp-subscription-handle:
+    post:
+      tags:
+      - "handle"
+      summary: "API for updating about new xapp subscription"
+      description: "By performing a POST method on the xapp-subscription-handle resource,\
+        \ the API caller is able to update the Routing manager about the creation\
+        \ of new subscription by an Xapp instance."
+      operationId: "provide_xapp_subscription_handle"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - in: "body"
+        name: "xapp-subscription-data"
+        description: "xApp related subscription data"
+        required: true
+        schema:
+          $ref: "#/definitions/xapp-subscription-data"
+        x-exportParamName: "XappSubscriptionData"
+      responses:
+        "201":
+          description: "Xapp Subscription data received"
+        "400":
+          description: "Invalid data"
+    delete:
+      tags:
+      - "handle"
+      summary: "API for deleting an xapp subscription"
+      description: "By performing the delete operation on xapp-subscription-handle\
+        \ resource, the API caller will be able to update routing manager about the\
+        \ deletion of an xapp's subscription"
+      operationId: "delete_xapp_subscription_handle"
+      consumes:
+      - "application/json"
+      parameters:
+      - in: "body"
+        name: "xapp-subscription-data"
+        description: "xApp related subscription data"
+        required: true
+        schema:
+          $ref: "#/definitions/xapp-subscription-data"
+        x-exportParamName: "XappSubscriptionData"
+      responses:
+        "200":
+          description: "Xapp Subscription deleted"
+        "204":
+          description: "Content not found"
+  /handles/xapp-subscription-handle/{subscription_id}:
+    put:
+      tags:
+      - "handle"
+      summary: "API for updating the subscriber xApp list"
+      description: "By performing a PUT method on a xapp-subscription-handle/{subscription_id}\
+        \ resource, the API caller is able to update the Routing manager about the\
+        \ list of subscriber xApps related to the subscription denoted by the {subsription_id}."
+      operationId: "update_xapp_subscription_handle"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - name: "subscription_id"
+        in: "path"
+        description: "Subscription ID"
+        required: true
+        type: "integer"
+        format: "uint16"
+        x-exportParamName: "SubscriptionId"
+      - in: "body"
+        name: "xapp-list"
+        description: "xApp list"
+        required: true
+        schema:
+          $ref: "#/definitions/xapp-list"
+        x-exportParamName: "XappList"
+      responses:
+        "201":
+          description: "Xapp list received"
+        "400":
+          description: "Invalid data"
+  /handles/v1/e2t:
+    post:
+      tags:
+      - "handle"
+      summary: "API for establishing platform routes when a new e2t instance gets\
+        \ added to platform"
+      description: "E2T updates its FQDN to E2M  during its initialisation, hence\
+        \ after E2M informs routing manager about new E2T instances FQDN. At this\
+        \ point Routing Mgr would establish platform routes"
+      operationId: "create_new_e2t_handle"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - in: "body"
+        name: "e2t-data"
+        description: "FQDN of the newly joined E2T instance"
+        required: true
+        schema:
+          $ref: "#/definitions/e2t-data"
+        x-exportParamName: "E2tData"
+      responses:
+        "201":
+          description: "new e2t instance is considered and platform routes are established"
+        "400":
+          description: "Invalid data"
+    delete:
+      tags:
+      - "handle"
+      summary: "API for clearing routes specific to a particular e2T instance"
+      description: "E2M would monitor E2T instances using its keep alive based mechanism\
+        \ during this time if an E2T instance is detected to be dead, E2M would distribute\
+        \ already associated ran's to other available/healthy E2T instances. Here\
+        \ E2M would share E2T instance address to be removed OR which is unhealthy\
+        \ and list of RAN instances to be dissociated and an association list which\
+        \ contains E2T FQDN and associated RAN names"
+      operationId: "delete_e2t_handle"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - in: "body"
+        name: "e2t-data"
+        description: "FQDN of the newly joined E2T instance"
+        required: true
+        schema:
+          $ref: "#/definitions/e2t-delete-data"
+        x-exportParamName: "E2tData"
+      responses:
+        "201":
+          description: "new e2t instance is considered and platform routes are established"
+        "400":
+          description: "Invalid data"
+  /handles/v1/associate-ran-to-e2t:
+    post:
+      tags:
+      - "handle"
+      summary: "API for associating a ran to e2t instance"
+      description: "By performing a POST method on rane2tmapping, the API caller is\
+        \ able to update the Routing manager about the ran to e2t mapping which would\
+        \ be finally used to distribute routes to corresponding xApp and E2T instance"
+      operationId: "associate_ran_to_e2t_handle"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - in: "body"
+        name: "ran-e2t-list"
+        description: "ran to e2t mapping"
+        required: true
+        schema:
+          $ref: "#/definitions/ran-e2t-map"
+        x-exportParamName: "RanE2tList"
+      responses:
+        "201":
+          description: "e2t ran mapping recieved, platform routes"
+        "400":
+          description: "Invalid data"
+  /handles/v1/dissociate-ran:
+    post:
+      tags:
+      - "handle"
+      summary: "API to dissociate ran from e2t"
+      description: "By performing a POST method on rane2tmapping, routing manager\
+        \ will dissociate ran name from e2t instance by updating or clearing routes"
+      operationId: "dissociate_ran"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - in: "body"
+        name: "dissociate-list"
+        description: "list of RAN to dissociate"
+        required: true
+        schema:
+          $ref: "#/definitions/ran-e2t-map"
+        x-exportParamName: "DissociateList"
+      responses:
+        "201":
+          description: "ran instances disociated"
+        "400":
+          description: "Invalid data"
+definitions:
+  health-status:
+    type: "object"
+    properties:
+      status:
+        type: "string"
+        enum:
+        - "healthy"
+        - "unhealthy"
+    example:
+      status: "healthy"
+  xapp-callback-data:
+    type: "object"
+    properties:
+      id:
+        type: "string"
+      event:
+        type: "string"
+      version:
+        type: "integer"
+        format: "int64"
+      xApps:
+        type: "string"
+  xapp-subscription-data:
+    type: "object"
+    required:
+    - "address"
+    - "port"
+    - "subscription_id"
+    properties:
+      address:
+        type: "string"
+      port:
+        type: "integer"
+        format: "uint16"
+        minimum: 0
+        maximum: 65535
+      subscription_id:
+        type: "integer"
+        format: "int32"
+  xapp-list:
+    type: "array"
+    items:
+      $ref: "#/definitions/xapp-element"
+  xapp-element:
+    type: "object"
+    required:
+    - "address"
+    - "port"
+    properties:
+      address:
+        type: "string"
+      port:
+        type: "integer"
+        format: "uint16"
+        minimum: 0
+        maximum: 65535
+  ran-e2t-map:
+    type: "array"
+    items:
+      $ref: "#/definitions/ran-e2t-element"
+  ran-e2t-element:
+    type: "object"
+    required:
+    - "E2TAddress"
+    properties:
+      E2TAddress:
+        type: "string"
+      ranNamelist:
+        $ref: "#/definitions/ranNamelist"
+  ranNamelist:
+    type: "array"
+    items:
+      type: "string"
+  e2t-data:
+    type: "object"
+    required:
+    - "E2TAddress"
+    properties:
+      E2TAddress:
+        type: "string"
+      ranNamelist:
+        $ref: "#/definitions/ranNamelist"
+  e2t-delete-data:
+    type: "object"
+    required:
+    - "E2TAddress"
+    properties:
+      E2TAddress:
+        type: "string"
+      ranNamelistTobeDissociated:
+        $ref: "#/definitions/ranNamelist"
+      ranAssocList:
+        $ref: "#/definitions/ran-e2t-map"
+externalDocs:
+  description: "Routing Manager"
+  url: "http://placeholder"
diff --git a/tools/RoutingManagerSimulator/configuration/configuration.go b/tools/RoutingManagerSimulator/configuration/configuration.go
new file mode 100644 (file)
index 0000000..7e2cdef
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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 configuration
+
+import (
+       "fmt"
+       "github.com/spf13/viper"
+)
+
+type Configuration struct {
+       Http struct {
+               Port int
+       }
+
+}
+
+func ParseConfiguration() *Configuration{
+       viper.SetConfigType("yaml")
+       viper.SetConfigName("configuration")
+       viper.AddConfigPath("RoutingManagerSimulator/resources/")
+       viper.AddConfigPath("./resources/")  //For production
+       viper.AddConfigPath("../resources/") //For test under Docker
+       viper.AddConfigPath("../../resources/") //For test under Docker
+       err := viper.ReadInConfig()
+       if err != nil {
+               panic(fmt.Sprintf("#configuration.ParseConfiguration - failed to read configuration file: %s\n", err))
+       }
+
+       config := Configuration{}
+       config.fillHttpConfig(viper.Sub("http"))
+       return &config
+}
+
+func (c *Configuration)fillHttpConfig(httpConfig *viper.Viper) {
+       if httpConfig == nil {
+               panic(fmt.Sprintf("#configuration.fillHttpConfig - failed to fill HTTP configuration: The entry 'http' not found\n"))
+       }
+       c.Http.Port = httpConfig.GetInt("port")
+}
diff --git a/tools/RoutingManagerSimulator/configuration/configuration_test.go b/tools/RoutingManagerSimulator/configuration/configuration_test.go
new file mode 100644 (file)
index 0000000..a12f525
--- /dev/null
@@ -0,0 +1,76 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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 configuration
+
+import (
+       "github.com/stretchr/testify/assert"
+       "gopkg.in/yaml.v2"
+       "io/ioutil"
+       "os"
+       "testing"
+)
+
+func TestParseConfigurationSuccess(t *testing.T) {
+       config := ParseConfiguration()
+       assert.Equal(t, 12020, config.Http.Port)
+}
+
+func TestParseConfigurationFileNotFoundFailure(t *testing.T) {
+       configPath := "../resources/configuration.yaml"
+       configPathTmp := "../resources/configuration.yaml_tmp"
+       err := os.Rename(configPath, configPathTmp)
+       if err != nil {
+               t.Errorf("#TestParseConfigurationFileNotFoundFailure - failed to rename configuration file: %s\n", configPath)
+       }
+       defer func() {
+               err = os.Rename(configPathTmp, configPath)
+               if err != nil {
+                       t.Errorf("#TestParseConfigurationFileNotFoundFailure - failed to rename configuration file: %s\n", configPath)
+               }
+       }()
+       assert.Panics(t, func() { ParseConfiguration() })
+}
+
+func TestHttpConfigNotFoundFailure(t *testing.T) {
+       configPath := "../resources/configuration.yaml"
+       configPathTmp := "../resources/configuration.yaml_tmp"
+       err := os.Rename(configPath, configPathTmp)
+       if err != nil {
+               t.Errorf("#TestHttpConfigNotFoundFailure - failed to rename configuration file: %s\n", configPath)
+       }
+       defer func() {
+               err = os.Rename(configPathTmp, configPath)
+               if err != nil {
+                       t.Errorf("#TestHttpConfigNotFoundFailure - failed to rename configuration file: %s\n", configPath)
+               }
+       }()
+       yamlMap := map[string]interface{}{}
+       buf, err := yaml.Marshal(yamlMap)
+       if err != nil {
+               t.Errorf("#TestHttpConfigNotFoundFailure - failed to marshal configuration map\n")
+       }
+       err = ioutil.WriteFile("../resources/configuration.yaml", buf, 0644)
+       if err != nil {
+               t.Errorf("#TestHttpConfigNotFoundFailure - failed to write configuration file: %s\n", configPath)
+       }
+       assert.PanicsWithValue(t, "#configuration.fillHttpConfig - failed to fill HTTP configuration: The entry 'http' not found\n",
+               func() { ParseConfiguration() })
+}
diff --git a/tools/RoutingManagerSimulator/go.mod b/tools/RoutingManagerSimulator/go.mod
new file mode 100644 (file)
index 0000000..4ca14f1
--- /dev/null
@@ -0,0 +1,13 @@
+module rmsimulator
+
+go 1.12
+
+require (
+       github.com/gorilla/mux v1.7.0
+       github.com/pkg/errors v0.8.1
+       github.com/spf13/viper v1.6.1
+       github.com/stretchr/testify v1.4.0
+       go.uber.org/atomic v1.5.0
+       go.uber.org/zap v1.13.0
+       gopkg.in/yaml.v2 v2.2.4
+)
diff --git a/tools/RoutingManagerSimulator/go.sum b/tools/RoutingManagerSimulator/go.sum
new file mode 100644 (file)
index 0000000..0d7ed5a
--- /dev/null
@@ -0,0 +1,174 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+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-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/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
+github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
+github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
+github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
+github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
+github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
+github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
+github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
+gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
diff --git a/tools/RoutingManagerSimulator/go/api_handle.go b/tools/RoutingManagerSimulator/go/api_handle.go
new file mode 100755 (executable)
index 0000000..cb8936d
--- /dev/null
@@ -0,0 +1,79 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+import (
+       "net/http"
+)
+
+func AssociateRanToE2tHandle(w http.ResponseWriter, r *http.Request) {
+       w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+       w.WriteHeader(http.StatusOK)
+}
+
+func CreateNewE2tHandle(w http.ResponseWriter, r *http.Request) {
+       w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+       w.WriteHeader(http.StatusOK)
+}
+
+func DeleteE2tHandle(w http.ResponseWriter, r *http.Request) {
+       w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+       w.WriteHeader(http.StatusOK)
+}
+
+func DeleteXappSubscriptionHandle(w http.ResponseWriter, r *http.Request) {
+       w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+       w.WriteHeader(http.StatusOK)
+}
+
+func DissociateRan(w http.ResponseWriter, r *http.Request) {
+       w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+       w.WriteHeader(http.StatusOK)
+}
+
+func GetHandles(w http.ResponseWriter, r *http.Request) {
+       w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+       w.WriteHeader(http.StatusOK)
+}
+
+func ProvideXappHandle(w http.ResponseWriter, r *http.Request) {
+       w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+       w.WriteHeader(http.StatusOK)
+}
+
+func ProvideXappSubscriptionHandle(w http.ResponseWriter, r *http.Request) {
+       w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+       w.WriteHeader(http.StatusOK)
+}
+
+func UpdateXappSubscriptionHandle(w http.ResponseWriter, r *http.Request) {
+       w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+       w.WriteHeader(http.StatusOK)
+}
diff --git a/tools/RoutingManagerSimulator/go/api_health.go b/tools/RoutingManagerSimulator/go/api_health.go
new file mode 100755 (executable)
index 0000000..455f2d2
--- /dev/null
@@ -0,0 +1,38 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+import (
+       "net/http"
+)
+
+func GetHealth(w http.ResponseWriter, r *http.Request) {
+       w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+       w.WriteHeader(http.StatusOK)
+}
diff --git a/tools/RoutingManagerSimulator/go/logger.go b/tools/RoutingManagerSimulator/go/logger.go
new file mode 100755 (executable)
index 0000000..4e0d47b
--- /dev/null
@@ -0,0 +1,64 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+import (
+    "bytes"
+    "encoding/json"
+    "io/ioutil"
+    "log"
+    "net/http"
+    "time"
+)
+
+func Logger(inner http.Handler, name string) http.Handler {
+    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+        start := time.Now()
+
+        inner.ServeHTTP(w, r)
+
+        body, err := ioutil.ReadAll(r.Body)
+        if err != nil {
+            log.Printf("Error reading body: %v", err)
+            http.Error(w, "can't read body", http.StatusBadRequest)
+            return
+        }
+
+        buffer := new(bytes.Buffer)
+        _ =json.Compact(buffer, body)
+
+        log.Printf(
+            "%s %s  body: %s elapsed: %s",
+            r.Method,
+            r.RequestURI,
+            buffer,
+            time.Since(start),
+        )
+    })
+}
diff --git a/tools/RoutingManagerSimulator/go/model_e2t_data.go b/tools/RoutingManagerSimulator/go/model_e2t_data.go
new file mode 100755 (executable)
index 0000000..a939e90
--- /dev/null
@@ -0,0 +1,36 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+type E2tData struct {
+
+       E2TAddress string `json:"E2TAddress"`
+
+       RanNamelist *RanNamelist `json:"ranNamelist,omitempty"`
+}
diff --git a/tools/RoutingManagerSimulator/go/model_e2t_delete_data.go b/tools/RoutingManagerSimulator/go/model_e2t_delete_data.go
new file mode 100755 (executable)
index 0000000..88c21cc
--- /dev/null
@@ -0,0 +1,38 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+type E2tDeleteData struct {
+
+       E2TAddress string `json:"E2TAddress"`
+
+       RanNamelistTobeDissociated *RanNamelist `json:"ranNamelistTobeDissociated,omitempty"`
+
+       RanAssocList *RanE2tMap `json:"ranAssocList,omitempty"`
+}
diff --git a/tools/RoutingManagerSimulator/go/model_health_status.go b/tools/RoutingManagerSimulator/go/model_health_status.go
new file mode 100755 (executable)
index 0000000..a238b06
--- /dev/null
@@ -0,0 +1,34 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+type HealthStatus struct {
+
+       Status string `json:"status,omitempty"`
+}
diff --git a/tools/RoutingManagerSimulator/go/model_ran_e2t_element.go b/tools/RoutingManagerSimulator/go/model_ran_e2t_element.go
new file mode 100755 (executable)
index 0000000..1cf7397
--- /dev/null
@@ -0,0 +1,36 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+type RanE2tElement struct {
+
+       E2TAddress string `json:"E2TAddress"`
+
+       RanNamelist *RanNamelist `json:"ranNamelist,omitempty"`
+}
diff --git a/tools/RoutingManagerSimulator/go/model_ran_e2t_map.go b/tools/RoutingManagerSimulator/go/model_ran_e2t_map.go
new file mode 100755 (executable)
index 0000000..8ed6edc
--- /dev/null
@@ -0,0 +1,32 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+type RanE2tMap struct {
+}
diff --git a/tools/RoutingManagerSimulator/go/model_ran_namelist.go b/tools/RoutingManagerSimulator/go/model_ran_namelist.go
new file mode 100755 (executable)
index 0000000..ed69175
--- /dev/null
@@ -0,0 +1,32 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+type RanNamelist struct {
+}
diff --git a/tools/RoutingManagerSimulator/go/model_xapp_callback_data.go b/tools/RoutingManagerSimulator/go/model_xapp_callback_data.go
new file mode 100755 (executable)
index 0000000..1807b1e
--- /dev/null
@@ -0,0 +1,40 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+type XappCallbackData struct {
+
+       Id string `json:"id,omitempty"`
+
+       Event string `json:"event,omitempty"`
+
+       Version int64 `json:"version,omitempty"`
+
+       XApps string `json:"xApps,omitempty"`
+}
diff --git a/tools/RoutingManagerSimulator/go/model_xapp_element.go b/tools/RoutingManagerSimulator/go/model_xapp_element.go
new file mode 100755 (executable)
index 0000000..1439dec
--- /dev/null
@@ -0,0 +1,36 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+type XappElement struct {
+
+       Address string `json:"address"`
+
+       Port int32 `json:"port"`
+}
diff --git a/tools/RoutingManagerSimulator/go/model_xapp_list.go b/tools/RoutingManagerSimulator/go/model_xapp_list.go
new file mode 100755 (executable)
index 0000000..f561145
--- /dev/null
@@ -0,0 +1,32 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+type XappList struct {
+}
diff --git a/tools/RoutingManagerSimulator/go/model_xapp_subscription_data.go b/tools/RoutingManagerSimulator/go/model_xapp_subscription_data.go
new file mode 100755 (executable)
index 0000000..b36067d
--- /dev/null
@@ -0,0 +1,38 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+type XappSubscriptionData struct {
+
+       Address string `json:"address"`
+
+       Port int32 `json:"port"`
+
+       SubscriptionId int32 `json:"subscription_id"`
+}
diff --git a/tools/RoutingManagerSimulator/go/routers.go b/tools/RoutingManagerSimulator/go/routers.go
new file mode 100755 (executable)
index 0000000..6c34230
--- /dev/null
@@ -0,0 +1,146 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package swagger
+
+import (
+       "fmt"
+       "net/http"
+       "strings"
+
+       "github.com/gorilla/mux"
+)
+
+type Route struct {
+       Name        string
+       Method      string
+       Pattern     string
+       HandlerFunc http.HandlerFunc
+}
+
+type Routes []Route
+
+func NewRouter() *mux.Router {
+       router := mux.NewRouter().StrictSlash(true)
+       for _, route := range routes {
+               var handler http.Handler
+               handler = route.HandlerFunc
+               handler = Logger(handler, route.Name)
+
+               router.
+                       Methods(route.Method).
+                       Path(route.Pattern).
+                       Name(route.Name).
+                       Handler(handler)
+       }
+
+       return router
+}
+
+func Index(w http.ResponseWriter, r *http.Request) {
+       fmt.Fprintf(w, "Hello World!")
+}
+
+var routes = Routes{
+       Route{
+               "Index",
+               "GET",
+               "/ric/v1/",
+               Index,
+       },
+
+       Route{
+               "AssociateRanToE2tHandle",
+               strings.ToUpper("Post"),
+               "/ric/v1/handles/v1/associate-ran-to-e2t",
+               AssociateRanToE2tHandle,
+       },
+
+       Route{
+               "CreateNewE2tHandle",
+               strings.ToUpper("Post"),
+               "/ric/v1/handles/v1/e2t",
+               CreateNewE2tHandle,
+       },
+
+       Route{
+               "DeleteE2tHandle",
+               strings.ToUpper("Delete"),
+               "/ric/v1/handles/v1/e2t",
+               DeleteE2tHandle,
+       },
+
+       Route{
+               "DeleteXappSubscriptionHandle",
+               strings.ToUpper("Delete"),
+               "/ric/v1/handles/xapp-subscription-handle",
+               DeleteXappSubscriptionHandle,
+       },
+
+       Route{
+               "DissociateRan",
+               strings.ToUpper("Post"),
+               "/ric/v1/handles/v1/dissociate-ran",
+               DissociateRan,
+       },
+
+       Route{
+               "GetHandles",
+               strings.ToUpper("Get"),
+               "/ric/v1/handles",
+               GetHandles,
+       },
+
+       Route{
+               "ProvideXappHandle",
+               strings.ToUpper("Post"),
+               "/ric/v1/handles/xapp-handle",
+               ProvideXappHandle,
+       },
+
+       Route{
+               "ProvideXappSubscriptionHandle",
+               strings.ToUpper("Post"),
+               "/ric/v1/handles/xapp-subscription-handle",
+               ProvideXappSubscriptionHandle,
+       },
+
+       Route{
+               "UpdateXappSubscriptionHandle",
+               strings.ToUpper("Put"),
+               "/ric/v1/handles/xapp-subscription-handle/{subscription_id}",
+               UpdateXappSubscriptionHandle,
+       },
+
+       Route{
+               "GetHealth",
+               strings.ToUpper("Get"),
+               "/ric/v1/health",
+               GetHealth,
+       },
+}
diff --git a/tools/RoutingManagerSimulator/main.go b/tools/RoutingManagerSimulator/main.go
new file mode 100755 (executable)
index 0000000..f9f4824
--- /dev/null
@@ -0,0 +1,49 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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).
+
+
+/*
+ * Routing Manager
+ *
+ * This is the Swagger/OpenAPI 2.0 definition of Routing Manager's Northbound API.
+ *
+ * API version: 0.4.0
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package main
+
+import (
+       "fmt"
+       "log"
+       "net/http"
+       "rmsimulator/configuration"
+       "rmsimulator/go"
+)
+
+func main() {
+       config := configuration.ParseConfiguration()
+       port := config.Http.Port
+
+       log.Printf("Server started on port %d", port)
+
+       router := swagger.NewRouter()
+
+       log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), router))
+}
diff --git a/tools/RoutingManagerSimulator/resources/configuration.yaml b/tools/RoutingManagerSimulator/resources/configuration.yaml
new file mode 100644 (file)
index 0000000..e6fb1c2
--- /dev/null
@@ -0,0 +1,2 @@
+http:
+  port: 12020
diff --git a/tools/xapp_mock/configuration.json b/tools/xapp_mock/configuration.json
deleted file mode 100644 (file)
index 9df43a1..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-[ 
-       {“id”: “RIC_X2_SETUP_REQ” , “rmrMessageType”: 10060, “transactionId”: “e2e$”, “payloadHeader”: “$ranIp|$ranPort|$ranName|#packedPayload|”,  “packedPayload”: "3137322e31372e302e357c353537377c74657374327c34367c0006002a000002001500080013302300fffff000140017000001f700133023fffff0000000133023000000000001" },
-       {“id”: “RIC_ENB_CONF_UPDATE_ACK_positive” ,  “rmrMessageType”: 10081, “transactionId”: “e2e$”, “payloadHeader”: “$ranIp|$ranPort|$ranName|#packedPayload|”,  “packedPayload”: "2025000a00000100f70003000000" } 
-]
diff --git a/tools/xapp_mock/main/xapp_mock.go b/tools/xapp_mock/main/xapp_mock.go
deleted file mode 100644 (file)
index fd259f5..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-// Copyright 2019 AT&T Intellectual Property
-// Copyright 2019 Nokia
-//
-// 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 main
-
-import (
-       "../frontend"
-       "../rmr"
-       "../sender"
-       "flag"
-       "fmt"
-       "github.com/pkg/errors"
-       "log"
-       "os"
-       "strconv"
-)
-
-const (
-       ENV_RMR_PORT = "RMR_PORT"
-       RMR_PORT_DEFAULT = 5001
-)
-
-var rmrService *rmr.Service
-
-func main() {
-       var rmrContext *rmr.Context
-
-       var rmrConfig rmr.Config = rmr.Config{Port: RMR_PORT_DEFAULT, MaxMsgSize: rmr.RMR_MAX_MSG_SIZE, MaxRetries: 3, Flags: 0}
-       if port, err := strconv.ParseUint(os.Getenv(ENV_RMR_PORT), 10, 16); err == nil {
-               rmrConfig.Port = int(port)
-       } else {
-               log.Printf("%s: %s, using default (%d).", ENV_RMR_PORT, err,RMR_PORT_DEFAULT)
-       }
-       rmrService = rmr.NewService(rmrConfig, rmrContext)
-
-       /* Load configuration file*/
-       err := frontend.ProcessConfigurationFile("resources","conf",  ".json",
-               func(data []byte) error {
-                       return  frontend.JsonCommandsDecoder(data,jsonCommandsDecoderCB)
-               })
-       if err != nil {
-               log.Fatalf("processing Error: %s", err)
-       }
-
-       log.Print("xapp_mock is up and running.")
-
-       cmd:= flag.Arg(0) /*first remaining argument after flags have been processed*/
-       if err :=  frontend.JsonCommandDecoder([]byte(cmd),jsonCommandDecoderCB); err != nil {
-               log.Printf("command processing Error: %s", err)
-       }
-
-       rmrService.CloseContext()
-
-       log.Print("xapp_mock is down.")
-}
-
-
-// TODO: move callbacks to Dispatcher.
-func jsonCommandsDecoderCB(command *frontend.JsonCommand) error {
-       if len(command.Id) == 0{
-               return errors.New(fmt.Sprintf("invalid command, no Id"))
-       }
-       frontend.Configuration[command.Id] = command
-       if rmrMsgId, err := rmr.MessageIdToUint(command.WaitForRmrMessageType); err != nil {
-               return errors.New(fmt.Sprintf("invalid rmr message id: %s",command.WaitForRmrMessageType))
-       } else {
-               frontend.WaitedForRmrMessageType[int(rmrMsgId)] = command
-       }
-       return nil
-}
-
-// TODO: merge command with configuration
-func jsonCommandDecoderCB(command *frontend.JsonCommand) error {
-       if len(command.Id) == 0{
-               return errors.New(fmt.Sprintf("invalid command, no Id"))
-       }
-       switch command.Action {
-       case frontend.SendRmrMessage:
-               if  err := sender.SendJsonRmrMessage(*command, nil, rmrService); err != nil {
-                       return err
-               }
-               if len(command.WaitForRmrMessageType) > 0 {
-                       rmrService.ListenAndHandle() //TODO: handle error
-               }
-       case frontend.ReceiveRmrMessage:
-               if rmrMsgId, err := rmr.MessageIdToUint(command.RmrMessageType); err != nil {
-                       return errors.New(fmt.Sprintf("invalid rmr message id: %s",command.WaitForRmrMessageType))
-               } else {
-                       frontend.WaitedForRmrMessageType[int(rmrMsgId)] = command
-               }
-               rmrService.ListenAndHandle() //TODO: handle error
-       default:
-               return errors.New(fmt.Sprintf("invalid command action %s", command.Action))
-       }
-       return nil
-}
\ No newline at end of file
diff --git a/tools/xapp_mock/resources/router.txt b/tools/xapp_mock/resources/router.txt
deleted file mode 100644 (file)
index 1d3fea3..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-newrt|start
-rte|1001|10.0.2.15:38000
-rte|2002|10.0.2.15:3801
-newrt|end
similarity index 68%
rename from tools/xapp_mock/Dockerfile
rename to tools/xappmock/Dockerfile
index 4e08703..38db680 100644 (file)
 #   platform project (RICP).
 #
 
 #   platform project (RICP).
 #
 
-FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu16-c-go:1-u16.04-nng1.1.1 as ubuntu
+FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu16-c-go:2-u16.04-nng as ubuntu
 
 
-WORKDIR /opt/xapp_mock
+WORKDIR /opt/xappmock
 COPY . . 
 ENV PATH=$PATH:/usr/local/go/bin:/usr/lib/go-1.12/bin
 # Install RMr library and dev files
 COPY . . 
 ENV PATH=$PATH:/usr/local/go/bin:/usr/lib/go-1.12/bin
 # Install RMr library and dev files
-RUN wget --content-disposition https://packagecloud.io/o-ran-sc/master/packages/debian/stretch/rmr_1.3.0_amd64.deb/download.deb
-RUN dpkg -i rmr_1.3.0_amd64.deb
-RUN wget --content-disposition https://packagecloud.io/o-ran-sc/master/packages/debian/stretch/rmr-dev_1.3.0_amd64.deb/download.deb
-RUN dpkg -i rmr-dev_1.3.0_amd64.deb
+RUN wget --content-disposition  https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.10.0_amd64.deb/download.deb
+RUN dpkg -i rmr_1.10.0_amd64.deb
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.10.0_amd64.deb/download.deb
+RUN dpkg -i rmr-dev_1.10.0_amd64.deb
 
 
-RUN go get github.com/pkg/errors 
-RUN go build main/xapp_mock.go 
+RUN go build main/xappmock.go
     
 
 
 FROM ubuntu:16.04
     
 
 
 FROM ubuntu:16.04
-COPY --from=ubuntu /opt/xapp_mock/xapp_mock /opt/xapp_mock/xapp_mock
-COPY --from=ubuntu /opt/xapp_mock/resources /opt/xapp_mock/resources
+COPY --from=ubuntu /opt/xappmock/xappmock /opt/xappmock/xappmock
+COPY --from=ubuntu /opt/xappmock/resources /opt/xappmock/resources
 COPY --from=ubuntu /usr/local/lib/librmr_nng.so.1 /usr/local/lib/librmr_nng.so.1
 COPY --from=ubuntu /usr/local/lib/libnng.so.1 /usr/local/lib/libnng.so.1
 COPY --from=ubuntu /usr/local/lib/librmr_nng.so.1 /usr/local/lib/librmr_nng.so.1
 COPY --from=ubuntu /usr/local/lib/libnng.so.1 /usr/local/lib/libnng.so.1
-WORKDIR /opt/xapp_mock
+WORKDIR /opt/xappmock
 ENV LD_LIBRARY_PATH=/usr/local/lib 
 ENV RMR_SEED_RT=resources/router.txt
 ENV RMR_PORT=5001
 ENV LD_LIBRARY_PATH=/usr/local/lib 
 ENV RMR_SEED_RT=resources/router.txt
 ENV RMR_PORT=5001
-#CMD mkdir -p resources/conf  exec ./xapp_mock
+#CMD mkdir -p resources/conf  exec ./xappmock
 CMD mkdir -p resources/conf &&  exec /bin/bash 
 CMD mkdir -p resources/conf &&  exec /bin/bash 
diff --git a/tools/xappmock/dispatcher/dispatcher.go b/tools/xappmock/dispatcher/dispatcher.go
new file mode 100644 (file)
index 0000000..6e00592
--- /dev/null
@@ -0,0 +1,384 @@
+package dispatcher
+
+import (
+       "context"
+       "fmt"
+       "github.com/pkg/errors"
+       "reflect"
+       "sync"
+       "time"
+       "xappmock/enums"
+       "xappmock/logger"
+       "xappmock/models"
+       "xappmock/rmr"
+       "xappmock/sender"
+)
+
+// Id -> Command
+var configuration = make(map[string]*models.JsonCommand)
+
+// Rmr Message Id -> Command
+var waitForRmrMessageType = make(map[int]*models.JsonCommand)
+
+func addRmrMessageToWaitFor(rmrMessageToWaitFor string, command models.JsonCommand) error {
+       rmrMsgId, err := rmr.MessageIdToUint(rmrMessageToWaitFor)
+
+       if err != nil {
+               return errors.New(fmt.Sprintf("invalid rmr message id: %s", rmrMessageToWaitFor))
+       }
+
+       waitForRmrMessageType[int(rmrMsgId)] = &command
+       return nil
+}
+
+type Dispatcher struct {
+       rmrService    *rmr.Service
+       processResult models.ProcessResult
+       logger        *logger.Logger
+       jsonSender    *sender.JsonSender
+}
+
+func (d *Dispatcher) GetProcessResult() models.ProcessResult {
+       return d.processResult
+}
+
+func New(logger *logger.Logger, rmrService *rmr.Service, jsonSender *sender.JsonSender) *Dispatcher {
+       return &Dispatcher{
+               rmrService: rmrService,
+               logger:     logger,
+               jsonSender: jsonSender,
+       }
+}
+
+func (d *Dispatcher) JsonCommandsDecoderCB(cmd models.JsonCommand) error {
+       if len(cmd.Id) == 0 {
+               return errors.New(fmt.Sprintf("invalid cmd, no id"))
+       }
+       configuration[cmd.Id] = &cmd
+       return nil
+
+       //      if len(cmd.ReceiveCommandId) == 0 {
+       //              return nil
+       //      }
+       //
+       //      return addRmrMessageToWaitFor(cmd.ReceiveCommandId, cmd)
+}
+
+func (d *Dispatcher) sendNoRepeat(command models.JsonCommand) error {
+
+       if enums.CommandAction(command.Action) == enums.SendRmrMessage && d.processResult.StartTime == nil {
+               now := time.Now()
+               d.processResult.StartTime = &now
+       }
+
+       err := d.jsonSender.SendJsonRmrMessage(command, nil, d.rmrService)
+
+       if err != nil {
+               d.logger.Errorf("#Dispatcher.sendNoRepeat - error sending rmr message: %s", err)
+               d.processResult.Err = err
+               d.processResult.Stats.SentErrorCount.Inc()
+               return err
+       }
+
+       d.processResult.Stats.SentCount.Inc()
+       return nil
+}
+
+func (d *Dispatcher) sendWithRepeat(ctx context.Context, command models.JsonCommand) {
+
+       if enums.CommandAction(command.Action) == enums.SendRmrMessage && d.processResult.StartTime == nil {
+               now := time.Now()
+               d.processResult.StartTime = &now
+       }
+
+       for repeatCount := command.RepeatCount; repeatCount > 0; repeatCount-- {
+
+               select {
+               case <-ctx.Done():
+                       return
+               default:
+               }
+
+               err := d.jsonSender.SendJsonRmrMessage(command, nil, d.rmrService)
+
+               if err != nil {
+                       d.logger.Errorf("#Dispatcher.sendWithRepeat - error sending rmr message: %s", err)
+                       d.processResult.Stats.SentErrorCount.Inc()
+                       continue
+               }
+
+               d.processResult.Stats.SentCount.Inc()
+               time.Sleep(time.Duration(command.RepeatDelayInMs) * time.Millisecond)
+       }
+}
+
+func getReceiveRmrMessageType(receiveCommandId string) (string, error) {
+       command, ok := configuration[receiveCommandId]
+
+       if !ok {
+               return "", errors.New(fmt.Sprintf("invalid receive command id: %s", receiveCommandId))
+       }
+
+       if len(command.RmrMessageType) == 0 {
+               return "", errors.New(fmt.Sprintf("missing RmrMessageType for command id: %s", receiveCommandId))
+       }
+
+       return command.RmrMessageType, nil
+}
+
+func (d *Dispatcher) sendHandler(ctx context.Context, sendAndReceiveWg *sync.WaitGroup, command models.JsonCommand) {
+
+       defer sendAndReceiveWg.Done()
+       var listenAndHandleWg sync.WaitGroup
+
+       if len(command.ReceiveCommandId) > 0 {
+               rmrMessageToWaitFor, err := getReceiveRmrMessageType(command.ReceiveCommandId)
+
+               if err != nil {
+                       d.processResult.Err = err
+                       return
+               }
+
+               err = addRmrMessageToWaitFor(rmrMessageToWaitFor, command)
+
+               if err != nil {
+                       d.processResult.Err = err
+                       return
+               }
+
+               listenAndHandleWg.Add(1)
+               go d.listenAndHandle(ctx, &listenAndHandleWg, command)
+       }
+
+       if command.RepeatCount == 0 {
+               err := d.sendNoRepeat(command)
+
+               if err != nil {
+                       return
+               }
+
+       } else {
+               d.sendWithRepeat(ctx, command)
+       }
+
+       if len(command.ReceiveCommandId) > 0 {
+               listenAndHandleWg.Wait()
+       }
+}
+
+func (d *Dispatcher) receiveHandler(ctx context.Context, sendAndReceiveWg *sync.WaitGroup, command models.JsonCommand) {
+
+       defer sendAndReceiveWg.Done()
+
+       err := addRmrMessageToWaitFor(command.RmrMessageType, command)
+
+       if err != nil {
+               d.processResult.Err = err
+               return
+       }
+
+       var listenAndHandleWg sync.WaitGroup
+       listenAndHandleWg.Add(1) // this is due to the usage of listenAndHandle as a goroutine in the sender case
+       d.listenAndHandle(ctx, &listenAndHandleWg, command)
+}
+
+func getMergedCommand(cmd *models.JsonCommand) (models.JsonCommand, error) {
+       var command models.JsonCommand
+       if len(cmd.Id) == 0 {
+               return command, errors.New(fmt.Sprintf("invalid command, no id"))
+       }
+
+       command = *cmd
+
+       conf, ok := configuration[cmd.Id]
+
+       if ok {
+               command = *conf
+               mergeConfigurationAndCommand(&command, cmd)
+       }
+
+       return command, nil
+}
+
+func (d *Dispatcher) ProcessJsonCommand(ctx context.Context, cmd *models.JsonCommand) {
+
+       command, err := getMergedCommand(cmd)
+
+       if err != nil {
+               d.processResult.Err = err
+               return
+       }
+
+       var sendAndReceiveWg sync.WaitGroup
+
+       commandAction := enums.CommandAction(command.Action)
+
+       switch commandAction {
+
+       case enums.SendRmrMessage:
+               sendAndReceiveWg.Add(1)
+               go d.sendHandler(ctx, &sendAndReceiveWg, command)
+       case enums.ReceiveRmrMessage:
+               sendAndReceiveWg.Add(1)
+               go d.receiveHandler(ctx, &sendAndReceiveWg, command)
+       default:
+               d.processResult = models.ProcessResult{Err: errors.New(fmt.Sprintf("invalid command action %s", command.Action))}
+               return
+       }
+
+       sendAndReceiveWg.Wait()
+}
+
+func getResponseCommand(command models.JsonCommand) (*models.JsonCommand, error) {
+       responseCommand, ok := configuration[command.SendCommandId]
+
+       if !ok {
+               return nil, errors.New(fmt.Sprintf("invalid SendCommandId %s", command.SendCommandId))
+       }
+
+       return responseCommand, nil
+}
+
+func (d *Dispatcher) listenAndHandleNoRepeat(ctx context.Context, command models.JsonCommand) {
+       for {
+               select {
+               case <-ctx.Done():
+                       return
+               default:
+               }
+
+               mbuf, err := d.rmrService.RecvMessage()
+
+               if err != nil {
+                       d.logger.Errorf("#Dispatcher.listenAndHandleNoRepeat - error receiving message: %s", err)
+                       d.processResult.Err = err
+                       d.processResult.Stats.ReceivedErrorCount.Inc()
+                       return
+               }
+
+               if enums.CommandAction(command.Action) == enums.ReceiveRmrMessage && d.processResult.StartTime == nil {
+                       now := time.Now()
+                       d.processResult.StartTime = &now
+               }
+
+               messageInfo := models.NewMessageInfo(mbuf.MType, mbuf.Meid, mbuf.Payload, mbuf.XAction)
+
+               _, ok := waitForRmrMessageType[mbuf.MType]
+
+               if !ok {
+                       d.logger.Infof("#Dispatcher.listenAndHandleNoRepeat - received unexpected msg: %s", messageInfo)
+                       d.processResult.Stats.ReceivedUnexpectedCount.Inc()
+                       continue
+               }
+
+               d.logger.Infof("#Dispatcher.listenAndHandleNoRepeat - received expected msg: %s", messageInfo)
+               d.processResult.Stats.ReceivedExpectedCount.Inc()
+
+               if len(command.SendCommandId) > 0 {
+                       responseCommand, err := getResponseCommand(command)
+
+                       if err != nil {
+                               d.processResult.Err = err
+                               return
+                       }
+
+                       _ = d.sendNoRepeat(*responseCommand)
+               }
+
+               return
+       }
+}
+
+func (d *Dispatcher) listenAndHandleWithRepeat(ctx context.Context, command models.JsonCommand) {
+
+       var responseCommand *models.JsonCommand
+
+       if len(command.SendCommandId) > 0 {
+               var err error
+               responseCommand, err = getResponseCommand(command)
+
+               if err != nil {
+                       d.processResult.Err = err
+                       return
+               }
+       }
+
+       for d.processResult.Stats.ReceivedExpectedCount.Load() < int32(command.RepeatCount) {
+               select {
+               case <-ctx.Done():
+                       return
+               default:
+               }
+
+               mbuf, err := d.rmrService.RecvMessage()
+
+               if err != nil {
+                       d.logger.Errorf("#Dispatcher.listenAndHandleWithRepeat - error receiving message: %s", err)
+                       d.processResult.Stats.ReceivedErrorCount.Inc()
+                       continue
+               }
+
+               if enums.CommandAction(command.Action) == enums.ReceiveRmrMessage && d.processResult.StartTime == nil {
+                       now := time.Now()
+                       d.processResult.StartTime = &now
+               }
+
+               messageInfo := models.NewMessageInfo(mbuf.MType, mbuf.Meid, mbuf.Payload, mbuf.XAction)
+
+               _, ok := waitForRmrMessageType[mbuf.MType]
+
+               if !ok {
+                       d.logger.Infof("#Dispatcher.listenAndHandleWithRepeat - received unexpected msg: %s", messageInfo)
+                       d.processResult.Stats.ReceivedUnexpectedCount.Inc()
+                       continue
+               }
+
+               d.logger.Infof("#Dispatcher.listenAndHandleWithRepeat - received expected msg: %s", messageInfo)
+               d.processResult.Stats.ReceivedExpectedCount.Inc()
+
+               if responseCommand != nil {
+                       _ = d.sendNoRepeat(*responseCommand) // TODO: goroutine? + error handling
+               }
+       }
+}
+
+func (d *Dispatcher) listenAndHandle(ctx context.Context, listenAndHandleWg *sync.WaitGroup, command models.JsonCommand) {
+
+       defer listenAndHandleWg.Done()
+
+       if command.RepeatCount == 0 {
+               d.listenAndHandleNoRepeat(ctx, command)
+               return
+       }
+
+       d.listenAndHandleWithRepeat(ctx, command)
+}
+
+func mergeConfigurationAndCommand(conf *models.JsonCommand, cmd *models.JsonCommand) {
+       nFields := reflect.Indirect(reflect.ValueOf(cmd)).NumField()
+
+       for i := 0; i < nFields; i++ {
+               if fieldValue := reflect.Indirect(reflect.ValueOf(cmd)).Field(i); fieldValue.IsValid() {
+                       switch fieldValue.Kind() {
+                       case reflect.String:
+                               if fieldValue.Len() > 0 {
+                                       reflect.Indirect(reflect.ValueOf(conf)).Field(i).Set(fieldValue)
+                               }
+                       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+                               if fieldValue.Int() != 0 {
+                                       reflect.Indirect(reflect.ValueOf(conf)).Field(i).Set(fieldValue)
+                               }
+                       case reflect.Bool:
+                               if fieldValue.Bool() {
+                                       reflect.Indirect(reflect.ValueOf(conf)).Field(i).Set(fieldValue)
+                               }
+                       case reflect.Float64, reflect.Float32:
+                               if fieldValue.Float() != 0 {
+                                       reflect.Indirect(reflect.ValueOf(conf)).Field(i).Set(fieldValue)
+                               }
+                       default:
+                               reflect.Indirect(reflect.ValueOf(conf)).Field(i).Set(fieldValue)
+                       }
+               }
+       }
+}
diff --git a/tools/xappmock/enums/command_action.go b/tools/xappmock/enums/command_action.go
new file mode 100644 (file)
index 0000000..7e31239
--- /dev/null
@@ -0,0 +1,25 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package enums
+
+type CommandAction string
+
+const (
+       SendRmrMessage    CommandAction = "send"
+       ReceiveRmrMessage CommandAction = "receive"
+)
similarity index 92%
rename from tools/xapp_mock/frontend/configfile.go
rename to tools/xappmock/frontend/configfile.go
index 2f1923f..105d1dc 100644 (file)
@@ -27,7 +27,7 @@ import (
        "strings"
 )
 
        "strings"
 )
 
-func ProcessConfigurationFile(resourcesFolder, inputFolder,  suffix string, processor func(data []byte) error) error {
+func ProcessConfigurationFile(resourcesFolder, inputFolder, suffix string, processor func(data []byte) error) error {
        cwd, err := os.Getwd()
        if err != nil {
                return errors.New(err.Error())
        cwd, err := os.Getwd()
        if err != nil {
                return errors.New(err.Error())
similarity index 60%
rename from tools/xapp_mock/frontend/jsonDecoder.go
rename to tools/xappmock/frontend/jsonDecoder.go
index e5ee02a..844e63d 100644 (file)
@@ -25,57 +25,31 @@ import (
        "fmt"
        "github.com/pkg/errors"
        "io"
        "fmt"
        "github.com/pkg/errors"
        "io"
+       "xappmock/models"
 )
 
 )
 
-const (
-       SendRmrMessage  = "send"
-       ReceiveRmrMessage  = "receive"
-)
-
-
-type JsonCommand struct {
- Id string
- RmrMessageType  string
- TransactionId string
- RanName string
- RanIp string
- RanPort int
- PayloadHeader string
- PackedPayload string
- Payload string
- Action string
- WaitForRmrMessageType string
-}
-
-// Id -> Command
-var Configuration = make(map[string]*JsonCommand)
-// Rmr Message Id -> Command
-var WaitedForRmrMessageType = make(map[int]*JsonCommand)
-
-func JsonCommandDecoder(data []byte, processor func (*JsonCommand) error ) error {
+func DecodeJsonCommand(data []byte) (*models.JsonCommand, error) {
        dec := json.NewDecoder(bytes.NewReader(data))
        dec := json.NewDecoder(bytes.NewReader(data))
-       var cmd JsonCommand
+       var cmd models.JsonCommand
        if err := dec.Decode(&cmd); err != nil && err != io.EOF {
        if err := dec.Decode(&cmd); err != nil && err != io.EOF {
-               return errors.New(err.Error())
-       }
-       if err := processor (&cmd); err != nil {
-               return err
+               return nil, errors.New(err.Error())
        }
        }
-       return nil
+
+       return &cmd, nil
 }
 
 }
 
-func JsonCommandsDecoder(data []byte, processor func (*JsonCommand) error ) error {
+func JsonCommandsDecoder(data []byte, processor func(models.JsonCommand) error) error {
        dec := json.NewDecoder(bytes.NewReader(data))
        for {
        dec := json.NewDecoder(bytes.NewReader(data))
        for {
-               var commands []JsonCommand
+               var commands []models.JsonCommand
                if err := dec.Decode(&commands); err == io.EOF {
                        break
                } else if err != nil {
                        return errors.New(err.Error())
                }
                for i, cmd := range commands {
                if err := dec.Decode(&commands); err == io.EOF {
                        break
                } else if err != nil {
                        return errors.New(err.Error())
                }
                for i, cmd := range commands {
-                       if err := processor(&cmd); err != nil {
-                               return errors.New(fmt.Sprintf("processing error at #%d, %s",i,err))
+                       if err := processor(cmd); err != nil {
+                               return errors.New(fmt.Sprintf("processing error at #%d, %s", i, err))
                        }
                }
        }
                        }
                }
        }
diff --git a/tools/xappmock/go.mod b/tools/xappmock/go.mod
new file mode 100644 (file)
index 0000000..b61ff4a
--- /dev/null
@@ -0,0 +1,9 @@
+module xappmock
+
+go 1.12
+
+require (
+       github.com/pkg/errors v0.8.1
+       go.uber.org/atomic v1.5.0
+       go.uber.org/zap v1.13.0
+)
diff --git a/tools/xappmock/go.sum b/tools/xappmock/go.sum
new file mode 100644 (file)
index 0000000..81ca7d4
--- /dev/null
@@ -0,0 +1,57 @@
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c h1:IGkKhmfzcztjm6gYkykvu/NiS8kaqbCWAEWWAyf8J5U=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
diff --git a/tools/xappmock/logger/logger.go b/tools/xappmock/logger/logger.go
new file mode 100644 (file)
index 0000000..0c168d7
--- /dev/null
@@ -0,0 +1,184 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package logger
+
+import (
+       "fmt"
+       "go.uber.org/zap"
+       "go.uber.org/zap/zapcore"
+       "strings"
+       "time"
+)
+
+type Logger struct {
+       Logger     *zap.Logger
+}
+
+// Copied from zap logger
+//
+// A Level is a logging priority. Higher levels are more important.
+type LogLevel int8
+
+const (
+       // DebugLevel logs are typically voluminous, and are usually disabled in
+       // production.
+       DebugLevel LogLevel = iota - 1
+       // InfoLevel is the default logging priority.
+       InfoLevel
+       // WarnLevel logs are more important than Info, but don't need individual
+       // human review.
+       WarnLevel
+       // ErrorLevel logs are high-priority. If an application is running smoothly,
+       // it shouldn't generate any error-level logs.
+       ErrorLevel
+       // DPanicLevel logs are particularly important errors. In development the
+       // logger panics after writing the message.
+       DPanicLevel
+       // PanicLevel logs a message, then panics.
+       PanicLevel
+       // FatalLevel logs a message, then calls os.Exit(1).
+       FatalLevel
+
+       _minLevel = DebugLevel
+       _maxLevel = FatalLevel
+)
+
+var logLevelTokenToLevel = map[string] LogLevel {
+       "debug" : DebugLevel,
+       "info": InfoLevel,
+       "warn": WarnLevel,
+       "error": ErrorLevel,
+       "dpanic": DPanicLevel,
+       "panic": PanicLevel,
+       "fatal": FatalLevel,
+}
+
+func LogLevelTokenToLevel(level string) (LogLevel, bool) {
+       if level, ok := logLevelTokenToLevel[strings.TrimSpace(strings.ToLower(level))];ok {
+               return level, true
+       }
+       return _maxLevel+1, false
+}
+
+func InitLogger(requested LogLevel) (*Logger, error) {
+       var logger *zap.Logger
+       var err error
+       switch requested {
+       case DebugLevel:
+               logger, err = initLoggerByLevel(zapcore.DebugLevel)
+       case InfoLevel:
+               logger, err = initLoggerByLevel(zapcore.InfoLevel)
+       case WarnLevel:
+               logger, err = initLoggerByLevel(zapcore.WarnLevel)
+       case ErrorLevel:
+               logger, err = initLoggerByLevel(zapcore.ErrorLevel)
+       case DPanicLevel:
+               logger, err = initLoggerByLevel(zapcore.DPanicLevel)
+       case PanicLevel:
+               logger, err = initLoggerByLevel(zapcore.PanicLevel)
+       case FatalLevel:
+               logger, err = initLoggerByLevel(zapcore.FatalLevel)
+       default:
+               err = fmt.Errorf("Invalid logging Level :%d",requested)
+       }
+       if err != nil {
+               return nil, err
+       }
+       return &Logger{Logger:logger}, nil
+
+}
+func(l *Logger)Sync() error {
+       l.Debugf("#logger.Sync - Going to flush buffered log")
+       return l.Logger.Sync()
+}
+
+func (l *Logger)Infof(formatMsg string, a ...interface{})  {
+       if l.InfoEnabled() {
+               msg := fmt.Sprintf(formatMsg, a...)
+               l.Logger.Info(msg, zap.Any("mdc", l.getTimeStampMdc()))
+       }
+}
+
+func (l *Logger)Debugf(formatMsg string, a ...interface{})  {
+       if l.DebugEnabled(){
+               msg := fmt.Sprintf(formatMsg, a...)
+               l.Logger.Debug(msg, zap.Any("mdc", l.getTimeStampMdc()))
+       }
+}
+
+func (l *Logger)Errorf(formatMsg string, a ...interface{})  {
+       msg := fmt.Sprintf(formatMsg, a...)
+       l.Logger.Error(msg, zap.Any("mdc", l.getTimeStampMdc()))
+}
+
+func (l *Logger)Warnf(formatMsg string, a ...interface{})  {
+       msg := fmt.Sprintf(formatMsg, a...)
+       l.Logger.Warn(msg, zap.Any("mdc", l.getTimeStampMdc()))
+}
+
+func (l *Logger) getTimeStampMdc() map[string]string {
+       timeStr := time.Now().Format("2006-01-02 15:04:05.000")
+       mdc := map[string]string{"time": timeStr}
+       return mdc
+}
+
+func (l *Logger)InfoEnabled()bool{
+       return l.Logger.Core().Enabled(zap.InfoLevel)
+}
+
+func (l *Logger)DebugEnabled()bool{
+       return l.Logger.Core().Enabled(zap.DebugLevel)
+}
+
+func (l *Logger)DPanicf(formatMsg string, a ...interface{})  {
+       msg := fmt.Sprintf(formatMsg, a...)
+       l.Logger.DPanic(msg, zap.Any("mdc", l.getTimeStampMdc()))
+}
+
+func initLoggerByLevel(l zapcore.Level) (*zap.Logger, error) {
+       cfg := zap.Config{
+               Encoding:         "json",
+               Level:            zap.NewAtomicLevelAt(l),
+               OutputPaths:      []string{"stdout"},
+               ErrorOutputPaths: []string{"stderr"},
+               EncoderConfig: zapcore.EncoderConfig{
+                       MessageKey: "msg",
+
+                       LevelKey:    "crit",
+                       EncodeLevel: zapcore.CapitalLevelEncoder,
+
+                       TimeKey:    "ts",
+                       EncodeTime: epochMillisIntegerTimeEncoder,
+
+                       CallerKey: "id",
+                       EncodeCaller: xAppMockCallerEncoder,
+               },
+       }
+       return cfg.Build()
+}
+
+func xAppMockCallerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
+       enc.AppendString("xAppMock")
+}
+
+func epochMillisIntegerTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
+       nanos := t.UnixNano()
+       millis := int64(nanos) / int64(time.Millisecond)
+       enc.AppendInt64(millis)
+}
+
diff --git a/tools/xappmock/main/xappmock.go b/tools/xappmock/main/xappmock.go
new file mode 100644 (file)
index 0000000..8ae62f7
--- /dev/null
@@ -0,0 +1,115 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+package main
+
+import (
+       "context"
+       "flag"
+       "fmt"
+       "os"
+       "os/signal"
+       "strconv"
+       "time"
+       "xappmock/dispatcher"
+       "xappmock/frontend"
+       "xappmock/logger"
+       "xappmock/rmr"
+       "xappmock/sender"
+)
+
+const (
+       ENV_RMR_PORT     = "RMR_PORT"
+       RMR_PORT_DEFAULT = 5001
+)
+
+var rmrService *rmr.Service
+
+func main() {
+
+       logLevel, _ := logger.LogLevelTokenToLevel("info")
+       logger, err := logger.InitLogger(logLevel)
+       if err != nil {
+               fmt.Printf("#app.main - failed to initialize logger, error: %s", err)
+               os.Exit(1)
+       }
+
+       var rmrContext *rmr.Context
+       var rmrConfig = rmr.Config{Port: RMR_PORT_DEFAULT, MaxMsgSize: rmr.RMR_MAX_MSG_SIZE, MaxRetries: 10, Flags: 0}
+
+       if port, err := strconv.ParseUint(os.Getenv(ENV_RMR_PORT), 10, 16); err == nil {
+               rmrConfig.Port = int(port)
+       } else {
+               logger.Infof("#main - %s: %s, using default (%d).", ENV_RMR_PORT, err, RMR_PORT_DEFAULT)
+       }
+
+       rmrService = rmr.NewService(rmrConfig, rmrContext)
+       jsonSender := sender.NewJsonSender(logger)
+       dispatcherDesc := dispatcher.New(logger, rmrService, jsonSender)
+
+       /* Load configuration file*/
+       err = frontend.ProcessConfigurationFile("resources", "conf", ".json",
+               func(data []byte) error {
+                       return frontend.JsonCommandsDecoder(data, dispatcherDesc.JsonCommandsDecoderCB)
+               })
+
+       if err != nil {
+               logger.Errorf("#main - processing error: %s", err)
+               os.Exit(1)
+       }
+
+       logger.Infof("#main - xApp Mock is up and running...")
+
+       flag.Parse()
+       cmd := flag.Arg(0) /*first remaining argument after flags have been processed*/
+
+       command, err := frontend.DecodeJsonCommand([]byte(cmd))
+
+       if err != nil {
+               logger.Errorf("#main - command decoding error: %s", err)
+               rmrService.CloseContext()
+               logger.Infof("#main - xApp Mock is down")
+               return
+       }
+
+       c := make(chan os.Signal, 1)
+       signal.Notify(c, os.Interrupt)
+       ctx, cancel := context.WithCancel(context.Background())
+
+       go func() {
+               oscall := <-c
+               logger.Infof("system call:%+v", oscall)
+               cancel()
+               rmrService.CloseContext()
+       }()
+
+       dispatcherDesc.ProcessJsonCommand(ctx, command)
+       pr := dispatcherDesc.GetProcessResult()
+
+       if pr.Err != nil {
+               logger.Errorf("#main - command processing Error: %s", pr.Err)
+       }
+
+       if pr.StartTime != nil {
+               processElapsedTimeInMs := float64(time.Since(*pr.StartTime)) / float64(time.Millisecond)
+               logger.Infof("#main - processing (sending/receiving) messages took %.2f ms", processElapsedTimeInMs)
+
+       }
+       logger.Infof("#main - process stats: %s", pr.Stats)
+
+       rmrService.CloseContext() // TODO: called twice
+       logger.Infof("#main - xApp Mock is down")
+}
diff --git a/tools/xappmock/models/json_command.go b/tools/xappmock/models/json_command.go
new file mode 100644 (file)
index 0000000..6ebd731
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package models
+
+type JsonCommand struct {
+       Id               string
+       RmrMessageType   string
+       SendCommandId    string
+       ReceiveCommandId string
+       TransactionId    string
+       RanName          string
+       RanIp            string
+       RanPort          int
+       PayloadHeader    string
+       PackedPayload    string
+       Payload          string
+       Action           string
+       RepeatCount      int
+       RepeatDelayInMs  int
+}
diff --git a/tools/xappmock/models/message_info.go b/tools/xappmock/models/message_info.go
new file mode 100644 (file)
index 0000000..0833ffa
--- /dev/null
@@ -0,0 +1,48 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package models
+
+import (
+       "fmt"
+       "time"
+)
+
+// TODO: message command id / source / dest
+
+type MessageInfo struct {
+       MessageTimestamp int64  `json:"messageTimestamp"`
+       MessageType      int    `json:"messageType"`
+       Meid             string `json:"meid"`
+       Payload          []byte `json:"payload"`
+       TransactionId    string `json:"transactionId"`
+}
+
+func NewMessageInfo(messageType int, meid string, payload []byte, transactionId []byte) MessageInfo {
+       return MessageInfo{
+               MessageTimestamp: time.Now().Unix(),
+               MessageType:      messageType,
+               Meid:             meid,
+               Payload:          payload,
+               TransactionId:    string(transactionId),
+       }
+}
+
+func (mi MessageInfo) String() string {
+       return fmt.Sprintf("message timestamp: %d | message type: %d | meid: %s | payload: %x | transaction id: %s",
+               mi.MessageTimestamp, mi.MessageType, mi.Meid, mi.Payload, mi.TransactionId)
+}
diff --git a/tools/xappmock/models/process_result.go b/tools/xappmock/models/process_result.go
new file mode 100644 (file)
index 0000000..8847d2d
--- /dev/null
@@ -0,0 +1,43 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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.
+//
+
+package models
+
+import (
+       "fmt"
+       "go.uber.org/atomic"
+       "time"
+)
+
+type ProcessStats struct {
+       SentCount               atomic.Int32
+       SentErrorCount          atomic.Int32
+       ReceivedExpectedCount   atomic.Int32
+       ReceivedUnexpectedCount atomic.Int32
+       ReceivedErrorCount      atomic.Int32
+}
+
+type ProcessResult struct {
+       StartTime *time.Time
+       Stats     ProcessStats
+       Err       error
+}
+
+func (ps ProcessStats) String() string {
+       return fmt.Sprintf("sent messages: %d | send errors: %d | expected received messages: %d | unexpected received messages: %d | receive errors: %d",
+               ps.SentCount, ps.SentErrorCount, ps.ReceivedExpectedCount, ps.ReceivedUnexpectedCount, ps.ReceivedErrorCount)
+}
diff --git a/tools/xappmock/resources/conf/configuration.json b/tools/xappmock/resources/conf/configuration.json
new file mode 100644 (file)
index 0000000..212a955
--- /dev/null
@@ -0,0 +1,75 @@
+[
+  {
+    "id": "X2_SETUP_REQUEST",
+    "rmrMessageType": "10060",
+    "transactionId": "e2e$",
+    "payloadHeader": "$ranIp|$ranPort|$ranName|#packedPayload|",
+    "packedPayload": "0006002a000002001500080013302300fffff000140017000001f700133023fffff0000000133023000000000001"
+  },
+  {
+    "id": "X2_SETUP_RESPONSE",
+    "rmrMessageType": "10061",
+    "packedPayload": "2006002a000002001500080002f82900007ab000140017000000630002f8290007ab00102002f829000001000133"
+  },
+  {
+    "id": "RIC_SUBSCRIPTION_REQUEST",
+    "rmrMessageType": "12010",
+    "transactionId": "e2e$",
+    "packedPayload": "00c9002b000003ea7e0005004eec0182ea6300020001ea810015000a0011121300212224264000ea6b000420000000"
+  },
+  {
+    "id": "RIC_SUBSCRIPTION_RESPONSE",
+    "rmrMessageType": "12011",
+    "transactionId": "e2e$",
+    "packedPayload": "20c9001d000003ea7e0005004eec0182ea6300020001ea6c000700ea6d40020000"
+  },
+  {
+    "id": "RIC_SUBSCRIPTION_FAILURE",
+    "rmrMessageType": "12012",
+    "transactionId": "e2e$",
+    "packedPayload": "40c9001f000003ea7e00050000010001ea6300020000ea6e000908ea6f400400014100"
+  },
+  {
+    "id": "RIC_SUBSCRIPTION_DELETE_REQUEST",
+    "rmrMessageType": "12020",
+    "transactionId": "e2e$",
+    "packedPayload": "00ca0012000002ea7e0005004eec0182ea6300020001"
+  },
+  {
+    "id": "RIC_SUBSCRIPTION_DELETE_RESPONSE",
+    "rmrMessageType": "12021",
+    "transactionId": "e2e$",
+    "packedPayload": "20ca0012000002ea7e0005004eec0182ea6300020001"
+  },
+  {
+    "id": "RIC_INDICATION",
+    "rmrMessageType": "12050"
+  },
+  {
+    "id": "RESOURCE_STATUS_REQUEST",
+    "rmrMessageType": "10090",
+    "transactionId": "e2e$",
+    "packedPayload": "0009003c0000080027000300000e001c00010000260004fe000000001d400d00001f4008000a0b0cabcd8000001e4001000040400100006d4001000091400100"
+  },
+  {
+    "id": "RESOURCE_STATUS_RESPONSE",
+    "rmrMessageType": "10091",
+    "transactionId": "e2e$",
+    "packedPayload": "20090065000003002700030000000028000300004a00414050000042404b4013302302b030a2800043400700020000000a000043400700040000000a000043400700080000000a000043400700200000000a000043400700400000000a000043400700800000000a00"
+  },
+  {
+    "id": "RESOURCE_STATUS_FAILURE",
+    "rmrMessageType": "10092",
+    "transactionId": "e2e$",
+    "packedPayload": "400900320000040027000300000e0028000300000c00054001620044401800004540130002f8290007ab500000434006000000000740"
+  },
+  {
+    "id": "RESOURCE_STATUS_UPDATE",
+    "rmrMessageType": "10090"
+  },
+  {
+    "id": "LOAD_INFORMATION",
+    "rmrMessageType": "10020"
+  }
+]
+
diff --git a/tools/xappmock/resources/router.txt b/tools/xappmock/resources/router.txt
new file mode 100644 (file)
index 0000000..015ca2e
--- /dev/null
@@ -0,0 +1,29 @@
+newrt|start
+rte|10060|10.0.2.15:38000
+rte|10360|10.0.2.15:38000
+rte|10070|10.0.2.15:38000
+rte|10071|10.0.2.15:3801
+rte|10061|10.0.2.15:3801
+rte|10361|10.0.2.15:3801
+rte|10062|10.0.2.15:3801
+rte|10362|10.0.2.15:3801
+rte|1080|10.0.2.15:3801
+rte|10020|10.0.2.15:5557
+rte|10370|10.0.2.15:3801
+rte|10371|10.0.2.15:38000
+rte|10372|10.0.2.15:38000
+rte|10080|10.0.2.15:3801
+rte|10081|10.0.2.15:38000
+rte|10082|10.0.2.15:38000
+rte|1100|10.0.2.15:3801
+rte|1090|10.0.2.15:38000
+rte|1200|10.0.2.15:4801
+rte|1210|10.0.2.15:4801
+rte|1220|10.0.2.15:4801
+rte|10090|10.0.2.15:38000
+rte|12010|10.0.2.15:38000
+rte|12011|10.0.2.15:5555
+rte|12020|10.0.2.15:38000
+rte|10091|10.0.2.15:4801
+rte|10092|10.0.2.15:4801
+newrt|end
similarity index 100%
rename from tools/xapp_mock/resp
rename to tools/xappmock/resp
similarity index 92%
rename from tools/xapp_mock/rmr/rmrCgoApi.go
rename to tools/xappmock/rmr/rmrCgoApi.go
index 86b2c81..489591e 100644 (file)
@@ -52,7 +52,7 @@ func (*Context) Init(port string, maxMsgSize int, maxRetries int, flags int) *Me
 func (ctx *Context) SendMsg(msg *MBuf) (*MBuf, error) {
 
        allocatedCMBuf, err := ctx.getAllocatedCRmrMBuf(msg, ctx.MaxMsgSize)
 func (ctx *Context) SendMsg(msg *MBuf) (*MBuf, error) {
 
        allocatedCMBuf, err := ctx.getAllocatedCRmrMBuf(msg, ctx.MaxMsgSize)
-       if err != nil{
+       if err != nil {
                return nil, err
        }
        if state := allocatedCMBuf.state; state != RMR_OK {
                return nil, err
        }
        if state := allocatedCMBuf.state; state != RMR_OK {
@@ -61,14 +61,14 @@ func (ctx *Context) SendMsg(msg *MBuf) (*MBuf, error) {
        }
        defer C.rmr_free_msg(allocatedCMBuf)
 
        }
        defer C.rmr_free_msg(allocatedCMBuf)
 
-       for i:=0; i < ctx.MaxRetries; i++ {
+       for i := 0; i < ctx.MaxRetries; i++ {
                currCMBuf := C.rmr_send_msg(ctx.RmrCtx, allocatedCMBuf)
                if state := currCMBuf.state; state != RMR_OK {
                        if state != RMR_ERR_RETRY {
                                errorMessage := fmt.Sprintf("#rmrCgoApi.SendMsg - Failed to send message. state: %v - %s", state, states[int(state)])
                                return nil, errors.New(errorMessage)
                        }
                currCMBuf := C.rmr_send_msg(ctx.RmrCtx, allocatedCMBuf)
                if state := currCMBuf.state; state != RMR_OK {
                        if state != RMR_ERR_RETRY {
                                errorMessage := fmt.Sprintf("#rmrCgoApi.SendMsg - Failed to send message. state: %v - %s", state, states[int(state)])
                                return nil, errors.New(errorMessage)
                        }
-                       time.Sleep(100*time.Millisecond)
+                       time.Sleep(100 * time.Millisecond)
                        continue
                }
                return convertToMBuf(currCMBuf)
                        continue
                }
                return convertToMBuf(currCMBuf)
@@ -78,11 +78,11 @@ func (ctx *Context) SendMsg(msg *MBuf) (*MBuf, error) {
 }
 
 func (ctx *Context) RecvMsg() (*MBuf, error) {
 }
 
 func (ctx *Context) RecvMsg() (*MBuf, error) {
-       allocatedCMBuf, err :=C.rmr_alloc_msg(ctx.RmrCtx, C.int(ctx.MaxMsgSize))
-       if err != nil{
+       allocatedCMBuf, err := C.rmr_alloc_msg(ctx.RmrCtx, C.int(ctx.MaxMsgSize))
+       if err != nil {
                return nil, err
        }
                return nil, err
        }
-       if state := allocatedCMBuf.state;state != RMR_OK {
+       if state := allocatedCMBuf.state; state != RMR_OK {
                errorMessage := fmt.Sprintf("#rmrCgoApi.SendMsg - Failed to get allocated message. state: %v - %s", state, states[int(state)])
                return nil, errors.New(errorMessage)
        }
                errorMessage := fmt.Sprintf("#rmrCgoApi.SendMsg - Failed to get allocated message. state: %v - %s", state, states[int(state)])
                return nil, errors.New(errorMessage)
        }
@@ -97,7 +97,6 @@ func (ctx *Context) RecvMsg() (*MBuf, error) {
        return convertToMBuf(currCMBuf)
 }
 
        return convertToMBuf(currCMBuf)
 }
 
-
 func (ctx *Context) IsReady() bool {
        return int(C.rmr_ready(ctx.RmrCtx)) != 0
 }
 func (ctx *Context) IsReady() bool {
        return int(C.rmr_ready(ctx.RmrCtx)) != 0
 }
similarity index 97%
rename from tools/xapp_mock/rmr/rmrCgoTypes.go
rename to tools/xappmock/rmr/rmrCgoTypes.go
index 7307aac..3f1ce24 100644 (file)
@@ -98,17 +98,15 @@ type MBuf struct {
        XAction []byte
 }
 
        XAction []byte
 }
 
-
 func (m MBuf) String() string {
        return fmt.Sprintf("{ MType: %d, Len: %d, Meid: %q, Xaction: %q, Payload: [%x] }", m.MType, m.Len, m.Meid, m.XAction, m.Payload)
 }
 
 func (m MBuf) String() string {
        return fmt.Sprintf("{ MType: %d, Len: %d, Meid: %q, Xaction: %q, Payload: [%x] }", m.MType, m.Len, m.Meid, m.XAction, m.Payload)
 }
 
-
 type Context struct {
 type Context struct {
-       MaxMsgSize     int
-       MaxRetries     int
-       Flags          int
-       RmrCtx         unsafe.Pointer
+       MaxMsgSize int
+       MaxRetries int
+       Flags      int
+       RmrCtx     unsafe.Pointer
 }
 
 type Messenger interface {
 }
 
 type Messenger interface {
similarity index 83%
rename from tools/xapp_mock/rmr/rmrCgoUtils.go
rename to tools/xappmock/rmr/rmrCgoUtils.go
index 868b79c..d2fa040 100644 (file)
@@ -38,9 +38,9 @@ import (
 Allocates an mBuf and initialize it with the content of C.rmr_mbuf_t.
 The xAction field is assigned a a value without trailing spaces.
 */
 Allocates an mBuf and initialize it with the content of C.rmr_mbuf_t.
 The xAction field is assigned a a value without trailing spaces.
 */
-func convertToMBuf( m *C.rmr_mbuf_t) (*MBuf, error) {
-       payloadArr := C.GoBytes(unsafe.Pointer(m.payload),C.int(m.len))
-       xActionArr := C.GoBytes(unsafe.Pointer(m.xaction),C.int(RMR_MAX_XACTION_LEN))
+func convertToMBuf(m *C.rmr_mbuf_t) (*MBuf, error) {
+       payloadArr := C.GoBytes(unsafe.Pointer(m.payload), C.int(m.len))
+       xActionArr := C.GoBytes(unsafe.Pointer(m.xaction), C.int(RMR_MAX_XACTION_LEN))
 
        // Trim padding (space and 0)
        xActionStr := strings.TrimRight(string(xActionArr), "\040\000")
 
        // Trim padding (space and 0)
        xActionStr := strings.TrimRight(string(xActionArr), "\040\000")
@@ -57,7 +57,7 @@ func convertToMBuf( m *C.rmr_mbuf_t) (*MBuf, error) {
 
        meidBuf := make([]byte, RMR_MAX_MEID_LEN)
        if meidCstr := C.rmr_get_meid(m, (*C.uchar)(unsafe.Pointer(&meidBuf[0]))); meidCstr != nil {
 
        meidBuf := make([]byte, RMR_MAX_MEID_LEN)
        if meidCstr := C.rmr_get_meid(m, (*C.uchar)(unsafe.Pointer(&meidBuf[0]))); meidCstr != nil {
-               mbuf.Meid =     strings.TrimRight(string(meidBuf), "\000")
+               mbuf.Meid = strings.TrimRight(string(meidBuf), "\000")
        }
 
        return mbuf, nil
        }
 
        return mbuf, nil
@@ -67,9 +67,9 @@ func convertToMBuf( m *C.rmr_mbuf_t) (*MBuf, error) {
 Allocates an C.rmr_mbuf_t and initialize it with the content of mBuf.
 The xAction field is padded with trailing spaces upto capacity
 */
 Allocates an C.rmr_mbuf_t and initialize it with the content of mBuf.
 The xAction field is padded with trailing spaces upto capacity
 */
-func (ctx *Context) getAllocatedCRmrMBuf( mBuf *MBuf, maxMsgSize int) (cMBuf *C.rmr_mbuf_t, rc error) {
+func (ctx *Context) getAllocatedCRmrMBuf(mBuf *MBuf, maxMsgSize int) (cMBuf *C.rmr_mbuf_t, rc error) {
        var xActionBuf [RMR_MAX_XACTION_LEN]byte
        var xActionBuf [RMR_MAX_XACTION_LEN]byte
-       var meidBuf[RMR_MAX_MEID_LEN]byte
+       var meidBuf [RMR_MAX_MEID_LEN]byte
 
        cMBuf = C.rmr_alloc_msg(ctx.RmrCtx, C.int(maxMsgSize))
        cMBuf.mtype = C.int(mBuf.MType)
 
        cMBuf = C.rmr_alloc_msg(ctx.RmrCtx, C.int(maxMsgSize))
        cMBuf.mtype = C.int(mBuf.MType)
@@ -79,13 +79,13 @@ func (ctx *Context) getAllocatedCRmrMBuf( mBuf *MBuf, maxMsgSize int) (cMBuf *C.
        xActionLen := len(mBuf.XAction)
 
        copy(xActionBuf[:], mBuf.XAction)
        xActionLen := len(mBuf.XAction)
 
        copy(xActionBuf[:], mBuf.XAction)
-       for i:= xActionLen; i < RMR_MAX_XACTION_LEN; i++{
+       for i := xActionLen; i < RMR_MAX_XACTION_LEN; i++ {
                xActionBuf[i] = '\040' //space
        }
 
        // Add padding
        copy(meidBuf[:], mBuf.Meid)
                xActionBuf[i] = '\040' //space
        }
 
        // Add padding
        copy(meidBuf[:], mBuf.Meid)
-       for i:= len(mBuf.Meid); i < RMR_MAX_MEID_LEN; i++{
+       for i := len(mBuf.Meid); i < RMR_MAX_MEID_LEN; i++ {
                meidBuf[i] = 0
        }
 
                meidBuf[i] = 0
        }
 
@@ -101,19 +101,19 @@ func (ctx *Context) getAllocatedCRmrMBuf( mBuf *MBuf, maxMsgSize int) (cMBuf *C.
                return nil, errors.New(fmt.Sprintf("#rmrCgoUtils.getAllocatedCRmrMBuf - Failed to read xAction data to allocated RMR message buffer, %s", err))
        }
 
                return nil, errors.New(fmt.Sprintf("#rmrCgoUtils.getAllocatedCRmrMBuf - Failed to read xAction data to allocated RMR message buffer, %s", err))
        }
 
-       len := C.rmr_bytes2meid(cMBuf,  (*C.uchar)(unsafe.Pointer(&meidBuf[0])), C.int(RMR_MAX_XACTION_LEN))
+       len := C.rmr_bytes2meid(cMBuf, (*C.uchar)(unsafe.Pointer(&meidBuf[0])), C.int(RMR_MAX_XACTION_LEN))
        if int(len) != RMR_MAX_MEID_LEN {
                return nil, errors.New(
                        "#rmrCgoUtils.getAllocatedCRmrMBuf - Failed to copy meid data to allocated RMR message buffer")
        }
        if int(len) != RMR_MAX_MEID_LEN {
                return nil, errors.New(
                        "#rmrCgoUtils.getAllocatedCRmrMBuf - Failed to copy meid data to allocated RMR message buffer")
        }
-       return cMBuf,nil
+       return cMBuf, nil
 }
 
 func MessageIdToUint(id string) (msgId uint64, err error) {
        if len(id) == 0 {
                msgId, err = 0, nil
 }
 
 func MessageIdToUint(id string) (msgId uint64, err error) {
        if len(id) == 0 {
                msgId, err = 0, nil
-       } else{
+       } else {
                msgId, err = strconv.ParseUint(id, 10, 16)
        }
        return
                msgId, err = strconv.ParseUint(id, 10, 16)
        }
        return
-}
\ No newline at end of file
+}
similarity index 65%
rename from tools/xapp_mock/rmr/rmrEndPoint.go
rename to tools/xappmock/rmr/rmrEndPoint.go
index 03c0852..c8c8ae2 100644 (file)
 package rmr
 
 import (
 package rmr
 
 import (
-       "../frontend"
-       "log"
        "strconv"
 )
        "strconv"
 )
+
 // RmrService holds an instance of RMR messenger as well as its configuration
 type Service struct {
 // RmrService holds an instance of RMR messenger as well as its configuration
 type Service struct {
-       messenger  *Messenger
+       messenger *Messenger
 }
 
 // NewRmrService instantiates a new Rmr service instance
 }
 
 // NewRmrService instantiates a new Rmr service instance
@@ -36,36 +35,17 @@ func NewService(rmrConfig Config, messenger Messenger) *Service {
        }
 }
 
        }
 }
 
-func (r *Service) SendMessage(messageType int, msg []byte, transactionId []byte) (*MBuf, error){
-       log.Printf( "SendMessage (type: %d, tid: %s, msg: %v", messageType, transactionId, msg)
+func (r *Service) SendMessage(messageType int, ranName string, msg []byte, transactionId []byte) (*MBuf, error) {
        mbuf := NewMBuf(messageType, len(msg), msg, transactionId)
        mbuf := NewMBuf(messageType, len(msg), msg, transactionId)
+       mbuf.Meid = ranName
        return (*r.messenger).SendMsg(mbuf)
 }
 
        return (*r.messenger).SendMsg(mbuf)
 }
 
-// ListenAndHandle waits for messages coming from rmr_rcv_msg and sends it to a designated message handler
-func (r *Service) ListenAndHandle() error {
-       for {
-               mbuf, err := (*r.messenger).RecvMsg()
-
-               if err != nil {
-                       return err
-               }
-
-               if _, ok := frontend.WaitedForRmrMessageType[mbuf.MType]; ok {
-                       log.Printf( "ListenAndHandle Expected msg: %s", mbuf)
-                       break
-               } else {
-                       log.Printf( "ListenAndHandle Unexpected msg: %s", mbuf)
-               }
-       }
-       return nil
+func (r *Service) RecvMessage() (*MBuf, error) {
+       return (*r.messenger).RecvMsg()
 }
 
 }
 
-
 func (r *Service) CloseContext() {
        (*r.messenger).Close()
 
 }
 func (r *Service) CloseContext() {
        (*r.messenger).Close()
 
 }
-
-
-
similarity index 69%
rename from tools/xapp_mock/sender/jsonSender.go
rename to tools/xappmock/sender/jsonSender.go
index d7d4ffb..f890add 100644 (file)
@@ -20,22 +20,33 @@ Binary file (standard input) matches
 package sender
 
 import (
 package sender
 
 import (
-       "../frontend"
-       "../rmr"
        "fmt"
        "github.com/pkg/errors"
        "fmt"
        "github.com/pkg/errors"
-       "log"
+       "os"
        "reflect"
        "strconv"
        "strings"
        "sync/atomic"
        "time"
        "unicode"
        "reflect"
        "strconv"
        "strings"
        "sync/atomic"
        "time"
        "unicode"
+       "xappmock/logger"
+       "xappmock/models"
+       "xappmock/rmr"
 )
 
 var counter uint64
 
 )
 
 var counter uint64
 
-func SendJsonRmrMessage(command frontend.JsonCommand /*the copy is modified locally*/, xAction *[]byte, r *rmr.Service) error {
+type JsonSender struct {
+       logger *logger.Logger
+}
+
+func NewJsonSender(logger *logger.Logger) *JsonSender {
+       return &JsonSender{
+               logger: logger,
+       }
+}
+
+func (s *JsonSender) SendJsonRmrMessage(command models.JsonCommand /*the copy is modified locally*/, xAction *[]byte, r *rmr.Service) error {
        var payload []byte
        _, err := fmt.Sscanf(command.PackedPayload, "%x", &payload)
        if err != nil {
        var payload []byte
        _, err := fmt.Sscanf(command.PackedPayload, "%x", &payload)
        if err != nil {
@@ -46,12 +57,18 @@ func SendJsonRmrMessage(command frontend.JsonCommand /*the copy is modified loca
        if len(command.TransactionId) == 0 {
                command.TransactionId = string(*xAction)
        }
        if len(command.TransactionId) == 0 {
                command.TransactionId = string(*xAction)
        }
-       command.PayloadHeader = expandPayloadHeader(command.PayloadHeader, &command)
+       command.PayloadHeader = s.expandPayloadHeader(command.PayloadHeader, &command)
+       s.logger.Infof("#JsonSender.SendJsonRmrMessage - command payload header: %s", command.PayloadHeader)
        rmrMsgId, err := rmr.MessageIdToUint(command.RmrMessageType)
        if err != nil {
        rmrMsgId, err := rmr.MessageIdToUint(command.RmrMessageType)
        if err != nil {
-               return errors.New(fmt.Sprintf("invalid rmr message id: %s",command.WaitForRmrMessageType))
+               return errors.New(fmt.Sprintf("invalid rmr message id: %s", command.RmrMessageType))
        }
        }
-       _, err = r.SendMessage(int(rmrMsgId), append([]byte(command.PayloadHeader), payload...), []byte(command.TransactionId))
+
+       msg := append([]byte(command.PayloadHeader), payload...)
+       messageInfo := models.NewMessageInfo(int(rmrMsgId), command.RanName, msg, []byte(command.TransactionId))
+       s.logger.Infof("#JsonSender.SendJsonRmrMessage - going to send message: %s", messageInfo)
+
+       _, err = r.SendMessage(int(rmrMsgId), command.RanName, msg, []byte(command.TransactionId))
        return err
 }
 
        return err
 }
 
@@ -78,7 +95,7 @@ func expandTransactionId(id string) string {
  * Example: “payloadHeader”: “$ranIp|$ranPort|$ranName|#packedPayload|”
  */
 
  * Example: “payloadHeader”: “$ranIp|$ranPort|$ranName|#packedPayload|”
  */
 
-func expandPayloadHeader(header string, command *frontend.JsonCommand) string {
+func (s *JsonSender) expandPayloadHeader(header string, command *models.JsonCommand) string {
        var name strings.Builder
        var expandedHeader strings.Builder
 
        var name strings.Builder
        var expandedHeader strings.Builder
 
@@ -88,12 +105,17 @@ func expandPayloadHeader(header string, command *frontend.JsonCommand) string {
                if err != nil {
                        break
                }
                if err != nil {
                        break
                }
+
                switch ch {
                case '$':
                        for {
                switch ch {
                case '$':
                        for {
-                               ch, err = r.ReadByte()  //on error ch == 0
+                               ch, err = r.ReadByte() //on error ch == 0
                                if unicode.IsDigit(rune(ch)) || unicode.IsLetter(rune(ch)) {
                                if unicode.IsDigit(rune(ch)) || unicode.IsLetter(rune(ch)) {
-                                       name.WriteByte(ch)
+                                       if name.Len() == 0 {
+                                               name.WriteByte(byte(unicode.ToUpper(rune(ch))))
+                                       } else {
+                                               name.WriteByte(ch)
+                                       }
                                } else {
                                        if fieldValue := reflect.Indirect(reflect.ValueOf(command)).FieldByName(name.String()); fieldValue.IsValid() {
                                                switch fieldValue.Kind() {
                                } else {
                                        if fieldValue := reflect.Indirect(reflect.ValueOf(command)).FieldByName(name.String()); fieldValue.IsValid() {
                                                switch fieldValue.Kind() {
@@ -106,7 +128,8 @@ func expandPayloadHeader(header string, command *frontend.JsonCommand) string {
                                                case reflect.Float64, reflect.Float32:
                                                        expandedHeader.WriteString(fmt.Sprintf("%g", fieldValue.Float()))
                                                default:
                                                case reflect.Float64, reflect.Float32:
                                                        expandedHeader.WriteString(fmt.Sprintf("%g", fieldValue.Float()))
                                                default:
-                                                       log.Fatalf("invalid type for $%s, value must be a string, an int, a bool or a float", name.String())
+                                                       s.logger.Errorf("#JsonSender.expandPayloadHeader - invalid type for $%s, value must be a string, an int, a bool or a float", name.String())
+                                                       os.Exit(1)
                                                }
                                        }
                                        name.Reset()
                                                }
                                        }
                                        name.Reset()
@@ -115,15 +138,20 @@ func expandPayloadHeader(header string, command *frontend.JsonCommand) string {
                        }
                case '#':
                        for {
                        }
                case '#':
                        for {
-                               ch, err = r.ReadByte()  //on error ch == 0
+                               ch, err = r.ReadByte() //on error ch == 0
                                if unicode.IsDigit(rune(ch)) || unicode.IsLetter(rune(ch)) {
                                if unicode.IsDigit(rune(ch)) || unicode.IsLetter(rune(ch)) {
-                                       name.WriteByte(ch)
+                                       if name.Len() == 0 {
+                                               name.WriteByte(byte(unicode.ToUpper(rune(ch))))
+                                       } else {
+                                               name.WriteByte(ch)
+                                       }
                                } else {
                                        if fieldValue := reflect.Indirect(reflect.ValueOf(command)).FieldByName(name.String()); fieldValue.IsValid() {
                                                if fieldValue.Kind() == reflect.String {
                                                        expandedHeader.WriteString(strconv.FormatInt(int64(len(fieldValue.String())), 10))
                                                } else {
                                } else {
                                        if fieldValue := reflect.Indirect(reflect.ValueOf(command)).FieldByName(name.String()); fieldValue.IsValid() {
                                                if fieldValue.Kind() == reflect.String {
                                                        expandedHeader.WriteString(strconv.FormatInt(int64(len(fieldValue.String())), 10))
                                                } else {
-                                                       log.Fatalf("invalid type for #%s, value must be a string", name.String())
+                                                       s.logger.Errorf("#JsonSender.expandPayloadHeader - invalid type for #%s, value must be a string", name.String())
+                                                       os.Exit(1)
                                                }
                                        }
                                        name.Reset()
                                                }
                                        }
                                        name.Reset()
@@ -145,5 +173,5 @@ func incAndGetCounter() uint64 {
 }
 
 func init() {
 }
 
 func init() {
-       counter = uint64(time.Now().Second())
+       counter = uint64(time.Now().Unix() - 1572000000)
 }
 }