[RICPLT-2526] KeepAlive worker and response. 30/2030/1
authorIrina <ib565x@intl.att.com>
Mon, 16 Dec 2019 12:20:38 +0000 (14:20 +0200)
committerIrina <ib565x@intl.att.com>
Mon, 16 Dec 2019 12:20:47 +0000 (14:20 +0200)
Change-Id: I325381c73008f0bf7eb318a07f1904bfd6780aff
Signed-off-by: Irina <ib565x@intl.att.com>
44 files changed:
Automation/Tests/KeepAlive/__init__.robot [new file with mode: 0755]
Automation/Tests/KeepAlive/keep_alive_test.robot [new file with mode: 0644]
Automation/Tests/RSM_Resource_Status/resource_status_false_stop.robot
Automation/Tests/Resource/Keywords.robot
Automation/Tests/Resource/scripts_variables.robot
E2Manager/app/main.go
E2Manager/configuration/configuration.go
E2Manager/configuration/configuration_test.go
E2Manager/controllers/nodeb_controller_test.go
E2Manager/go.mod
E2Manager/go.sum
E2Manager/handlers/httpmsghandlers/delete_all_request_handler_test.go
E2Manager/handlers/httpmsghandlers/x2_reset_request_handler_test.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/endc_configuration_update_handler_test.go
E2Manager/handlers/rmrmsghandlers/setup_response_notification_handler_test.go
E2Manager/handlers/rmrmsghandlers/x2_reset_request_notification_handler_test.go
E2Manager/handlers/rmrmsghandlers/x2_reset_response_handler_test.go
E2Manager/handlers/rmrmsghandlers/x2enb_configuration_update_handler_test.go
E2Manager/managers/e2t_instances_manager.go
E2Manager/managers/e2t_instances_manager_test.go
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/ran_reconnection_manager_test.go
E2Manager/managers/ran_setup_manager_test.go
E2Manager/managers/ran_status_change_manager_test.go
E2Manager/mocks/e2t_instances_manager_mock.go
E2Manager/mocks/e2t_shutdown_manager_mock.go [new file with mode: 0644]
E2Manager/mocks/rmrMessengerMock.go
E2Manager/models/e2_term_init_payload.go
E2Manager/models/e2t_keep_alive_payload.go [new file with mode: 0644]
E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go
E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go
E2Manager/resources/configuration.yaml
E2Manager/rmrCgo/rmrCgoApi.go
E2Manager/rmrCgo/rmrCgoApi_test.go
E2Manager/rmrCgo/rmrCgoTypes.go
E2Manager/router.txt
E2Manager/services/rmrsender/rmr_sender.go
E2Manager/services/rmrsender/rmr_sender_test.go
E2Manager/services/rnib_data_service.go

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 45344ff..9864e3e 100644 (file)
@@ -51,6 +51,6 @@ prepare logs for tests
     Remove log files
     Save logs
 
