[RICPLT-1703] - Reset Request + rmr_service refactoring (disabled) 23/723/1
authorrh362j <ronen.hasid@intl.att.com>
Thu, 15 Aug 2019 12:37:32 +0000 (15:37 +0300)
committerrh362j <ronen.hasid@intl.att.com>
Thu, 15 Aug 2019 12:40:02 +0000 (15:40 +0300)
Signed-off-by: rh362j <ronen.hasid@intl.att.com>
Change-Id: I939041928c0fa18d2682262ce920710b99cf0539

31 files changed:
E2Manager/asn1codec/Makefile
E2Manager/asn1codec/inc/configuration_update_wrapper.h
E2Manager/asn1codec/inc/x2reset_request_wrapper.h [new file with mode: 0644]
E2Manager/asn1codec/inc/x2setup_request_wrapper.h
E2Manager/asn1codec/src/configuration_update_wrapper.c
E2Manager/asn1codec/src/tests/configuration_update_wrapper_test.c
E2Manager/asn1codec/src/tests/x2reset_request_wrapper_test.c [new file with mode: 0644]
E2Manager/asn1codec/src/tests/x2setup_request_wrapper_test.c
E2Manager/asn1codec/src/x2reset_request_wrapper.c [new file with mode: 0644]
E2Manager/asn1codec/src/x2setup_request_wrapper.c
E2Manager/controllers/controller.go
E2Manager/controllers/controller_test.go
E2Manager/controllers/nodeb_controller_test.go
E2Manager/e2managererrors/request_validation_error.go [new file with mode: 0644]
E2Manager/e2managererrors/resource_not_found.go [new file with mode: 0644]
E2Manager/e2managererrors/rmr_error.go [new file with mode: 0644]
E2Manager/e2managererrors/wrong_state_error.go [new file with mode: 0644]
E2Manager/handlers/delete_all_request_handler.go
E2Manager/handlers/request_handler.go
E2Manager/handlers/x2_reset_request_handler.go [new file with mode: 0644]
E2Manager/main/http_server.go
E2Manager/mocks/rnibReaderMock.go
E2Manager/models/reset_request.go [new file with mode: 0644]
E2Manager/providers/incoming_request_handler_provider.go
E2Manager/providers/incoming_request_handler_provider_test.go
E2Manager/rmrCgo/rmrCgoTypes.go
E2Manager/router.txt
E2Manager/services/receivers/rmr_service_receiver.go [new file with mode: 0644]
E2Manager/services/receivers/rmr_service_receiver_test.go [new file with mode: 0644]
E2Manager/services/rmr_service.go
E2Manager/services/rmr_service_test.go

index b4229a7..59c304b 100644 (file)
@@ -19,14 +19,16 @@ CFLAGS=-Wall -Wpedantic -std=c11 -Og  -I./inc -I./src -I./e2ap_engine -DASN_DISA
 export CFLAGS
 OBJDIR=lib
 LIB=$(OBJDIR)/libe2ap_codec.a
-LIBSRC=configuration_update_wrapper.c x2setup_request_wrapper.c asn1codec_utils.c
+LIBSRC=configuration_update_wrapper.c x2setup_request_wrapper.c x2reset_request_wrapper.c asn1codec_utils.c
 LIBOBJ=$(addprefix $(OBJDIR)/,$(LIBSRC:.c=.o))
 TESTX2SETUPREQUEST=tests/x2setup_request_wrapper_test
 TESTCONFUPDATE=tests/configuration_update_wrapper_test
+TESTX2RESETREQUEST=tests/x2reset_request_wrapper_test
+
 
 .PHONY: all clean e2ap_engine
 
-all: $(LIB) $(TESTX2SETUPREQUEST) $(TESTCONFUPDATE)
+all: $(LIB) $(TESTX2SETUPREQUEST) $(TESTCONFUPDATE)  $(TESTX2RESETREQUEST)
 
 
 e2ap_engine/libasncodec.a:
@@ -47,6 +49,12 @@ $(TESTCONFUPDATE): % : $(LIB) src/%.c
        mkdir -p $(dir $@)
        $(CC) $(CFLAGS) src/$@.c -o $@ $(LIB)  e2ap_engine/libasncodec.a
 
+$(TESTX2RESETREQUEST): % : $(LIB) src/%.c 
+       mkdir -p $(dir $@)
+       $(CC) $(CFLAGS) src/$@.c -o $@ $(LIB)  e2ap_engine/libasncodec.a
+
+
+
 clean:
        rm -rf $(OBJDIR) tests 
 clobber:
index 81608b3..13e3c07 100644 (file)
  *
  */
 
-/*******************************************************************************
- *
- *   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.
- *
- *******************************************************************************/
-
-// Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries
 
 #include <stddef.h>
 #include <stdbool.h>
diff --git a/E2Manager/asn1codec/inc/x2reset_request_wrapper.h b/E2Manager/asn1codec/inc/x2reset_request_wrapper.h
new file mode 100644 (file)
index 0000000..d91750e
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <asn1codec_utils.h>
+
+#ifndef INC_X2RESET_REQUEST_WRAPPER_H
+#define INC_X2RESET_REQUEST_WRAPPER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+bool
+build_pack_x2reset_request(enum Cause_PR cause_group, int cause_value, size_t* packed_buf_size, unsigned char* packed_buf,size_t err_buf_size, char* err_buf);
+bool
+build_pack_x2reset_request_aux(enum Cause_PR cause_group, int cause_value, size_t* packed_buf_size, unsigned char* packed_buf,size_t err_buf_size, char* err_buf,enum asn_transfer_syntax syntax);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INC_RESET_REQUEST_WRAPPER_H */
index 8af5fb8..6a704a5 100644 (file)
  *
  */
 
-/*******************************************************************************
- *
- *   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.
- *
- *******************************************************************************/
-
-// Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries
 
 #include <stddef.h>
 #include <stdbool.h>
index cea1aa9..a225206 100644 (file)
  *
  */
 
-/*******************************************************************************
- *
- *   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.
- *
- *******************************************************************************/
-
-// Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries
-
-// Platform Includes: Platform specific classes, functions, and libraries
-
-// Local Includes: Application specific classes, functions, and libraries
-
 #include <string.h>
 #include <errno.h>
 #undef NDEBUG
index f45479e..269d931 100644 (file)
  *
  */
 
-//
-// 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.
-//
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/E2Manager/asn1codec/src/tests/x2reset_request_wrapper_test.c b/E2Manager/asn1codec/src/tests/x2reset_request_wrapper_test.c
new file mode 100644 (file)
index 0000000..b6b1b99
--- /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.
+ *
+ */
+
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <x2reset_request_wrapper.h>
+
+void test_build_pack_x2reset_request();
+void test_unpack(void);
+
+int
+main(int argc, char* argv[])
+{
+    test_build_pack_x2reset_request();
+    exit(0);
+}
+
+void test_build_pack_x2reset_request(){
+    size_t error_buf_size = 8192;
+    size_t packed_buf_size = 4096;
+    unsigned char responseDataBuf[packed_buf_size];
+    char responseErrorBuf[error_buf_size];
+    bool result;
+    E2AP_PDU_t *pdu;
+    /**********************************************************************************/
+
+    packed_buf_size = 4096;
+    result = build_pack_x2reset_request(Cause_PR_radioNetwork,CauseRadioNetwork_time_critical_handover,
+                   &packed_buf_size, responseDataBuf, error_buf_size, responseErrorBuf);
+    if (!result) {
+        printf("#%s failed. Packing error %s\n", __func__, responseErrorBuf);
+        return;
+    }
+    printf("#%s packed size:%lu\nPayload:\n", __func__, packed_buf_size);
+    for (size_t i = 0; i < packed_buf_size; ++i)
+        printf("%02x",responseDataBuf[i]);
+    printf("\n");
+
+    pdu =calloc(1, sizeof(E2AP_PDU_t));
+    if (!unpack_pdu_aux(pdu, packed_buf_size, responseDataBuf,error_buf_size, responseErrorBuf,ATS_ALIGNED_BASIC_PER)){
+       printf("#%s failed. Packing error %s\n", __func__, responseErrorBuf);
+    }
+    responseErrorBuf[0] = 0;
+    asn1_pdu_printer(pdu, sizeof(responseErrorBuf), responseErrorBuf);
+    printf("#%s: %s\n", __func__, responseErrorBuf);
+
+}
+
index ca647c0..6278bc7 100644 (file)
  *
  */
 