-Verify RSM Resource Status Request Message Sent
+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
index 982fe57..92f2e83 100755 (executable)
@@ -93,13 +93,13 @@ Prepare Enviorment
      ${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      "e2esimu.${SUITE NAME}.log".replace(" ","-")
+     ${e2e_simu_log_filename}      Evaluate      "e2e_simu.${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} e2esimu > ${e2e_simu_log_filename}'
+     ${Save_e2e_simu_log}     Evaluate   'docker logs --since ${starting_timestamp} e2e_simu > ${e2e_simu_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}  
index e2998ae..517c047 100644 (file)
@@ -36,6 +36,8 @@ ${failed_to_retrieve_nodeb_message}     RAN name: test1 - Failed fetching RAN fr
 ${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
index 04b9047..f7674f3 100644 (file)
@@ -55,6 +55,8 @@ func main() {
        rmrSender := rmrsender.NewRmrSender(logger, rmrMessenger)
        ranSetupManager := managers.NewRanSetupManager(logger, rmrSender, rnibDataService)
        e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, logger)
+       e2tShutdownManager := managers.NewE2TShutdownManager(logger, rnibDataService, e2tInstancesManager)
+       e2tKeepAliveWorker := managers.NewE2TKeepAliveWorker(logger, rmrSender, e2tInstancesManager, e2tShutdownManager, config)
        rmrNotificationHandlerProvider := rmrmsghandlerprovider.NewNotificationHandlerProvider()
        rmrNotificationHandlerProvider.Init(logger, config, rnibDataService, rmrSender, ranSetupManager, e2tInstancesManager)
 
@@ -64,11 +66,10 @@ func main() {
        defer rmrMessenger.Close()
 
        go rmrReceiver.ListenAndHandle()
+       go e2tKeepAliveWorker.Execute()
 
        httpMsgHandlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(logger, rmrSender, config, rnibDataService, ranSetupManager, e2tInstancesManager)
        rootController := controllers.NewRootController(rnibDataService)
        nodebController := controllers.NewNodebController(logger, httpMsgHandlerProvider)
        _ = httpserver.Run(logger, config.Http.Port, rootController, nodebController)
-}
-
-
+}
\ No newline at end of file
index cfba4d2..2c93c09 100644 (file)
@@ -33,19 +33,21 @@ type Configuration struct {
                Port       int
                MaxMsgSize int
        }
-       NotificationResponseBuffer int
-       BigRedButtonTimeoutSec     int
-       MaxConnectionAttempts      int
-       MaxRnibConnectionAttempts  int
-       RnibRetryIntervalMs                int
+       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.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 {
@@ -62,28 +64,29 @@ func ParseConfiguration() *Configuration{
        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
 }
 
-func (c *Configuration)fillLoggingConfig(logConfig *viper.Viper) {
+func (c *Configuration) fillLoggingConfig(logConfig *viper.Viper) {
        if logConfig == nil {
                panic(fmt.Sprintf("#configuration.fillLoggingConfig - failed to fill logging configuration: The entry 'logging' not found\n"))
        }
        c.Logging.LogLevel = logConfig.GetString("logLevel")
 }
 
-func (c *Configuration)fillHttpConfig(httpConfig *viper.Viper) {
+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")
 }
 
-func (c *Configuration)fillRmrConfig(rmrConfig *viper.Viper) {
+func (c *Configuration) fillRmrConfig(rmrConfig *viper.Viper) {
        if rmrConfig == nil {
                panic(fmt.Sprintf("#configuration.fillRmrConfig - failed to fill RMR configuration: The entry 'rmr' not found\n"))
        }
        c.Rmr.Port = rmrConfig.GetInt("port")
        c.Rmr.MaxMsgSize = rmrConfig.GetInt("maxMsgSize")
 }
-
index 370e79e..a7c8cc5 100644 (file)
@@ -33,6 +33,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, 1500, config.KeepAliveResponseTimeoutMs)
+       assert.Equal(t, 500, config.KeepAliveDelayMs)
 }
 
 func TestParseConfigurationFileNotFoundFailure(t *testing.T) {
index 6847536..6282abd 100644 (file)
@@ -116,7 +116,7 @@ func TestX2SetupSuccess(t *testing.T) {
        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")
@@ -148,7 +148,7 @@ func TestEndcSetupSuccess(t *testing.T) {
        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")
@@ -421,7 +421,7 @@ func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
        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)
 
        writer := httptest.NewRecorder()
 
index e5d0b41..1fd1095 100644 (file)
@@ -1,9 +1,9 @@
 module e2mgr
 
 require (
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.27
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.27
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.27
+       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
index 9878d51..830b9df 100644 (file)
@@ -9,6 +9,8 @@ gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.26 h1:OQs1i2pNH85IxGiEs
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.26/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes=
 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.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/entities v1.0.24 h1:5ZnhEUygvN5PuTXS2bNt6KavT+Wtuh9Vra+EqZIvw+Q=
@@ -19,6 +21,8 @@ gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.26 h1:8buj1aJBkoHPFQP
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.26/go.mod h1:Fh23KkroYw5CRBh39WzZzxpKSkpQWL3scdzGnMngLo8=
 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.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/nodeb-rnib.git/reader v1.0.24 h1:Wwp36IoHwp091lXVCYLtFK6AMhoGAR4NYEgW1C42h6k=
@@ -29,6 +33,8 @@ gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.26 h1:zGKpxfqz7Ql4rpD53
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.26/go.mod h1:DCf5H9yy6kNTXsnUgXAPSuJt22ca4pYm0mo2ovJhLrA=
 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=
index c61f060..73a89c5 100644 (file)
@@ -135,7 +135,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)
-       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)
 
@@ -167,7 +167,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)
-       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)
 
@@ -196,7 +196,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)
-       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)
 
@@ -242,7 +242,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)
-       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)
 
@@ -288,7 +288,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)
-       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)
 
@@ -334,7 +334,7 @@ func TestHandleSendRmrFailedFlow(t *testing.T) {
 
        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)
 
index 53138bd..16def4c 100644 (file)
@@ -35,7 +35,7 @@ func TestHandleSuccessfulDefaultCause(t *testing.T) {
        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)
@@ -52,7 +52,7 @@ func TestHandleSuccessfulRequestedCause(t *testing.T) {
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
        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)
@@ -119,7 +119,7 @@ func TestHandleFailureRmrError(t *testing.T) {
        payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
        var xAction[]byte
        msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction)
-       rmrMessengerMock.On("SendMsg", msg).Return(&rmrCgo.MBuf{}, fmt.Errorf("rmr error"))
+       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)
index d9bca7c..f649da2 100644 (file)
@@ -117,7 +117,7 @@ func TestE2TermInitHandlerSuccessOneRan(t *testing.T) {
        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)
@@ -145,7 +145,7 @@ func TestE2TermInitHandlerSuccessTwoRans(t *testing.T) {
        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")
@@ -185,7 +185,7 @@ func TestE2TermInitHandlerSuccessThreeRansFirstRmrFailure(t *testing.T) {
        //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"))
 
        e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
        e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, "test1", "test2", "test3")
@@ -232,7 +232,7 @@ func TestE2TermInitHandlerSuccessThreeRansSecondNotFoundFailure(t *testing.T) {
        //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")
@@ -280,7 +280,7 @@ func TestE2TermInitHandlerSuccessThreeRansSecondRnibInternalErrorFailure(t *test
        //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")
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 c14b89d..aabd2fd 100644 (file)
@@ -49,9 +49,9 @@ func TestHandleEndcConfigUpdateSuccess(t *testing.T) {
        notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload, StartTime: time.Now(),
                TransactionId: *mBuf.XAction}
        var err error
-       rmrMessengerMock.On("SendMsg", mBuf).Return(&rmrCgo.MBuf{}, err)
+       rmrMessengerMock.On("SendMsg", mBuf, true).Return(&rmrCgo.MBuf{}, err)
        h.Handle(&notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf, true)
 }
 
 func TestHandleEndcConfigUpdateFailure(t *testing.T) {
@@ -66,7 +66,7 @@ func TestHandleEndcConfigUpdateFailure(t *testing.T) {
        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).Return(&rmrCgo.MBuf{}, fmt.Errorf("send failure"))
+       rmrMessengerMock.On("SendMsg", mBuf, true).Return(&rmrCgo.MBuf{}, fmt.Errorf("send failure"))
        h.Handle(&notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf, true)
 }
index 5e2eca2..db9abb4 100644 (file)
@@ -147,7 +147,7 @@ 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.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
@@ -212,7 +212,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)
-       testContext.rmrMessengerMock.AssertCalled(t, "SendMsg", tc.statusChangeMbuf)
+       testContext.rmrMessengerMock.AssertCalled(t, "SendMsg", tc.statusChangeMbuf, true)
 }
 
 func TestX2SetupFailureResponse(t *testing.T) {
@@ -258,7 +258,7 @@ func TestEndcSetupResponse(t *testing.T) {
 
        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) {
@@ -337,5 +337,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)
-       testContext.rmrMessengerMock.AssertCalled(t, "SendMsg", tc.statusChangeMbuf)
+       testContext.rmrMessengerMock.AssertCalled(t, "SendMsg", tc.statusChangeMbuf, true)
 }