-//
-// 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.
-//
+
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/E2Manager/asn1codec/src/x2reset_request_wrapper.c b/E2Manager/asn1codec/src/x2reset_request_wrapper.c
new file mode 100644 (file)
index 0000000..25108f3
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <string.h>
+#include <errno.h>
+#undef NDEBUG
+#include <assert.h>
+#include <ProcedureCode.h>
+#include <InitiatingMessage.h>
+#include <ProtocolIE-ID.h>
+#include <x2reset_request_wrapper.h>
+
+/*
+ * Build and pack a reset request.
+ * Abort the process on allocation failure.
+ *  packed_buf_size - in: size of packed_buf; out: number of chars used.
+ */
+
+bool
+build_pack_x2reset_request(enum Cause_PR cause_group, int cause_value, size_t* packed_buf_size, unsigned char* packed_buf,size_t err_buf_size, char* err_buf)
+{
+       return build_pack_x2reset_request_aux(cause_group, cause_value, packed_buf_size, packed_buf,err_buf_size,err_buf,ATS_ALIGNED_BASIC_PER);
+
+}
+
+bool
+build_pack_x2reset_request_aux(enum Cause_PR cause_group, int cause_value, size_t* packed_buf_size, unsigned char* packed_buf,size_t err_buf_size, char* err_buf,enum asn_transfer_syntax syntax)
+{
+       bool rc = true;
+       E2AP_PDU_t *pdu = calloc(1, sizeof(E2AP_PDU_t));
+       InitiatingMessage_t *initiatingMessage = calloc(1, sizeof(InitiatingMessage_t));
+       ResetRequest_t   *resetRequest;
+
+    assert(pdu != 0);
+    assert(initiatingMessage != 0);
+
+
+    pdu->present = E2AP_PDU_PR_initiatingMessage;
+    pdu->choice.initiatingMessage = initiatingMessage;
+
+    initiatingMessage->procedureCode = ProcedureCode_id_reset;
+    initiatingMessage->criticality = Criticality_reject;
+    initiatingMessage->value.present = InitiatingMessage__value_PR_ResetRequest;
+    resetRequest = &initiatingMessage->value.choice.ResetRequest;
+
+    ResetRequest_IEs_t *cause_ie = calloc(1, sizeof(ResetRequest_IEs_t));
+    assert(cause_ie != 0);
+    ASN_SEQUENCE_ADD(&resetRequest->protocolIEs, cause_ie);
+
+    cause_ie->id = ProtocolIE_ID_id_Cause;
+    cause_ie->criticality = Criticality_ignore;
+    cause_ie->value.present = ResetRequest_IEs__value_PR_Cause;
+    Cause_t *cause = &cause_ie->value.choice.Cause;
+    cause->present = cause_group;
+    switch (cause->present) {
+    case Cause_PR_radioNetwork:
+       cause->choice.radioNetwork = cause_value;
+       break;
+    case Cause_PR_transport:
+       cause->choice.transport = cause_value;
+       break;
+    case Cause_PR_protocol:
+       cause->choice.protocol = cause_value;
+       break;
+    case Cause_PR_misc:
+       cause->choice.misc = cause_value;
+       break;
+    default:
+       cause->choice.misc = CauseMisc_om_intervention;
+       break;
+    }
+
+    rc = pack_pdu_aux(pdu, packed_buf_size, packed_buf,err_buf_size, err_buf,syntax);
+
+    ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
+    return rc;
+}
+
index b028e01..a159f98 100644 (file)
  *
  */
 
-/*******************************************************************************
- *
- *   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.
- *
- *******************************************************************************/
-
-// Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries
-
-// Platform Includes: Platform specific classes, functions, and libraries
-
-// Local Includes: Application specific classes, functions, and libraries
 #include <string.h>
 #include <errno.h>
 #undef NDEBUG
index 07b3ec2..a0c7a15 100644 (file)
@@ -24,22 +24,28 @@ import (
        "e2mgr/models"
        "e2mgr/providers"
        "e2mgr/rNibWriter"
+       "e2mgr/services"
        "encoding/json"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/julienschmidt/httprouter"
+       "io"
        "net/http"
+       "time"
 )
 
+const (
+       ParamRanName = "ranName"
+)
 type Controller struct {
        logger         *logger.Logger
        handlerProvider *providers.IncomingRequestHandlerProvider
        rmrResponseChannel chan<- *models.NotificationResponse
 }
 