index 41c78f1..8976bcd 100644 (file)
@@ -65,12 +65,12 @@ func TestHandleX2ResetRequestNotificationSuccess(t *testing.T) {
        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)
+       rmrMessengerMock.On("SendMsg", resetResponseMbuf, true).Return(&rmrCgo.MBuf{}, err)
        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)
-       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) {
index 7504f1d..92d1b8e 100644 (file)
@@ -72,9 +72,9 @@ func TestX2ResetResponseSuccess(t *testing.T) {
        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)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", ranRestartedMbuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", ranRestartedMbuf, true)
 }
 
 func TestX2ResetResponseSuccessEmptyIEs(t *testing.T) {
@@ -91,9 +91,9 @@ func TestX2ResetResponseSuccessEmptyIEs(t *testing.T) {
        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)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", ranRestartedMbuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", ranRestartedMbuf, true)
 }
 
 func TestX2ResetResponseShuttingDown(t *testing.T) {
index 2d55bd1..ab1e240 100644 (file)
@@ -48,9 +48,9 @@ func TestHandleX2EnbConfigUpdateSuccess(t *testing.T) {
        notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload,
                StartTime: time.Now(), TransactionId:xAction}
        var err error
-       rmrMessengerMock.On("SendMsg", mBuf).Return(&rmrCgo.MBuf{}, err)
+       rmrMessengerMock.On("SendMsg", mBuf, true).Return(&rmrCgo.MBuf{}, err)
        h.Handle(&notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf, true)
 }
 
 func TestHandleX2EnbConfigUpdateFailure(t *testing.T) {
@@ -65,7 +65,7 @@ func TestHandleX2EnbConfigUpdateFailure(t *testing.T) {
        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).Return(&rmrCgo.MBuf{}, fmt.Errorf("send failure"))
+       rmrMessengerMock.On("SendMsg", mBuf, true).Return(&rmrCgo.MBuf{}, fmt.Errorf("send failure"))
        h.Handle(&notificationRequest)
-       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg", mBuf, true)
 }
index 6800d2b..fb59f2f 100644 (file)
@@ -25,6 +25,7 @@ import (
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "math"
        "sync"
+       "time"
 )
 
 type E2TInstancesManager struct {
@@ -36,11 +37,13 @@ type E2TInstancesManager struct {
 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
+       ResetKeepAliveTimestamp(e2tAddress string) error
 }
 
 func NewE2TInstancesManager(rnibDataService services.RNibDataService, logger *logger.Logger) *E2TInstancesManager {
@@ -67,6 +70,36 @@ func (m *E2TInstancesManager) GetE2TInstance(e2tAddress string) (*entities.E2TIn
        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, err
+       }
+
+       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()
 
@@ -233,3 +266,32 @@ func (m *E2TInstancesManager) AssociateRan(ranName string, e2tAddress string) er
        m.logger.Infof("#E2TInstancesManager.AssociateRan - successfully associated RAN %s with E2T %s", ranName, e2tInstance.Address)
        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
+}
\ No newline at end of file
index 2c71cd3..006c5a2 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 managers
 
 import (
@@ -276,6 +292,73 @@ func TestSelectE2TInstancesSuccess(t *testing.T) {
        rnibWriterMock.AssertExpectations(t)
 }
 
+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)
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 86d9a7c..09b6914 100644 (file)
@@ -155,7 +155,7 @@ func TestConnectedRanExecuteSetupSuccess(t *testing.T) {
        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)
index d8bb0d6..3fe01d3 100644 (file)
@@ -65,7 +65,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)
-       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)
@@ -88,7 +88,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)
-       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)
@@ -113,7 +113,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)
-       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")
@@ -138,7 +138,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)
-       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")
@@ -165,7 +165,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)
-       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")
@@ -190,7 +190,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)
-       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")
index be8642e..ea9bfcd 100644 (file)
@@ -40,7 +40,7 @@ func TestMarshalSuccess(t *testing.T) {
 
        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)
index 3892d8e..0bbe764 100644 (file)
@@ -62,3 +62,15 @@ func (m *E2TInstancesManagerMock) GetE2TInstances() ([]*entities.E2TInstance, er
 
        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)
+
+}
\ No newline at end of file
diff --git a/E2Manager/mocks/e2t_shutdown_manager_mock.go b/E2Manager/mocks/e2t_shutdown_manager_mock.go
new file mode 100644 (file)
index 0000000..27b86aa
--- /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 E2TShutdownManagerMock struct {
+       mock.Mock
+}
+
+func (m *E2TShutdownManagerMock) Shutdown(e2tInstance *entities.E2TInstance) error {
+       args := m.Called(e2tInstance)
+       return args.Error(0)
+}
\ No newline at end of file
index 4a69181..c8d32f2 100644 (file)
@@ -32,8 +32,8 @@ func (m *RmrMessengerMock) Init(port string, maxMsgSize int, flags int, logger *
        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)
 }
 
index 0aa1521..e533582 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 models
 
 type E2TermInitPayload struct {
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
index 5f72a1f..99a3c32 100644 (file)
@@ -84,6 +84,7 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config
        x2ResetResponseHandler := rmrmsghandlers.NewX2ResetResponseHandler(logger, rnibDataService, ranStatusChangeManager, x2ResetResponseExtractor)
        x2ResetRequestNotificationHandler := rmrmsghandlers.NewX2ResetRequestNotificationHandler(logger, rnibDataService, ranStatusChangeManager, rmrSender)
        e2TermInitNotificationHandler := rmrmsghandlers.NewE2TermInitNotificationHandler(logger, ranReconnectionManager, rnibDataService, e2tInstancesManager)
+       e2TKeepAliveResponseHandler := rmrmsghandlers.NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManager)
 
        provider.Register(rmrCgo.RIC_X2_SETUP_RESP, x2SetupResponseHandler)
        provider.Register(rmrCgo.RIC_X2_SETUP_FAILURE, x2SetupFailureResponseHandler)
@@ -96,4 +97,5 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config
        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 97db37c..1874e71 100644 (file)
@@ -103,6 +103,7 @@ func TestGetNotificationHandlerSuccess(t *testing.T) {
                {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, e2tInstancesManager)},
+               {rmrCgo.E2_TERM_KEEP_ALIVE_RESP, rmrmsghandlers.NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManager)},
                {rmrCgo.RIC_X2_RESET_RESP, rmrmsghandlers.NewX2ResetResponseHandler(logger, rnibDataService, ranStatusChangeManager, converters.NewX2ResetResponseExtractor(logger))},
                {rmrCgo.RIC_X2_RESET, rmrmsghandlers.NewX2ResetRequestNotificationHandler(logger, rnibDataService, ranStatusChangeManager, rmrSender)},
        }
index 0b73b60..27f55d1 100644 (file)
@@ -10,3 +10,5 @@ bigRedButtonTimeoutSec: 5
 maxConnectionAttempts: 3
 maxRnibConnectionAttempts: 3
 rnibRetryIntervalMs: 10
+keepAliveResponseTimeoutMs: 1500
+keepAliveDelayMs: 500
index 4a9f8c4..7f68684 100644 (file)
@@ -54,7 +54,7 @@ func (*Context) Init(port string, maxMsgSize int, flags int, logger *logger.Logg
        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)
@@ -65,21 +65,21 @@ func (ctx *Context) SendMsg(msg *MBuf) (*MBuf, error) {
                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
-       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)
        }
 
-       ctx.Logger.Debugf("#rmrCgoApi.SendMsg - The message has been sent successfully ")
        return convertToMBuf(ctx.Logger, currCMBuf), nil
 }
 
@@ -99,9 +99,13 @@ func (ctx *Context) RecvMsg() (*MBuf, error) {
        }
 
        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)
+
+       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
 }
 
index fd1e7b2..cfcaa4b 100644 (file)
@@ -72,7 +72,7 @@ func TestSendRecvMsgSuccess(t *testing.T) {
        }
        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)
+       result, err := msgr.SendMsg(msg, true)
 
        assert.Nil(t, err)
        assert.NotNil(t, result)
@@ -94,7 +94,7 @@ func TestSendMsgRmrInvalidMsgNumError(t *testing.T) {
 
        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)