-func NewController(logger *logger.Logger, rNibReaderProvider func() reader.RNibReader, rNibWriterProvider func() rNibWriter.RNibWriter,
+func NewController(logger *logger.Logger, rmrService *services.RmrService, rNibReaderProvider func() reader.RNibReader, rNibWriterProvider func() rNibWriter.RNibWriter,
        config *configuration.Configuration, rmrResponseChannel chan<- *models.NotificationResponse) *Controller {
 
-       provider := providers.NewIncomingRequestHandlerProvider(logger, config, rNibWriterProvider, rNibReaderProvider)
+       provider := providers.NewIncomingRequestHandlerProvider(logger, rmrService, config, rNibWriterProvider, rNibReaderProvider)
        return &Controller{
                logger: logger,
                handlerProvider: provider,
@@ -52,9 +58,32 @@ func (c *Controller)ShutdownHandler(writer http.ResponseWriter, r *http.Request,
        c.handleRequest(writer, &r.Header, providers.ShutdownRequest,nil, false, http.StatusNoContent)
 }
 
-//TODO create struct to input parameters
+func (c *Controller) X2ResetHandler(writer http.ResponseWriter, r *http.Request, params httprouter.Params){
+       startTime := time.Now()
+       request:= models.ResetRequest{}
+       ranName:= params.ByName(ParamRanName)
+       if !c.extractJsonBody(r.Body, &request, writer){
+               return
+       }
+       request.RanName = ranName
+       request.StartTime = startTime
+       c.handleRequest(writer, &r.Header, providers.ResetRequest, request, false, http.StatusNoContent)
+}
+
+func (c *Controller) extractJsonBody(body io.Reader, request models.Request, writer http.ResponseWriter) bool{
+       decoder := json.NewDecoder(body)
+       if err:= decoder.Decode(request); err != nil {
+               if err != nil {
+                       c.logger.Errorf("[Client -> E2 Manager] #controller.extractJsonBody - unable to extract json body - error: %s", err)
+                       c.handleErrorResponse(e2managererrors.NewRequestValidationError(), writer)
+                       return false
+               }
+       }
+       return true
+}
+
 func (c *Controller) handleRequest(writer http.ResponseWriter, header *http.Header, requestName providers.IncomingRequest,
-       request *models.Request, validateHeader bool, httpStatusResponse int) {
+       request models.Request, validateHeader bool, httpStatusResponse int) {
 
        c.logger.Infof("[Client -> E2 Manager] #controller.handleRequest - request: %v", requestName) //TODO print request if exist
 
@@ -113,6 +142,19 @@ func (c *Controller) handleErrorResponse(err error, writer http.ResponseWriter){
                        e2Error, _ := err.(*e2managererrors.HeaderValidationError)
                        errorResponseDetails = models.ErrorResponse{Code: e2Error.Err.Code, Message: e2Error.Err.Message}
                        httpError = http.StatusUnsupportedMediaType
+               case *e2managererrors.WrongStateError:
+                       e2Error, _ := err.(*e2managererrors.WrongStateError)
+                       errorResponseDetails = models.ErrorResponse{Code: e2Error.Err.Code, Message: e2Error.Err.Message}
+                       httpError = http.StatusBadRequest
+               case *e2managererrors.RequestValidationError:
+                       e2Error, _ := err.(*e2managererrors.RequestValidationError)
+                       errorResponseDetails = models.ErrorResponse{Code: e2Error.Err.Code, Message: e2Error.Err.Message}
+                       httpError = http.StatusBadRequest
+               case *e2managererrors.RmrError:
+                       e2Error, _ := err.(*e2managererrors.RmrError)
+                       errorResponseDetails = models.ErrorResponse{Code: e2Error.Err.Code, Message: e2Error.Err.Message}
+                       httpError = http.StatusInternalServerError
+
                default:
                        e2Error, _ := err.(*e2managererrors.InternalError)
                        errorResponseDetails = models.ErrorResponse{Code: e2Error.Err.Code, Message: e2Error.Err.Message}
index e753bcf..6b9e7ae 100644 (file)
@@ -42,6 +42,7 @@ func TestShutdownHandlerRnibError(t *testing.T) {
        log := initLog(t)
        config := configuration.ParseConfiguration()
 
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
        readerMock := &mocks.RnibReaderMock{}
        readerProvider := func() reader.RNibReader {
                return readerMock
@@ -57,7 +58,7 @@ func TestShutdownHandlerRnibError(t *testing.T) {
        readerMock.On("GetListNodebIds").Return(nbIdentityList, rnibErr)
 
        writer := httptest.NewRecorder()
-       controller := NewController(log, readerProvider, writerProvider, config, messageChannel)
+       controller := NewController(log, getRmrService(rmrMessengerMock, log), readerProvider, writerProvider, config, messageChannel)
        controller.ShutdownHandler(writer, tests.GetHttpRequest(), nil)
 
        var errorResponse = parseJsonRequest(t, writer.Body)
@@ -70,6 +71,7 @@ func TestHeaderValidationFailed(t *testing.T) {
        log := initLog(t)
        config := configuration.ParseConfiguration()
 
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
        readerMock := &mocks.RnibReaderMock{}
        readerProvider := func() reader.RNibReader {
                return readerMock
@@ -82,7 +84,7 @@ func TestHeaderValidationFailed(t *testing.T) {
 
        writer := httptest.NewRecorder()
 
-       controller := NewController(log, readerProvider, writerProvider, config, messageChannel)
+       controller := NewController(log, getRmrService(rmrMessengerMock, log), readerProvider, writerProvider, config, messageChannel)
 
        header := &http.Header{}
 
@@ -99,6 +101,7 @@ func TestHeaderValidationFailed(t *testing.T) {
 func TestShutdownStatusNoContent(t *testing.T){
        log := initLog(t)
 
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
        readerMock := &mocks.RnibReaderMock{}
        readerProvider := func() reader.RNibReader {
                return readerMock
@@ -115,7 +118,7 @@ func TestShutdownStatusNoContent(t *testing.T){
        readerMock.On("GetListNodebIds").Return(nbIdentityList, rnibError)
 
        writer := httptest.NewRecorder()
-       controller := NewController(log, readerProvider, writerProvider, config, messageChannel)
+       controller := NewController(log, getRmrService(rmrMessengerMock, log), readerProvider, writerProvider, config, messageChannel)
        controller.ShutdownHandler(writer, tests.GetHttpRequest(), nil)
 
        assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
@@ -125,6 +128,7 @@ func TestHandleInternalError(t *testing.T) {
        log := initLog(t)
        config := configuration.ParseConfiguration()
 
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
        readerMock := &mocks.RnibReaderMock{}
        readerProvider := func() reader.RNibReader {
                return readerMock
@@ -136,7 +140,7 @@ func TestHandleInternalError(t *testing.T) {
        var messageChannel chan<- *models.NotificationResponse
 
        writer := httptest.NewRecorder()
-       controller := NewController(log, readerProvider, writerProvider, config, messageChannel)
+       controller := NewController(log, getRmrService(rmrMessengerMock, log), readerProvider, writerProvider, config, messageChannel)
        err := e2managererrors.NewInternalError()
 
        controller.handleErrorResponse(err, writer)
@@ -151,6 +155,7 @@ func TestHandleCommandAlreadyInProgressError(t *testing.T) {
        log := initLog(t)
        config := configuration.ParseConfiguration()
 
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
        readerMock := &mocks.RnibReaderMock{}
        readerProvider := func() reader.RNibReader {
                return readerMock
@@ -161,7 +166,7 @@ func TestHandleCommandAlreadyInProgressError(t *testing.T) {
        }
        var messageChannel chan<- *models.NotificationResponse
        writer := httptest.NewRecorder()
-       controller := NewController(log, readerProvider, writerProvider, config, messageChannel)
+       controller := NewController(log, getRmrService(rmrMessengerMock, log), readerProvider, writerProvider, config, messageChannel)
        err := e2managererrors.NewCommandAlreadyInProgressError()
 
        controller.handleErrorResponse(err, writer)
@@ -175,6 +180,7 @@ func TestHandleCommandAlreadyInProgressError(t *testing.T) {
 func TestValidateHeaders(t *testing.T){
        log := initLog(t)
 
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
        readerMock := &mocks.RnibReaderMock{}
        readerProvider := func() reader.RNibReader {
                return readerMock
@@ -186,7 +192,7 @@ func TestValidateHeaders(t *testing.T){
        config := configuration.ParseConfiguration()
        var messageChannel chan<- *models.NotificationResponse
 
-       controller := NewController(log, readerProvider, writerProvider, config, messageChannel)
+       controller := NewController(log, getRmrService(rmrMessengerMock, log), readerProvider, writerProvider, config, messageChannel)
 
        header := http.Header{}
        header.Set("Content-Type", "application/json")
index 9497ff8..f6a9e54 100644 (file)
@@ -19,12 +19,12 @@ package controllers
 
 import (
        "e2mgr/logger"
-       "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/models"
        "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
+       "e2mgr/sessions"
        "e2mgr/tests"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
@@ -143,19 +143,12 @@ func handleRequest(writer *httptest.ResponseRecorder, log *logger.Logger, rmrMes
 
 func getRmrService(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *services.RmrService {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
-       rnibReaderProvider := func() reader.RNibReader {
-               return &mocks.RnibReaderMock{}
-       }
-
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return &mocks.RnibWriterMock{}
-       }
-       nManager := managers.NewNotificationManager(rnibReaderProvider, rnibWriterProvider)
-       rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
        messageChannel := make(chan *models.NotificationResponse)
-       return services.NewRmrService(services.NewRmrConfig(tests.Port, tests.MaxMsgSize, tests.Flags, log), rmrMessenger, E2Sessions, nManager, messageChannel)
+       rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
+       return services.NewRmrService(services.NewRmrConfig(tests.Port, tests.MaxMsgSize, tests.Flags, log), rmrMessenger,  make(sessions.E2Sessions), messageChannel)
 }
 
+
 func executeGetNodeb(logger *logger.Logger, writer *httptest.ResponseRecorder, rnibReaderProvider func() reader.RNibReader) {
        req, _ := http.NewRequest("GET", "/nodeb", nil)
 
diff --git a/E2Manager/e2managererrors/request_validation_error.go b/E2Manager/e2managererrors/request_validation_error.go
new file mode 100644 (file)
index 0000000..2029aa7
--- /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 RequestValidationError struct {
+       Err BaseError
+}
+
+func NewRequestValidationError() *RequestValidationError {
+       return &RequestValidationError{
+               BaseError{
+                       Code:    402,
+                       Message: "Validation error",
+               },
+       }
+}
+
+func (e *RequestValidationError) Error() string {
+       return e.Err.Message
+}
diff --git a/E2Manager/e2managererrors/resource_not_found.go b/E2Manager/e2managererrors/resource_not_found.go
new file mode 100644 (file)
index 0000000..a69f73e
--- /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 ResourceNotFoundError struct {
+       Err BaseError
+}
+
+func NewResourceNotFoundError() *ResourceNotFoundError {
+       return &ResourceNotFoundError{
+               BaseError{
+                       Code:    404,
+                       Message: "Resource not found",
+               },
+       }
+}
+
+func (e *ResourceNotFoundError) Error() string {
+       return e.Err.Message
+}
diff --git a/E2Manager/e2managererrors/rmr_error.go b/E2Manager/e2managererrors/rmr_error.go
new file mode 100644 (file)
index 0000000..fca2a8a
--- /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 RmrError struct {
+       Err BaseError
+}
+
+func NewRmrError() *RmrError {
+       return &RmrError{
+               BaseError{
+                       Code:    502,
+                       Message: "RMR error",
+               },
+       }
+}
+
+func (e *RmrError) Error() string {
+       return e.Err.Message
+}
diff --git a/E2Manager/e2managererrors/wrong_state_error.go b/E2Manager/e2managererrors/wrong_state_error.go
new file mode 100644 (file)
index 0000000..be7b59a
--- /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 WrongStateError struct {
+       Err BaseError
+}
+
+func NewWrongStateError() *RnibDbError {
+       return &RnibDbError{
+               BaseError{
+                       Code:    403,
+                       Message: "RAN in wrong state",
+               },
+       }
+}
+
+func (e *WrongStateError) Error() string {
+       return e.Err.Message
+}
index 3a9958f..95f83a2 100644 (file)
@@ -46,7 +46,7 @@ func NewDeleteAllRequestHandler(config *configuration.Configuration, writerProvi
        }
 }
 
-func (handler *DeleteAllRequestHandler) Handle(logger *logger.Logger, request *models.Request, rmrResponseChannel chan<- *models.NotificationResponse) error {
+func (handler *DeleteAllRequestHandler) Handle(logger *logger.Logger, request models.Request, rmrResponseChannel chan<- *models.NotificationResponse) error {
 
        err, continueFlow := handler.updateNodebStates(logger, false)
        if err != nil {
index 4b93a61..5e343fe 100644 (file)
@@ -23,5 +23,5 @@ import (
 )
 
 type RequestHandler interface {
-       Handle(logger *logger.Logger, request *models.Request, rmrResponseChannel chan<- *models.NotificationResponse) error
+       Handle(logger *logger.Logger, request models.Request, rmrResponseChannel chan<- *models.NotificationResponse) error
 }
diff --git a/E2Manager/handlers/x2_reset_request_handler.go b/E2Manager/handlers/x2_reset_request_handler.go
new file mode 100644 (file)
index 0000000..e666513
--- /dev/null
@@ -0,0 +1,183 @@
+//
+// 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 handlers
+// #cgo CFLAGS: -I../asn1codec/inc/  -I../asn1codec/e2ap_engine/
+// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec
+// #include <x2reset_request_wrapper.h>
+import "C"
+import (
+       "e2mgr/configuration"
+       "e2mgr/e2managererrors"
+       "e2mgr/logger"
+       "e2mgr/rNibWriter"
+       "e2mgr/rmrCgo"
+       "e2mgr/services"
+       "e2mgr/sessions"
+       "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"
+       "unsafe"
+
+       "e2mgr/models"
+)
+
+type X2ResetRequestHandler struct {
+       readerProvider func() reader.RNibReader
+       writerProvider func() rNibWriter.RNibWriter
+       rmrService *services.RmrService
+       config         *configuration.Configuration
+}
+
+/*
+
+C
+*/
+
+type cause struct {
+causeGroup uint32
+cause      int
+}
+
+var knownCauses = map[string] cause  {
+"misc:control-processing-overload": {causeGroup:C.Cause_PR_misc,  cause: C.CauseMisc_control_processing_overload},
+"misc:hardware-failure": {causeGroup:C.Cause_PR_misc,  cause: C.CauseMisc_hardware_failure},
+"misc:om-intervention": {causeGroup:C.Cause_PR_misc,  cause: C.CauseMisc_om_intervention},
+"misc:not-enough-user-plane-processing-resources": {causeGroup:C.Cause_PR_misc,  cause: C.CauseMisc_not_enough_user_plane_processing_resources},
+"misc:unspecified": {causeGroup:C.Cause_PR_misc,  cause: C.CauseMisc_unspecified},
+
+"protocol:transfer-syntax-error": {causeGroup:C.Cause_PR_protocol,  cause: C.CauseProtocol_transfer_syntax_error},
+"protocol:abstract-syntax-error-reject": {causeGroup:C.Cause_PR_protocol,  cause: C.CauseProtocol_abstract_syntax_error_reject},
+"protocol:abstract-syntax-error-ignore-and-notify": {causeGroup:C.Cause_PR_protocol,  cause: C.CauseProtocol_abstract_syntax_error_ignore_and_notify},
+"protocol:message-not-compatible-with-receiver-state": {causeGroup:C.Cause_PR_protocol,  cause: C.CauseProtocol_message_not_compatible_with_receiver_state},
+"protocol:semantic-error": {causeGroup:C.Cause_PR_protocol,  cause: C.CauseProtocol_semantic_error},
+"protocol:unspecified": {causeGroup:C.Cause_PR_protocol,  cause: C.CauseProtocol_unspecified},
+"protocol:abstract-syntax-error-falsely-constructed-message": {causeGroup:C.Cause_PR_protocol,  cause: C.CauseProtocol_abstract_syntax_error_falsely_constructed_message},
+
+"transport:transport-resource-unavailable": {causeGroup:C.Cause_PR_transport,  cause: C.CauseTransport_transport_resource_unavailable},
+"transport:unspecified":{causeGroup:C.Cause_PR_transport,  cause: C.CauseTransport_unspecified},
+
+"radioNetwork:handover-desirable-for-radio-reasons": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_handover_desirable_for_radio_reasons},
+"radioNetwork:time-critical-handover": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_time_critical_handover},
+"radioNetwork:resource-optimisation-handover": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_resource_optimisation_handover},
+"radioNetwork:reduce-load-in-serving-cell": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_reduce_load_in_serving_cell},
+"radioNetwork:partial-handover": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_partial_handover},
+"radioNetwork:unknown-new-enb-ue-x2ap-id": {causeGroup:C.Cause_PR_radioNetwork,  cause:C.CauseRadioNetwork_unknown_new_eNB_UE_X2AP_ID},
+"radioNetwork:unknown-old-enb-ue-x2ap-id": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_unknown_old_eNB_UE_X2AP_ID},
+"radioNetwork:unknown-pair-of-ue-x2ap-id": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_unknown_pair_of_UE_X2AP_ID},
+"radioNetwork:ho-target-not-allowed": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_ho_target_not_allowed},
+"radioNetwork:tx2relocoverall-expiry": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_tx2relocoverall_expiry},
+"radioNetwork:trelocprep-expiry": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_trelocprep_expiry},
+"radioNetwork:cell-not-available": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_cell_not_available},
+"radioNetwork:no-radio-resources-available-in-target-cell": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_no_radio_resources_available_in_target_cell},
+"radioNetwork:invalid-mme-groupid": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_invalid_MME_GroupID},
+"radioNetwork:unknown-mme-code": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_unknown_MME_Code},
+"radioNetwork:encryption-and-or-integrity-protection-algorithms-not-supported": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported},
+"radioNetwork:reportcharacteristicsempty": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_reportCharacteristicsEmpty},
+"radioNetwork:noreportperiodicity": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_noReportPeriodicity},
+"radioNetwork:existingMeasurementID": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_existingMeasurementID},
+"radioNetwork:unknown-enb-measurement-id": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_unknown_eNB_Measurement_ID},
+"radioNetwork:measurement-temporarily-not-available": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_measurement_temporarily_not_available},
+"radioNetwork:unspecified": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_unspecified},
+"radioNetwork:load-balancing": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_load_balancing},
+"radioNetwork:handover-optimisation": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_handover_optimisation},
+"radioNetwork:value-out-of-allowed-range": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_value_out_of_allowed_range},
+"radioNetwork:multiple-E-RAB-ID-instances": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_multiple_E_RAB_ID_instances},
+"radioNetwork:switch-off-ongoing": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_switch_off_ongoing},
+"radioNetwork:not-supported-qci-value": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_not_supported_QCI_value},
+"radioNetwork:measurement-not-supported-for-the-object": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_measurement_not_supported_for_the_object},
+"radioNetwork:tdcoverall-expiry": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_tDCoverall_expiry},
+"radioNetwork:tdcprep-expiry": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_tDCprep_expiry},
+"radioNetwork:action-desirable-for-radio-reasons": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_action_desirable_for_radio_reasons},
+"radioNetwork:reduce-load": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_reduce_load},
+"radioNetwork:resource-optimisation": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_resource_optimisation},
+"radioNetwork:time-critical-action": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_time_critical_action},
+"radioNetwork:target-not-allowed": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_target_not_allowed},
+"radioNetwork:no-radio-resources-available": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_no_radio_resources_available},
+"radioNetwork:invalid-qos-combination": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_invalid_QoS_combination},
+"radioNetwork:encryption-algorithms-not-aupported": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_encryption_algorithms_not_aupported},
+"radioNetwork:procedure-cancelled":{causeGroup:C.Cause_PR_radioNetwork,  cause:C.CauseRadioNetwork_procedure_cancelled},
+"radioNetwork:rrm-purpose": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_rRM_purpose},
+"radioNetwork:improve-user-bit-rate": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_improve_user_bit_rate},
+"radioNetwork:user-inactivity": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_user_inactivity},
+"radioNetwork:radio-connection-with-ue-lost": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_radio_connection_with_UE_lost},
+"radioNetwork:failure-in-the-radio-interface-procedure": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_failure_in_the_radio_interface_procedure},
+"radioNetwork:bearer-option-not-supported": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_bearer_option_not_supported},
+"radioNetwork:mcg-mobility": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_mCG_Mobility},
+"radioNetwork:scg-mobility": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_sCG_Mobility},
+"radioNetwork:count-reaches-max-value": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_count_reaches_max_value},
+"radioNetwork:unknown-old-en-gnb-ue-x2ap-id": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_unknown_old_en_gNB_UE_X2AP_ID} ,
+"radioNetwork:pdcp-Overload": {causeGroup:C.Cause_PR_radioNetwork,  cause: C.CauseRadioNetwork_pDCP_Overload},
+}
+
+func NewX2ResetRequestHandler(rmrService *services.RmrService, config *configuration.Configuration, writerProvider func() rNibWriter.RNibWriter,
+       readerProvider func() reader.RNibReader) *X2ResetRequestHandler {
+       return &X2ResetRequestHandler{
+               readerProvider: readerProvider,
+               writerProvider: writerProvider,
+               rmrService: rmrService,
+               config:         config,
+       }
+}
+
+func (handler *X2ResetRequestHandler) Handle(logger *logger.Logger, request models.Request, rmrResponseChannel chan<- *models.NotificationResponse) error {
+       resetRequest := request.(models.ResetRequest)
+       nodeb, err  := handler.readerProvider().GetNodeb(resetRequest.RanName)
+       if err != nil {
+               logger.Errorf("#reset_request_handler.Handle - failed to get status of RAN: %s from RNIB. Error: %s", resetRequest.RanName,  err.Error())
+               if err.GetCode() == common.RESOURCE_NOT_FOUND {
+                       return e2managererrors.NewResourceNotFoundError()
+               }
+               return e2managererrors.NewRnibDbError()
+       }
+
+       if nodeb.ConnectionStatus != entities.ConnectionStatus_CONNECTED {
+               logger.Errorf("#reset_request_handler.Handle - RAN: %s in wrong state (%s)", resetRequest.RanName, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)])
+               return e2managererrors.NewWrongStateError()
+       }
+
+
+       if len(resetRequest.Cause) == 0 {
+               resetRequest.Cause = "misc:om-intervention"
+       }
+       cause, ok:= knownCauses[resetRequest.Cause]
+       if !ok {
+               logger.Errorf("#reset_request_handler.Handle - Unknown cause (%s)", resetRequest.Cause)
+               return e2managererrors.NewRequestValidationError()
+       }
+
+       var payloadSize  = C.ulong(MaxAsn1PackedBufferSize)
+       packedBuffer := [MaxAsn1PackedBufferSize]C.uchar{}
+       errorBuffer := [MaxAsn1CodecMessageBufferSize]C.char{}
+
+       if status := C.build_pack_x2reset_request(cause.causeGroup, C.int(cause.cause), &payloadSize, &packedBuffer[0], MaxAsn1CodecMessageBufferSize, &errorBuffer[0]); !status {
+               logger.Errorf("#reset_request_handler.Handle - failed to build and pack the reset message %s ", C.GoString(&errorBuffer[0]))
+               return  e2managererrors.NewInternalError()
+       }
+       transactionId := resetRequest.RanName
+       handler.rmrService.E2sessions[transactionId] = sessions.E2SessionDetails{SessionStart: resetRequest.StartTime, Request: &models.RequestDetails{RanName: resetRequest.RanName}}
+       response := models.NotificationResponse{MgsType: rmrCgo.RIC_X2_RESET, RanName: resetRequest.RanName, Payload: C.GoBytes(unsafe.Pointer(&packedBuffer[0]), C.int(payloadSize))}
+       if err:= handler.rmrService.SendRmrMessage(&response); err != nil {
+               logger.Errorf("#reset_request_handler.Handle - failed to send reset message to RMR: %s", err)
+               return  e2managererrors.NewRmrError()
+       }
+
+       logger.Infof("#reset_request_handler.Handle - sent x2 reset to RAN: %s with cause: %s", resetRequest.RanName, resetRequest.Cause)
+       return nil
+}
+
+
index 037dd1b..1e601fb 100644 (file)
@@ -26,6 +26,7 @@ import (
        "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
+       "e2mgr/services/receivers"
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/julienschmidt/httprouter"
@@ -53,9 +54,10 @@ func main() {
        var nManager = managers.NewNotificationManager(reader.GetRNibReader, rNibWriter.GetRNibWriter)
 
        rmrResponseChannel := make(chan *models.NotificationResponse, config.NotificationResponseBuffer)
-       rmrService := services.NewRmrService(rmrConfig, msgImpl, controllers.E2Sessions, nManager, rmrResponseChannel)
+       rmrService := services.NewRmrService(rmrConfig, msgImpl, controllers.E2Sessions, rmrResponseChannel)
+       rmrServiceReceiver := receivers.NewRmrServiceReceiver(*rmrService, nManager)
        defer rmrService.CloseContext()
-       go rmrService.ListenAndHandle()
+       go rmrServiceReceiver.ListenAndHandle()
        go rmrService.SendResponse()
        runServer(rmrService, logger, config, rmrResponseChannel)
 }
@@ -64,13 +66,14 @@ func runServer(rmrService *services.RmrService, logger *logger.Logger, config *c
 
        router := httprouter.New()
        controller := controllers.NewNodebController(logger, rmrService, reader.GetRNibReader, rNibWriter.GetRNibWriter)
-       newController := controllers.NewController(logger, reader.GetRNibReader, rNibWriter.GetRNibWriter, config, rmrResponseChannel)
+       newController := controllers.NewController(logger, rmrService, reader.GetRNibReader, rNibWriter.GetRNibWriter, config, rmrResponseChannel)
 
        router.POST("/v1/nodeb/:messageType", controller.HandleRequest)
        router.GET("/v1/nodeb-ids", controller.GetNodebIdList)
        router.GET("/v1/nodeb/:ranName", controller.GetNodeb)
        router.GET("/v1/health", controller.HandleHealthCheckRequest)
        router.PUT("/v1/nodeb/shutdown", newController.ShutdownHandler)
+       //router.PUT("/v1/nodeb-reset/:ranName", newController.X2ResetHandler)
 
        port := fmt.Sprintf(":%d", config.Http.Port)
        if err := http.ListenAndServe(port, router); err != nil {
index fc98987..0d8df33 100644 (file)
@@ -32,7 +32,7 @@ func (m *RnibReaderMock) GetNodeb(inventoryName string) (*entities.NodebInfo, co
 
        errArg := args.Get(1);
 
-       if (errArg != nil) {
+       if errArg != nil {
                return args.Get(0).(*entities.NodebInfo), errArg.(common.IRNibError);
        }
 
@@ -44,7 +44,7 @@ func (m *RnibReaderMock) GetNodebByGlobalNbId(nodeType entities.Node_Type, globa
 
        errArg := args.Get(1);
 
-       if (errArg != nil) {
+       if errArg != nil {
                return args.Get(0).(*entities.NodebInfo), errArg.(common.IRNibError);
        }
 
@@ -56,7 +56,7 @@ func (m *RnibReaderMock)  GetCellList(inventoryName string) (*entities.Cells, co
 
        errArg := args.Get(1);
 
-       if (errArg != nil) {
+       if errArg != nil {
                return args.Get(0).(*entities.Cells), errArg.(common.IRNibError);
        }
 
@@ -68,7 +68,7 @@ func (m *RnibReaderMock) GetListGnbIds()(*[]*entities.NbIdentity, common.IRNibEr
 
        errArg := args.Get(1);
 
-       if (errArg != nil) {
+       if errArg != nil {
                return args.Get(0).(*[]*entities.NbIdentity), errArg.(common.IRNibError);
        }
 
@@ -80,7 +80,7 @@ func (m *RnibReaderMock) GetListEnbIds()(*[]*entities.NbIdentity, common.IRNibEr
 
        errArg := args.Get(1);
 
-       if (errArg != nil) {
+       if errArg != nil {
                return args.Get(0).(*[]*entities.NbIdentity), errArg.(common.IRNibError);
        }
 
@@ -93,7 +93,7 @@ func (m *RnibReaderMock) GetCountGnbList()(int, common.IRNibError) {
 
        errArg := args.Get(1);
 
-       if (errArg != nil) {
+       if errArg != nil {
                return args.Int(0), errArg.(common.IRNibError);
        }
 
@@ -106,7 +106,7 @@ func (m *RnibReaderMock) GetCell(inventoryName string, pci uint32) (*entities.Ce
 
        errArg := args.Get(1);
 
-       if (errArg != nil) {
+       if errArg != nil {
                return args.Get(0).(*entities.Cell), errArg.(common.IRNibError);
        }
 
@@ -118,7 +118,7 @@ func (m *RnibReaderMock) GetCellById(cellType entities.Cell_Type, cellId string)
 
        errArg := args.Get(1);
 
-       if (errArg != nil) {
+       if errArg != nil {
                return args.Get(0).(*entities.Cell), errArg.(common.IRNibError);
        }
 
diff --git a/E2Manager/models/reset_request.go b/E2Manager/models/reset_request.go
new file mode 100644 (file)
index 0000000..39c40a0
--- /dev/null
@@ -0,0 +1,26 @@
+//
+// 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 "time"
+
+type ResetRequest struct {
+       StartTime time.Time
+       RanName string
+       Cause   string `json:"cause"`
+}
index 731fb25..e8a124a 100644 (file)
@@ -23,6 +23,7 @@ import (
        "e2mgr/handlers"
        "e2mgr/logger"
        "e2mgr/rNibWriter"
+       "e2mgr/services"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
 )
 
@@ -30,6 +31,7 @@ type IncomingRequest string
 
 const(
        ShutdownRequest IncomingRequest = "Shutdown"
+       ResetRequest IncomingRequest = "Reset"
 )
 
 type IncomingRequestHandlerProvider struct{
@@ -37,20 +39,21 @@ type IncomingRequestHandlerProvider struct{
        logger *logger.Logger
 }
 
-func NewIncomingRequestHandlerProvider(logger *logger.Logger, config *configuration.Configuration, rNibWriterProvider func() rNibWriter.RNibWriter,
+func NewIncomingRequestHandlerProvider(logger *logger.Logger, rmrService *services.RmrService, config *configuration.Configuration, rNibWriterProvider func() rNibWriter.RNibWriter,
        rNibReaderProvider func() reader.RNibReader) *IncomingRequestHandlerProvider {
 
        return &IncomingRequestHandlerProvider{
-               requestMap:     initRequestHandlerMap(config, rNibWriterProvider, rNibReaderProvider),
+               requestMap:     initRequestHandlerMap(rmrService, config,  rNibWriterProvider, rNibReaderProvider),
                logger: logger,
        }
 }
 
-func initRequestHandlerMap(config *configuration.Configuration, rNibWriterProvider func() rNibWriter.RNibWriter,
+func initRequestHandlerMap(rmrService *services.RmrService,config *configuration.Configuration, rNibWriterProvider func() rNibWriter.RNibWriter,
        rNibReaderProvider func() reader.RNibReader) map[IncomingRequest]handlers.RequestHandler {
 
        return map[IncomingRequest]handlers.RequestHandler{
                ShutdownRequest: handlers.NewDeleteAllRequestHandler(config, rNibWriterProvider, rNibReaderProvider), //TODO change to pointer
+               ResetRequest: handlers.NewX2ResetRequestHandler(rmrService, config, rNibWriterProvider, rNibReaderProvider),      //TODO change to pointer
        }
 }
 
index 5a939db..481309c 100644 (file)
@@ -23,15 +23,27 @@ import (
        "e2mgr/handlers"
        "e2mgr/logger"
        "e2mgr/mocks"
+       "e2mgr/models"
        "e2mgr/rNibWriter"
+       "e2mgr/rmrCgo"
+       "e2mgr/services"
+       "e2mgr/sessions"
+       "e2mgr/tests"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/assert"
        "reflect"
        "testing"
 )
 
+func getRmrService(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *services.RmrService {
+       rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
+       messageChannel := make(chan *models.NotificationResponse)
+       rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
+       return services.NewRmrService(services.NewRmrConfig(tests.Port, tests.MaxMsgSize, tests.Flags, log), rmrMessenger,  make(sessions.E2Sessions), messageChannel)
+}
 
 func TestNewIncomingRequestHandlerProvider(t *testing.T) {
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
 
        log := initLog(t)
        readerProvider := func() reader.RNibReader {
@@ -41,7 +53,7 @@ func TestNewIncomingRequestHandlerProvider(t *testing.T) {
                return &mocks.RnibWriterMock{}
        }
 
-       provider := NewIncomingRequestHandlerProvider(log, configuration.ParseConfiguration(), writerProvider, readerProvider)
+       provider := NewIncomingRequestHandlerProvider(log, getRmrService(rmrMessengerMock, log), configuration.ParseConfiguration(), writerProvider, readerProvider)
        /*if provider == nil {
                t.Errorf("want: provider, got: nil")
        }*/
@@ -50,6 +62,7 @@ func TestNewIncomingRequestHandlerProvider(t *testing.T) {
 }
 
 func TestShutdownRequestHandler(t *testing.T) {
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
 
        log := initLog(t)
        readerProvider := func() reader.RNibReader {
@@ -59,7 +72,7 @@ func TestShutdownRequestHandler(t *testing.T) {
                return &mocks.RnibWriterMock{}
        }
 
-       provider := NewIncomingRequestHandlerProvider(log, configuration.ParseConfiguration(), writerProvider, readerProvider)
+       provider := NewIncomingRequestHandlerProvider(log, getRmrService(rmrMessengerMock, log), configuration.ParseConfiguration(), writerProvider, readerProvider)
 
        handler, err := provider.GetHandler(ShutdownRequest)
 
@@ -78,7 +91,7 @@ func TestShutdownRequestHandler(t *testing.T) {
 }
 
 func TestGetShutdownHandlerFailure(t *testing.T) {
-
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
        log := initLog(t)
        readerProvider := func() reader.RNibReader {
                return &mocks.RnibReaderMock{}
@@ -87,7 +100,7 @@ func TestGetShutdownHandlerFailure(t *testing.T) {
                return &mocks.RnibWriterMock{}
        }
 
-       provider := NewIncomingRequestHandlerProvider(log, configuration.ParseConfiguration(), writerProvider, readerProvider)
+       provider := NewIncomingRequestHandlerProvider(log, getRmrService(rmrMessengerMock, log), configuration.ParseConfiguration(), writerProvider, readerProvider)
 
        _, actual := provider.GetHandler("test")
        expected := &e2managererrors.InternalError{}
index a284c95..e37b97b 100644 (file)
@@ -46,25 +46,27 @@ func NewContext(maxMsgSize int, flags int, ctx unsafe.Pointer, logger *logger.Lo
                Logger:     logger,
        }
 }
+
 //TODO: consider declaring using its own type
 const (
        // messages
-       RIC_X2_SETUP_REQ            = C.RIC_X2_SETUP_REQ
-       RIC_X2_SETUP_RESP           = C.RIC_X2_SETUP_RESP
-       RIC_X2_SETUP_FAILURE        = C.RIC_X2_SETUP_FAILURE
-       RIC_ENDC_X2_SETUP_REQ       = C.RIC_ENDC_X2_SETUP_REQ
-       RIC_ENDC_X2_SETUP_RESP      =C.RIC_ENDC_X2_SETUP_RESP
-       RIC_ENDC_X2_SETUP_FAILURE   = C.RIC_ENDC_X2_SETUP_FAILURE
-       RIC_SCTP_CONNECTION_FAILURE = C.RIC_SCTP_CONNECTION_FAILURE
-       RIC_ENB_LOAD_INFORMATION    = C.RIC_ENB_LOAD_INFORMATION
-       RIC_ENB_CONF_UPDATE             = C.RIC_ENB_CONF_UPDATE
-       RIC_ENB_CONFIGURATION_UPDATE_ACK = C.RIC_ENB_CONF_UPDATE_ACK
+       RIC_X2_SETUP_REQ                     = C.RIC_X2_SETUP_REQ
+       RIC_X2_SETUP_RESP                    = C.RIC_X2_SETUP_RESP
+       RIC_X2_SETUP_FAILURE                 = C.RIC_X2_SETUP_FAILURE
+       RIC_ENDC_X2_SETUP_REQ                = C.RIC_ENDC_X2_SETUP_REQ
+       RIC_ENDC_X2_SETUP_RESP               = C.RIC_ENDC_X2_SETUP_RESP
+       RIC_ENDC_X2_SETUP_FAILURE            = C.RIC_ENDC_X2_SETUP_FAILURE
+       RIC_SCTP_CONNECTION_FAILURE          = C.RIC_SCTP_CONNECTION_FAILURE
+       RIC_ENB_LOAD_INFORMATION             = C.RIC_ENB_LOAD_INFORMATION
+       RIC_ENB_CONF_UPDATE                  = C.RIC_ENB_CONF_UPDATE
+       RIC_ENB_CONFIGURATION_UPDATE_ACK     = C.RIC_ENB_CONF_UPDATE_ACK
        RIC_ENB_CONFIGURATION_UPDATE_FAILURE = C.RIC_ENB_CONF_UPDATE_FAILURE
-       RIC_ENDC_CONF_UPDATE            = C.RIC_ENDC_CONF_UPDATE
-       RIC_ENDC_CONF_UPDATE_ACK = C.RIC_ENDC_CONF_UPDATE_ACK
-       RIC_ENDC_CONF_UPDATE_FAILURE = C.RIC_ENDC_CONF_UPDATE_FAILURE
-       RIC_SCTP_CLEAR_ALL                      = C.RIC_SCTP_CLEAR_ALL
-       RIC_X2_RESET_RESP                       = C.RIC_X2_RESET_RESP
+       RIC_ENDC_CONF_UPDATE                 = C.RIC_ENDC_CONF_UPDATE
+       RIC_ENDC_CONF_UPDATE_ACK             = C.RIC_ENDC_CONF_UPDATE_ACK
+       RIC_ENDC_CONF_UPDATE_FAILURE         = C.RIC_ENDC_CONF_UPDATE_FAILURE
+       RIC_SCTP_CLEAR_ALL                   = C.RIC_SCTP_CLEAR_ALL
+       RIC_X2_RESET_RESP                    = C.RIC_X2_RESET_RESP
+       RIC_X2_RESET                         = C.RIC_X2_RESET
 )
 
 const (
@@ -72,41 +74,41 @@ const (
        RMR_MAX_MEID_LEN    = int(C.RMR_MAX_MEID)
 
        //states
-    RMR_OK                             = C.RMR_OK
-    RMR_ERR_BADARG             = C.RMR_ERR_BADARG
-    RMR_ERR_NOENDPT            = C.RMR_ERR_NOENDPT
-    RMR_ERR_EMPTY              = C.RMR_ERR_EMPTY
-    RMR_ERR_NOHDR              = C.RMR_ERR_NOHDR
-    RMR_ERR_SENDFAILED = C.RMR_ERR_SENDFAILED
-    RMR_ERR_CALLFAILED = C.RMR_ERR_CALLFAILED
-    RMR_ERR_NOWHOPEN   = C.RMR_ERR_NOWHOPEN
-    RMR_ERR_WHID               = C.RMR_ERR_WHID
-    RMR_ERR_OVERFLOW   = C.RMR_ERR_OVERFLOW
-    RMR_ERR_RETRY              = C.RMR_ERR_RETRY
-    RMR_ERR_RCVFAILED  = C.RMR_ERR_RCVFAILED
-    RMR_ERR_TIMEOUT            = C.RMR_ERR_TIMEOUT
-    RMR_ERR_UNSET       = C.RMR_ERR_UNSET
-    RMR_ERR_TRUNC       = C.RMR_ERR_TRUNC
-    RMR_ERR_INITFAILED  = C.RMR_ERR_INITFAILED
+       RMR_OK             = C.RMR_OK
+       RMR_ERR_BADARG     = C.RMR_ERR_BADARG
+       RMR_ERR_NOENDPT    = C.RMR_ERR_NOENDPT
+       RMR_ERR_EMPTY      = C.RMR_ERR_EMPTY
+       RMR_ERR_NOHDR      = C.RMR_ERR_NOHDR
+       RMR_ERR_SENDFAILED = C.RMR_ERR_SENDFAILED
+       RMR_ERR_CALLFAILED = C.RMR_ERR_CALLFAILED
+       RMR_ERR_NOWHOPEN   = C.RMR_ERR_NOWHOPEN
+       RMR_ERR_WHID       = C.RMR_ERR_WHID
+       RMR_ERR_OVERFLOW   = C.RMR_ERR_OVERFLOW
+       RMR_ERR_RETRY      = C.RMR_ERR_RETRY
+       RMR_ERR_RCVFAILED  = C.RMR_ERR_RCVFAILED
+       RMR_ERR_TIMEOUT    = C.RMR_ERR_TIMEOUT
+       RMR_ERR_UNSET      = C.RMR_ERR_UNSET
+       RMR_ERR_TRUNC      = C.RMR_ERR_TRUNC
+       RMR_ERR_INITFAILED = C.RMR_ERR_INITFAILED
 )
 
-var states = map[int]string {
-       RMR_OK                          :       "state is good",
-       RMR_ERR_BADARG          :       "argument passd to function was unusable",
-       RMR_ERR_NOENDPT         :       "send/call could not find an endpoint based on msg type",
-       RMR_ERR_EMPTY           :       "msg received had no payload; attempt to send an empty message",
-       RMR_ERR_NOHDR           :       "message didn't contain a valid header",
-       RMR_ERR_SENDFAILED      :       "send failed; errno has nano reason",
-       RMR_ERR_CALLFAILED      :       "unable to send call() message",
-       RMR_ERR_NOWHOPEN        :       "no wormholes are open",
-       RMR_ERR_WHID            :       "wormhole id was invalid",
-       RMR_ERR_OVERFLOW        :       "operation would have busted through a buffer/field size",
-       RMR_ERR_RETRY           :       "request (send/call/rts) failed, but caller should retry (EAGAIN for wrappers)",
-       RMR_ERR_RCVFAILED       :       "receive failed (hard error)",
-       RMR_ERR_TIMEOUT         :       "message processing call timed out",
-       RMR_ERR_UNSET       :   "the message hasn't been populated with a transport buffer",
-       RMR_ERR_TRUNC       :   "received message likely truncated",
-       RMR_ERR_INITFAILED  :   "initialisation of something (probably message) failed",
+var states = map[int]string{
+       RMR_OK:             "state is good",
+       RMR_ERR_BADARG:     "argument passd to function was unusable",
+       RMR_ERR_NOENDPT:    "send/call could not find an endpoint based on msg type",
+       RMR_ERR_EMPTY:      "msg received had no payload; attempt to send an empty message",
+       RMR_ERR_NOHDR:      "message didn't contain a valid header",
+       RMR_ERR_SENDFAILED: "send failed; errno has nano reason",
+       RMR_ERR_CALLFAILED: "unable to send call() message",
+       RMR_ERR_NOWHOPEN:   "no wormholes are open",
+       RMR_ERR_WHID:       "wormhole id was invalid",
+       RMR_ERR_OVERFLOW:   "operation would have busted through a buffer/field size",
+       RMR_ERR_RETRY:      "request (send/call/rts) failed, but caller should retry (EAGAIN for wrappers)",
+       RMR_ERR_RCVFAILED:  "receive failed (hard error)",
+       RMR_ERR_TIMEOUT:    "message processing call timed out",
+       RMR_ERR_UNSET:      "the message hasn't been populated with a transport buffer",
+       RMR_ERR_TRUNC:      "received message likely truncated",
+       RMR_ERR_INITFAILED: "initialisation of something (probably message) failed",
 }
 
 type MBuf struct {
@@ -117,15 +119,15 @@ type MBuf struct {
        XAction *[]byte
 }
 
-func (m MBuf) String () string {
+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 {
-       MaxMsgSize     int
-       Flags          int
-       RmrCtx         unsafe.Pointer
-       Logger         *logger.Logger
+       MaxMsgSize int
+       Flags      int
+       RmrCtx     unsafe.Pointer
+       Logger     *logger.Logger
 }
 
 type RmrMessenger interface {
index 2cf418a..5ff2cbe 100644 (file)
@@ -1,6 +1,8 @@
 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
diff --git a/E2Manager/services/receivers/rmr_service_receiver.go b/E2Manager/services/receivers/rmr_service_receiver.go
new file mode 100644 (file)
index 0000000..b2a1a08
--- /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 receivers
+
+import (
+       "e2mgr/managers"
+       "e2mgr/services"
+)
+
+// RmrService holds an instance of RMR messenger as well as its configuration
+type RmrServiceReceiver struct {
+       services.RmrService
+       nManager *managers.NotificationManager
+}
+
+// NewRmrService instantiates a new Rmr service instance
+func NewRmrServiceReceiver(rmrService services.RmrService, nManager *managers.NotificationManager) *RmrServiceReceiver {
+
+       return &RmrServiceReceiver{
+               RmrService: rmrService,
+               nManager:   nManager,
+       }
+}
+
+// ListenAndHandle waits for messages coming from rmr_rcv_msg and sends it to a designated message handler
+func (r *RmrServiceReceiver) ListenAndHandle() {
+
+       for {
+               mbuf, err := (*r.Messenger).RecvMsg()
+               r.Config.Logger.Debugf("#rmr_service_receiver.ListenAndHandle - Going to handle received message: %#v\n", mbuf)
+
+               // TODO: one mbuf received immediately execute goroutine
+               if err != nil {
+                       continue //TODO log error
+               }
+
+               r.nManager.HandleMessage(r.Config.Logger, r.E2sessions, mbuf, r.RmrResponse)
+       }
+}
diff --git a/E2Manager/services/receivers/rmr_service_receiver_test.go b/E2Manager/services/receivers/rmr_service_receiver_test.go
new file mode 100644 (file)
index 0000000..937a7c5
--- /dev/null
@@ -0,0 +1,71 @@
+//
+// 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 receivers
+
+import (
+       "e2mgr/logger"
+       "e2mgr/managers"
+       "e2mgr/mocks"
+       "e2mgr/models"
+       "e2mgr/rNibWriter"
+       "e2mgr/rmrCgo"
+       "e2mgr/services"
+       "e2mgr/sessions"
+       "e2mgr/tests"
+       "fmt"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
+       "testing"
+       "time"
+)
+
+func TestListenAndHandle(t *testing.T){
+       log, err := logger.InitLogger(logger.DebugLevel)
+       if err!=nil{
+               t.Errorf("#rmr_service_test.TestListenAndHandle - failed to initialize logger, error: %s", err)
+       }
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
+
+       var buf *rmrCgo.MBuf
+       e := fmt.Errorf("test error")
+       rmrMessengerMock.On("RecvMsg").Return(buf, e)
+
+       go  getRmrServiceReceiver(rmrMessengerMock,log).ListenAndHandle()
+
+       time.Sleep(time.Microsecond*10)
+}
+
+func getRmrService(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *services.RmrService {
+       rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
+       messageChannel := make(chan *models.NotificationResponse)
+       rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
+       return services.NewRmrService(services.NewRmrConfig(tests.Port, tests.MaxMsgSize, tests.Flags, log), rmrMessenger,  make(sessions.E2Sessions), messageChannel)
+}
+
+func getRmrServiceReceiver(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *RmrServiceReceiver {
+       readerMock :=&mocks.RnibReaderMock{}
+       rnibReaderProvider := func() reader.RNibReader {
+               return readerMock
+       }
+       writerMock := &mocks.RnibWriterMock{}
+       rnibWriterProvider := func() rNibWriter.RNibWriter {
+               return writerMock
+       }
+       nManager := managers.NewNotificationManager(rnibReaderProvider, rnibWriterProvider)
+       rmrService := getRmrService(rmrMessengerMock,log)
+       return NewRmrServiceReceiver(*rmrService, nManager)
+}
\ No newline at end of file
index 5a8be8b..a0126af 100644 (file)
@@ -19,7 +19,6 @@ package services
 
 import (
        "e2mgr/logger"
-       "e2mgr/managers"
        "e2mgr/models"
        "e2mgr/rmrCgo"
        "e2mgr/sessions"
@@ -27,7 +26,6 @@ import (
        "sync"
 )
 
-
 type RmrConfig struct {
        Port       int
        MaxMsgSize int
@@ -41,23 +39,20 @@ func NewRmrConfig(port int, maxMsgSize int, flags int, logger *logger.Logger) *R
 
 // RmrService holds an instance of RMR messenger as well as its configuration
 type RmrService struct {
-       config     *RmrConfig
-       messenger  *rmrCgo.RmrMessenger
-       e2sessions sessions.E2Sessions
-       nManager   *managers.NotificationManager
-       rmrResponse chan *models.NotificationResponse
+       Config      *RmrConfig
+       Messenger   *rmrCgo.RmrMessenger
+       E2sessions  sessions.E2Sessions
+       RmrResponse chan *models.NotificationResponse
 }
 
 // NewRmrService instantiates a new Rmr service instance
-func NewRmrService(rmrConfig *RmrConfig, msrImpl rmrCgo.RmrMessenger, e2sessions sessions.E2Sessions, nManager *managers.NotificationManager,
-       rmrResponse chan *models.NotificationResponse) *RmrService {
+func NewRmrService(rmrConfig *RmrConfig, msrImpl rmrCgo.RmrMessenger, e2sessions sessions.E2Sessions, rmrResponse chan *models.NotificationResponse) *RmrService {
 
        return &RmrService{
-               config:     rmrConfig,
-               messenger:  msrImpl.Init("tcp:"+strconv.Itoa(rmrConfig.Port), rmrConfig.MaxMsgSize, rmrConfig.Flags, rmrConfig.Logger),
-               e2sessions: e2sessions,
-               nManager:   nManager,
-               rmrResponse: rmrResponse,
+               Config:      rmrConfig,
+               Messenger:   msrImpl.Init("tcp:"+strconv.Itoa(rmrConfig.Port), rmrConfig.MaxMsgSize, rmrConfig.Flags, rmrConfig.Logger),
+               E2sessions:  e2sessions,
+               RmrResponse: rmrResponse,
        }
 }
 
@@ -66,72 +61,54 @@ func (r *RmrService) SendMessage(messageType int, messageChannel chan *models.E2
 
        wg.Add(1)
        setupRequestMessage := <-messageChannel
-       e2Message := setupRequestMessage.GetMessageAsBytes(r.config.Logger)
+       e2Message := setupRequestMessage.GetMessageAsBytes(r.Config.Logger)
 
        transactionId := []byte(setupRequestMessage.TransactionId())
 
-       msg := rmrCgo.NewMBuf(messageType, len(e2Message)/*r.config.MaxMsgSize*/, setupRequestMessage.RanName(), &e2Message, &transactionId)
+       msg := rmrCgo.NewMBuf(messageType, len(e2Message) /*r.config.MaxMsgSize*/, setupRequestMessage.RanName(), &e2Message, &transactionId)
 
-       r.config.Logger.Debugf("#rmr_service.SendMessage - Going to send the message: %#v\n", msg)
-       _, err := (*r.messenger).SendMsg(msg, r.config.MaxMsgSize)
+       r.Config.Logger.Debugf("#rmr_service.SendMessage - Going to send the message: %#v\n", msg)
+       _, err := (*r.Messenger).SendMsg(msg, r.Config.MaxMsgSize)
 
        errorChannel <- err
        wg.Done()
 }
 
-func (r *RmrService) SendRmrMessage(response *models.NotificationResponse) {
+func (r *RmrService) SendRmrMessage(response *models.NotificationResponse) error {
 
-       msgAsBytes := response.GetMessageAsBytes(r.config.Logger)
+       msgAsBytes := response.GetMessageAsBytes(r.Config.Logger)
        transactionIdByteArr := []byte(response.RanName)
 
        msg := rmrCgo.NewMBuf(response.MgsType, len(msgAsBytes), response.RanName, &msgAsBytes, &transactionIdByteArr)
 
-       r.config.Logger.Debugf("#rmr_service.SendRmrMessage - Going to send the message: %#v\n", msg)
-
-       _, err := (*r.messenger).SendMsg(msg, r.config.MaxMsgSize)
+       _, err := (*r.Messenger).SendMsg(msg, r.Config.MaxMsgSize)
 
        if err != nil {
-               r.config.Logger.Errorf("#rmr_service.SendRmrMessage - error: %#v\n", err)
-               return
+               r.Config.Logger.Errorf("#rmr_service.SendRmrMessage - error: %#v\n", err)
+               return err
        }
+       return nil
 }
 
-// ListenAndHandle waits for messages coming from rmr_rcv_msg and sends it to a designated message handler
-func (r *RmrService) ListenAndHandle() {
-
+func (r *RmrService) SendResponse() {
        for {
-               mbuf, err := (*r.messenger).RecvMsg()
-               r.config.Logger.Debugf("#rmr_service.ListenAndHandle - Going to handle received message: %#v\n", mbuf)
-
-               // TODO: one mbuf received immediately execute goroutine
-               if err != nil {
-                       continue        //TODO log error
-               }
 
-               r.nManager.HandleMessage(r.config.Logger, r.e2sessions, mbuf, r.rmrResponse)
-       }
-}
-
-func (r *RmrService) SendResponse(){
-       for{
-
-               response, ok := <-r.rmrResponse
+               response, ok := <-r.RmrResponse
                if !ok {
 
-                       r.config.Logger.Errorf("#rmr_service.SendResponse - channel closed")
+                       r.Config.Logger.Errorf("#rmr_service.SendResponse - channel closed")
                        break
                }
 
-               r.config.Logger.Debugf("#rmr_service.SendResponse - Going to send message: %#v\n", response)
+               r.Config.Logger.Debugf("#rmr_service.SendResponse - Going to send message: %#v\n", response)
                r.SendRmrMessage(response)
        }
 }
 
 func (r *RmrService) CloseContext() {
-       if r.config.Logger.DebugEnabled(){
-               r.config.Logger.Debugf("#rmr_service.CloseContext - RMR is ready: %v", (*r.messenger).IsReady())
-               (*r.messenger).Close()
-               r.config.Logger.Debugf("#rmr_service.CloseContext - RMR is ready: %v", (*r.messenger).IsReady())
+       if r.Config.Logger.DebugEnabled() {
+               r.Config.Logger.Debugf("#rmr_service.CloseContext - RMR is ready: %v", (*r.Messenger).IsReady())
+               (*r.Messenger).Close()
+               r.Config.Logger.Debugf("#rmr_service.CloseContext - RMR is ready: %v", (*r.Messenger).IsReady())
        }
 }
-
index 1fad55c..3e0a5be 100644 (file)
@@ -19,15 +19,12 @@ package services
 
 import (
        "e2mgr/logger"
-       "e2mgr/managers"
        "e2mgr/mocks"
        "e2mgr/models"
-       "e2mgr/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/sessions"
        "e2mgr/tests"
        "fmt"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
        "sync"
@@ -60,22 +57,6 @@ func TestSendMessage(t *testing.T){
        assert.Empty (t, errorChannel)
 }
 
-func TestListenAndHandle(t *testing.T){
-       log, err := logger.InitLogger(logger.DebugLevel)
-       if err!=nil{
-               t.Errorf("#rmr_service_test.TestListenAndHandle - failed to initialize logger, error: %s", err)
-       }
-       rmrMessengerMock := &mocks.RmrMessengerMock{}
-
-       var buf *rmrCgo.MBuf
-       e := fmt.Errorf("test error")
-       rmrMessengerMock.On("RecvMsg").Return(buf, e)
-
-       go  getRmrService(rmrMessengerMock,log).ListenAndHandle()
-
-       time.Sleep(time.Microsecond*10)
-}
-
 func TestCloseContext(t *testing.T){
        log, err := logger.InitLogger(logger.DebugLevel)
        if err!=nil{
@@ -92,16 +73,7 @@ func TestCloseContext(t *testing.T){
 
 func getRmrService(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *RmrService {
        rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
-       readerMock :=&mocks.RnibReaderMock{}
-       rnibReaderProvider := func() reader.RNibReader {
-               return readerMock
-       }
-       writerMock := &mocks.RnibWriterMock{}
-       rnibWriterProvider := func() rNibWriter.RNibWriter {
-               return writerMock
-       }
-       nManager := managers.NewNotificationManager(rnibReaderProvider, rnibWriterProvider)
        messageChannel := make(chan *models.NotificationResponse)
        rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
-       return NewRmrService(NewRmrConfig(tests.Port, tests.MaxMsgSize, tests.Flags, log), rmrMessenger,  make(sessions.E2Sessions), nManager, messageChannel)
-}
\ No newline at end of file
+       return NewRmrService(NewRmrConfig(tests.Port, tests.MaxMsgSize, tests.Flags, log), rmrMessenger,  make(sessions.E2Sessions), messageChannel)
+}