+       result, err := msgr.SendMsg(msg, true)
 
        assert.NotNil(t, err)
        assert.Nil(t, result)
@@ -112,7 +112,7 @@ func TestSendMsgRmrInvalidPortError(t *testing.T) {
 
        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)
+       result, err := msgr.SendMsg(msg, true)
 
        assert.NotNil(t, err)
        assert.Nil(t, result)
index 1fe6032..f5c8d69 100644 (file)
@@ -71,6 +71,8 @@ const (
        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 (
@@ -136,7 +138,7 @@ type Context struct {
 
 type RmrMessenger interface {
        Init(port string, maxMsgSize int, flags int, logger *logger.Logger) RmrMessenger
-       SendMsg(msg *MBuf) (*MBuf, error)
+       SendMsg(msg *MBuf, printLogs bool) (*MBuf, error)
        RecvMsg() (*MBuf, error)
        IsReady() bool
        Close()
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|1101|10.0.2.15:38000
 newrt|end
index ca8ce36..00ca7f9 100644 (file)
@@ -38,7 +38,7 @@ func NewRmrSender(logger *logger.Logger, messenger rmrCgo.RmrMessenger) *RmrSend
 func (r *RmrSender) Send(rmrMessage *models.RmrMessage) error {
        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)
@@ -48,3 +48,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
 }
+
+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 c4d0c38..0c6dc28 100644 (file)
@@ -52,13 +52,13 @@ func TestRmrSenderSendSuccess(t *testing.T) {
        payload := []byte("some payload")
        var xAction []byte
        mbuf := rmrCgo.NewMBuf(123, len(payload), ranName, &payload, &xAction)
-       rmrMessengerMock.On("SendMsg", mbuf).Return(&rmrCgo.MBuf{}, nil)
+       rmrMessengerMock.On("SendMsg", mbuf, true).Return(&rmrCgo.MBuf{}, nil)
        rmrMsg := models.NewRmrMessage(123, ranName, payload, xAction)
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrSender := NewRmrSender(logger, rmrMessenger)
        err := rmrSender.Send(rmrMsg)
        assert.Nil(t, err)
-       rmrMessengerMock.AssertCalled(t, "SendMsg",mbuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg",mbuf, true)
 
 }
 
@@ -69,12 +69,12 @@ func TestRmrSenderSendFailure(t *testing.T) {
        payload := []byte("some payload")
        var xAction []byte
        mbuf := rmrCgo.NewMBuf(123, len(payload), ranName, &payload, &xAction)
-       rmrMessengerMock.On("SendMsg", mbuf).Return(mbuf, fmt.Errorf("rmr send failure"))
+       rmrMessengerMock.On("SendMsg", mbuf, true).Return(mbuf, fmt.Errorf("rmr send failure"))
        rmrMsg := models.NewRmrMessage(123, ranName, payload, xAction)
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
        rmrSender := NewRmrSender(logger, rmrMessenger)
        err := rmrSender.Send(rmrMsg)
-       rmrMessengerMock.AssertCalled(t, "SendMsg",mbuf)
+       rmrMessengerMock.AssertCalled(t, "SendMsg",mbuf, true)
        assert.NotNil(t, err)
 }
 
index bc6b8ef..63ac443 100644 (file)
@@ -40,6 +40,10 @@ type RNibDataService interface {
        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 {
@@ -120,7 +124,6 @@ func (w *rNibDataService) GetListNodebIds() ([]*entities.NbIdentity, error) {
 }
 
 func (w *rNibDataService) GetE2TInstance(address string) (*entities.E2TInstance, error) {
-
        var e2tInstance *entities.E2TInstance = nil
 
        err := w.retry("GetE2TInstance", func() (err error) {
@@ -135,6 +138,17 @@ func (w *rNibDataService) GetE2TInstance(address string) (*entities.E2TInstance,
        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
@@ -147,6 +161,18 @@ func (w *rNibDataService) GetE2TInstances(addresses []string) ([]*entities.E2TIn
        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
@@ -163,8 +189,26 @@ func (w *rNibDataService) GetE2TAddresses() ([]string, error) {
        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