From: idanshal Date: Wed, 11 Mar 2020 16:11:02 +0000 (+0200) Subject: Support E2 Setup message... X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F58%2F2758%2F1;p=ric-plt%2Fe2mgr.git Support E2 Setup message... Change-Id: I3bb3476065aba70e3aac1fec212003e8c26e680e Signed-off-by: idanshal --- diff --git a/E2Manager/Dockerfile b/E2Manager/Dockerfile index 25a972a..1726158 100644 --- a/E2Manager/Dockerfile +++ b/E2Manager/Dockerfile @@ -27,10 +27,10 @@ COPY . . ENV PATH=$PATH:/usr/local/go/bin:/usr/lib/go-1.12/bin #RUN git clone https://gerrit.o-ran-sc.org/r/ric-plt/lib/rmr && cd rmr/; mkdir build; cd build; /opt/bin/cmake -DDEV_PKG=1 ..; make install # Install RMr library and dev files -RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.13.0_amd64.deb/download.deb -RUN dpkg -i rmr_1.13.0_amd64.deb -RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.13.0_amd64.deb/download.deb -RUN dpkg -i rmr-dev_1.13.0_amd64.deb +RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_3.3.0_amd64.deb/download.deb +RUN dpkg -i rmr_3.3.0_amd64.deb +RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_3.3.0_amd64.deb/download.deb +RUN dpkg -i rmr-dev_3.3.0_amd64.deb RUN cd 3rdparty/asn1codec && make RUN go build app/main.go diff --git a/E2Manager/go.mod b/E2Manager/go.mod index 8cd3f48..6f2c06e 100644 --- a/E2Manager/go.mod +++ b/E2Manager/go.mod @@ -1,9 +1,9 @@ module e2mgr require ( - gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.30 - gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.30 - gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.30 + gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.31 + gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.31 + gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.31 gerrit.o-ran-sc.org/r/ric-plt/sdlgo v0.5.2 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/go-ozzo/ozzo-validation v3.5.0+incompatible diff --git a/E2Manager/go.sum b/E2Manager/go.sum index 1f1691a..50ace17 100644 --- a/E2Manager/go.sum +++ b/E2Manager/go.sum @@ -1,10 +1,16 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.30 h1:GuA/5jPx+Srjcs38Bja0392Ht+7ubUOyBbCAp4QRCJY= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.30/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.31 h1:zRZCGfATFQ2VfK4Eh7DaWQn7AgySsUqDheCLx5cfN3U= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.31/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.30 h1:MBOyQeDNA+8rs8OSsEIuh7oHhO/5v7ISimd/BMRhLYA= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.30/go.mod h1:Fh23KkroYw5CRBh39WzZzxpKSkpQWL3scdzGnMngLo8= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.31 h1:J5voE21HWJv1lZKJS7Yc+qPSTc3U2g9NRiCVsdTR2KQ= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.31/go.mod h1:Fh23KkroYw5CRBh39WzZzxpKSkpQWL3scdzGnMngLo8= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.30 h1:fL5qY6KS5RRxvduCnXeK8fWj7YUF1p9b9ObduFSSlRs= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.30/go.mod h1:HeUXZTDqAaGYiVVcWrHwgY0qDNQ6Rt6nZSvWdMueDNc= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.31 h1:hNK2niv1crecqU44P/gmz/VQSABhVXqkcDlvb62E0jo= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.31/go.mod h1:0VWDEhoWG7Zflif7FjVzgomzcnS4TjlYM2l/NzREauY= gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.2 h1:UK7awyRKIkVdokWvvkYvazlg3EWIfMnIqCcJxTnLlDA= gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.2/go.mod h1:y2WhrCvdLkAKdH+ySdHSOSehACJkTMyZghCGVcqoZzc= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= diff --git a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go new file mode 100644 index 0000000..1c5abe7 --- /dev/null +++ b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go @@ -0,0 +1,147 @@ +package rmrmsghandlers + +import ( + "bytes" + "e2mgr/logger" + "e2mgr/managers" + "e2mgr/models" + "e2mgr/rmrCgo" + "e2mgr/services" + "e2mgr/services/rmrsender" + "e2mgr/utils" + "encoding/xml" + "errors" + "fmt" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" +) + +type E2SetupRequestNotificationHandler struct { + logger *logger.Logger + e2tInstancesManager managers.IE2TInstancesManager + rmrSender *rmrsender.RmrSender + rNibDataService services.RNibDataService + e2tAssociationManager *managers.E2TAssociationManager +} + +func NewE2SetupRequestNotificationHandler(logger *logger.Logger, e2tInstancesManager managers.IE2TInstancesManager, rmrSender *rmrsender.RmrSender, rNibDataService services.RNibDataService, e2tAssociationManager *managers.E2TAssociationManager) E2SetupRequestNotificationHandler { + return E2SetupRequestNotificationHandler{ + logger: logger, + e2tInstancesManager: e2tInstancesManager, + rmrSender: rmrSender, + rNibDataService: rNibDataService, + e2tAssociationManager: e2tAssociationManager, + } +} + +func (h E2SetupRequestNotificationHandler) Handle(request *models.NotificationRequest){ + ranName := request.RanName + h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - received E2 Setup Request. Payload: %x", ranName, request.Payload) + + setupRequest, e2tIpAddress, err := h.parseSetupRequest(request.Payload) + if err != nil { + h.logger.Errorf(err.Error()) + return + } + + h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - E2T Address: %s - handling E2_SETUP_REQUEST", e2tIpAddress) + + _, err = h.e2tInstancesManager.GetE2TInstance(e2tIpAddress) + + if err != nil { + h.logger.Errorf("#E2TermInitNotificationHandler.Handle - Failed retrieving E2TInstance. error: %s", err) + return + } + + nodebInfo, err := h.rNibDataService.GetNodeb(ranName) + if err != nil{ + if _, ok := err.(*common.ResourceNotFoundError); ok{ + nbIdentity := h.buildNbIdentity(ranName, setupRequest) + nodebInfo = h.buildNodebInfo(ranName, e2tIpAddress, setupRequest) + err = h.rNibDataService.SaveNodeb(nbIdentity, nodebInfo) + if err != nil{ + h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - failed to save nodebInfo entity. Error: %s", ranName, err) + return + } + } else{ + h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - failed to retrieve nodebInfo entity. Error: %s", ranName, err) + return + } + + } else { + if nodebInfo.ConnectionStatus == entities.ConnectionStatus_SHUTTING_DOWN { + h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s, connection status: %s - nodeB entity in incorrect state", nodebInfo.RanName, nodebInfo.ConnectionStatus) + h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - Summary: elapsed time for receiving and handling setup request message from E2 terminator: %f ms", utils.ElapsedTime(request.StartTime)) + return + } + h.updateNodeBFunctions(nodebInfo, setupRequest) + } + err = h.e2tAssociationManager.AssociateRan(e2tIpAddress, nodebInfo) + if err != nil{ + h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - failed to associate E2T to nodeB entity. Error: %s", ranName, err) + return + } + successResponse := &models.E2SetupSuccessResponseMessage{} + successResponse.SetPlmnId(setupRequest.GetPlmnId()) + successResponse.SetNbId("&" + fmt.Sprintf("%020b", 0xf0)) + responsePayload, err := xml.Marshal(successResponse) + if err != nil{ + h.logger.Warnf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - Error marshalling E2 Setup Response. Response: %x", ranName, responsePayload) + } + msg := models.NewRmrMessage(rmrCgo.RIC_E2_SETUP_RESP, ranName, responsePayload, request.TransactionId) + h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - E2 Setup Request has been built. Message: %x", ranName, msg) + //TODO err = h.rmrSender.Send(msg) + +} + +func (h E2SetupRequestNotificationHandler) parseSetupRequest(payload []byte)(*models.E2SetupRequestMessage, string, error){ + + colonInd := bytes.IndexByte(payload, ':') + if colonInd < 0 { + return nil, "", errors.New("#E2SetupRequestNotificationHandler.parseSetupRequest - Error parsing E2 Setup Request, failed extract E2T IP Address: no ':' separator found") + } + + e2tIpAddress := string(payload[:colonInd]) + if len(e2tIpAddress) == 0 { + return nil, "", errors.New("#E2SetupRequestNotificationHandler.parseSetupRequest - Empty E2T Address received") + } + + pipInd := bytes.IndexByte(payload, '|') + if pipInd < 0 { + return nil, "", errors.New( "#E2SetupRequestNotificationHandler.parseSetupRequest - Error parsing E2 Setup Request failed extract Payload: no | separator found") + } + + setupRequest := &models.E2SetupRequestMessage{} + err := xml.Unmarshal(payload[pipInd + 1:], &setupRequest) + if err != nil { + return nil, "", errors.New("#E2SetupRequestNotificationHandler.parseSetupRequest - Error unmarshalling E2 Setup Request payload: %s") + } + + return setupRequest, e2tIpAddress, nil +} + +func (h E2SetupRequestNotificationHandler) updateNodeBFunctions(nodeB *entities.NodebInfo, request *models.E2SetupRequestMessage){ + //TODO the function should be implemented in the scope of the US 192 "Save the entire Setup request in RNIB" +} + +func (h E2SetupRequestNotificationHandler) buildNodebInfo(ranName string, e2tAddress string, request *models.E2SetupRequestMessage) *entities.NodebInfo{ + nodebInfo := &entities.NodebInfo{ + AssociatedE2TInstanceAddress: e2tAddress, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + RanName: ranName, + NodeType: entities.Node_GNB, + Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}}, + } + h.updateNodeBFunctions(nodebInfo, request) + return nodebInfo +} + +func (h E2SetupRequestNotificationHandler) buildNbIdentity(ranName string, setupRequest *models.E2SetupRequestMessage)*entities.NbIdentity{ + return &entities.NbIdentity{ + InventoryName:ranName, + GlobalNbId: &entities.GlobalNbId{ + PlmnId: setupRequest.GetPlmnId(), + NbId: setupRequest.GetNbId(), + }, + } +} \ No newline at end of file diff --git a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go new file mode 100644 index 0000000..bd24f17 --- /dev/null +++ b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go @@ -0,0 +1,505 @@ +package rmrmsghandlers + +import ( + "bytes" + "e2mgr/configuration" + "e2mgr/logger" + "e2mgr/managers" + "e2mgr/mocks" + "e2mgr/models" + "e2mgr/services" + "e2mgr/tests" + "errors" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "io" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +const ( + prefix = "10.0.2.15:9999|" + logFilePath = "./loggerTest.txt" + e2tInstanceAddress = "10.0.2.15" + nodebRanName = "gnb:310-410-b5c67788" +) + +func TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess(t *testing.T) { + path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml") + if err != nil { + t.Fatal(err) + } + xmlGnb, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + + logFile, err := os.Create(logFilePath) + if err != nil{ + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err) + } + oldStdout := os.Stdout + defer changeStdout(oldStdout) + defer removeLogFile(t) + os.Stdout = logFile + + handler := stubMockSuccessFlowNewNodeb(t) + prefBytes := []byte(prefix) + notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)} + handler.Handle(notificationRequest) + assertSuccessFlowNewNodebLogs(t) +} + +func TestE2SetupRequestNotificationHandler_HandleNewEnGnbSuccess(t *testing.T) { + path, err :=filepath.Abs("../../tests/resources/setupRequest_en-gNB.xml") + if err != nil { + t.Fatal(err) + } + xmlEnGnb, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + logFile, err := os.Create(logFilePath) + if err != nil{ + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewEnGnbSuccess - failed to create file, error: %s", err) + } + oldStdout := os.Stdout + defer changeStdout(oldStdout) + defer removeLogFile(t) + os.Stdout = logFile + + handler := stubMockSuccessFlowNewNodeb(t) + prefBytes := []byte(prefix) + notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlEnGnb...)} + handler.Handle(notificationRequest) + assertSuccessFlowNewNodebLogs(t) +} + +func TestE2SetupRequestNotificationHandler_HandleNewNgEnbSuccess(t *testing.T) { + path, err :=filepath.Abs("../../tests/resources/setupRequest_ng-eNB.xml") + if err != nil { + t.Fatal(err) + } + xmlEnGnb, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + logFile, err := os.Create(logFilePath) + if err != nil{ + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewNgEnbSuccess - failed to create file, error: %s", err) + } + oldStdout := os.Stdout + defer changeStdout(oldStdout) + defer removeLogFile(t) + os.Stdout = logFile + + handler := stubMockSuccessFlowNewNodeb(t) + prefBytes := []byte(prefix) + notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlEnGnb...)} + handler.Handle(notificationRequest) + assertSuccessFlowNewNodebLogs(t) +} + +func TestE2SetupRequestNotificationHandler_HandleExistingGnbSuccess(t *testing.T) { + path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml") + if err != nil { + t.Fatal(err) + } + xmlGnb, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + + logFile, err := os.Create(logFilePath) + if err != nil{ + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err) + } + oldStdout := os.Stdout + defer changeStdout(oldStdout) + defer removeLogFile(t) + os.Stdout = logFile + + handler := stubMockSuccessFlowExistingNodeb(t) + prefBytes := []byte(prefix) + notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)} + handler.Handle(notificationRequest) + assertSuccessFlowExistingNodebLogs(t) +} + +func TestE2SetupRequestNotificationHandler_HandleParseError(t *testing.T) { + path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml") + if err != nil { + t.Fatal(err) + } + xmlGnb, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + + logFile, err := os.Create(logFilePath) + if err != nil{ + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err) + } + oldStdout := os.Stdout + defer changeStdout(oldStdout) + defer removeLogFile(t) + os.Stdout = logFile + + _, handler, _, _, _, _, _ := initMocks(t) + prefBytes := []byte("invalid_prefix") + notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)} + handler.Handle(notificationRequest) + assertParseErrorFlowLogs(t) +} + +func TestE2SetupRequestNotificationHandler_HandleUnmarshalError(t *testing.T) { + logFile, err := os.Create(logFilePath) + if err != nil{ + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err) + } + oldStdout := os.Stdout + defer changeStdout(oldStdout) + defer removeLogFile(t) + os.Stdout = logFile + + _, handler, _, _, _, _, _ := initMocks(t) + prefBytes := []byte(prefix) + notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, "xmlGnb"...)} + handler.Handle(notificationRequest) + assertUnmarshalErrorFlowLogs(t) +} + +func TestE2SetupRequestNotificationHandler_HandleGetE2TInstanceError(t *testing.T) { + path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml") + if err != nil { + t.Fatal(err) + } + xmlGnb, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + + logFile, err := os.Create(logFilePath) + if err != nil{ + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err) + } + oldStdout := os.Stdout + defer changeStdout(oldStdout) + defer removeLogFile(t) + os.Stdout = logFile + + _, handler, _, _, _, e2tInstancesManagerMock, _ := initMocks(t) + var e2tInstance * entities.E2TInstance + e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, common.NewResourceNotFoundError("Not found")) + prefBytes := []byte(prefix) + notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)} + handler.Handle(notificationRequest) + assertGetE2TInstanceErrorLogs(t) +} + +func TestE2SetupRequestNotificationHandler_HandleGetNodebError(t *testing.T) { + path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml") + if err != nil { + t.Fatal(err) + } + xmlGnb, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + + logFile, err := os.Create(logFilePath) + if err != nil{ + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err) + } + oldStdout := os.Stdout + defer changeStdout(oldStdout) + defer removeLogFile(t) + os.Stdout = logFile + _, handler, readerMock, _, _, e2tInstancesManagerMock, _ := initMocks(t) + var e2tInstance = &entities.E2TInstance{} + e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil) + var gnb *entities.NodebInfo + readerMock.On("GetNodeb", mock.Anything).Return(gnb, common.NewInternalError(errors.New("Some error"))) + prefBytes := []byte(prefix) + notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)} + handler.Handle(notificationRequest) + assertGetNodebErrorLogs(t) +} + +func TestE2SetupRequestNotificationHandler_HandleAssociationError(t *testing.T) { + path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml") + if err != nil { + t.Fatal(err) + } + xmlGnb, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + + logFile, err := os.Create(logFilePath) + if err != nil{ + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err) + } + oldStdout := os.Stdout + defer changeStdout(oldStdout) + defer removeLogFile(t) + os.Stdout = logFile + + _, handler, readerMock, writerMock, _, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t) + var e2tInstance = &entities.E2TInstance{} + e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil) + var gnb *entities.NodebInfo + readerMock.On("GetNodeb", mock.Anything).Return(gnb, common.NewResourceNotFoundError("Not found")) + writerMock.On("SaveNodeb", mock.Anything, mock.Anything).Return(nil) + routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceAddress, mock.Anything).Return(errors.New("association error")) + + prefBytes := []byte(prefix) + notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)} + handler.Handle(notificationRequest) + assertAssociationErrorLogs(t) +} + +func TestE2SetupRequestNotificationHandler_HandleExistingGnbInvalidStatusError(t *testing.T) { + path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml") + if err != nil { + t.Fatal(err) + } + xmlGnb, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + + logFile, err := os.Create(logFilePath) + if err != nil{ + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err) + } + oldStdout := os.Stdout + defer changeStdout(oldStdout) + defer removeLogFile(t) + os.Stdout = logFile + + handler := stubMockInvalidStatusFlowExistingNodeb(t) + prefBytes := []byte(prefix) + notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)} + handler.Handle(notificationRequest) + assertInvalidNodebStatusLogs(t) +} + +func assertInvalidNodebStatusLogs(t *testing.T){ + buf := getLogFileBuffer(t) + assertReceivedAndParsedLog(buf, t) + assertInvalidNodebStatusLog(buf, t) + assertNoMoreRecordsLog(buf, t) +} + +func assertInvalidNodebStatusLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "#RnibDataService.GetNodeb") + assert.Contains(t, record, "connection status: SHUTTING_DOWN") + record, _ = buf.ReadString('\n') + assert.Contains(t, record, "#E2SetupRequestNotificationHandler.Handle") + assert.Contains(t, record, "connection status: SHUTTING_DOWN - nodeB entity in incorrect state") + record, _ = buf.ReadString('\n') + assert.Contains(t, record, "#E2SetupRequestNotificationHandler.Handle") + assert.Contains(t, record, "Summary: elapsed time for receiving and handling setup request message from E2 terminator") +} + +func assertAssociationErrorLogs(t *testing.T){ + buf := getLogFileBuffer(t) + assertReceivedAndParsedLog(buf, t) + assertNewNodebSavedLog(buf, t) + assertAssociationErrorLog(buf, t) + assertNoMoreRecordsLog(buf, t) +} + +func assertAssociationErrorLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "#E2TAssociationManager.AssociateRan - Associating RAN") + record, _ = buf.ReadString('\n') + assert.Contains(t, record, "#E2TAssociationManager.AssociateRan - RoutingManager failure: Failed to associate RAN") + record, _ = buf.ReadString('\n') + assert.Contains(t, record, "#E2SetupRequestNotificationHandler.Handle - RAN name:") + assert.Contains(t, record, "failed to associate E2T to nodeB entity") +} + +func assertGetNodebErrorLogs(t *testing.T) { + buf := getLogFileBuffer(t) + assertReceivedAndParsedLog(buf, t) + assertGetNodebErrorLog(buf, t) + assertNoMoreRecordsLog(buf, t) +} + +func assertGetNodebErrorLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "failed to retrieve nodebInfo entity") +} + +func assertGetE2TInstanceErrorLogs(t *testing.T) { + buf := getLogFileBuffer(t) + assertReceivedAndParsedLog(buf, t) + assertGetE2TInstanceErrorLog(buf, t) + assertNoMoreRecordsLog(buf, t) +} + +func assertGetE2TInstanceErrorLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "Failed retrieving E2TInstance") +} + +func removeLogFile(t *testing.T) { + err := os.Remove(logFilePath) + if err != nil { + t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleGnbSuccess - failed to remove file, error: %s", err) + } +} + +func assertParseErrorFlowLogs(t *testing.T) { + buf := getLogFileBuffer(t) + assertReceivedAndFailedParseLog(buf, t) + assertNoMoreRecordsLog(buf, t) +} + +func assertUnmarshalErrorFlowLogs(t *testing.T) { + buf := getLogFileBuffer(t) + assertReceivedAndFailedUnmarshalLog(buf, t) + assertNoMoreRecordsLog(buf, t) +} + +func assertSuccessFlowNewNodebLogs(t *testing.T){ + buf := getLogFileBuffer(t) + assertReceivedAndParsedLog(buf, t) + assertNewNodebSavedLog(buf, t) + assertAssociatedLog(buf, t) + assertRequestBuiltLog(buf, t) + assertNoMoreRecordsLog(buf, t) +} + +func assertSuccessFlowExistingNodebLogs(t *testing.T){ + buf := getLogFileBuffer(t) + assertReceivedAndParsedLog(buf, t) + assertExistingNodebRetrievedLog(buf, t) + assertAssociatedLog(buf, t) + assertRequestBuiltLog(buf, t) + assertNoMoreRecordsLog(buf, t) +} + +func assertReceivedAndParsedLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "received E2 Setup Request") + record, _ = buf.ReadString('\n') + assert.Contains(t, record, "handling E2_SETUP_REQUEST") +} + +func assertReceivedAndFailedParseLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "received E2 Setup Request") + record, _ = buf.ReadString('\n') + assert.Contains(t, record, "Error parsing E2 Setup Request") +} + +func assertReceivedAndFailedUnmarshalLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "received E2 Setup Request") + record, _ = buf.ReadString('\n') + assert.Contains(t, record, "Error unmarshalling E2 Setup Request") +} + +func assertNewNodebSavedLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "#RnibDataService.SaveNodeb - nbIdentity:") +} + +func assertExistingNodebRetrievedLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "#RnibDataService.GetNodeb - RAN name:") +} + +func assertAssociatedLog(buf *bytes.Buffer, t *testing.T){ + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "#E2TAssociationManager.AssociateRan - Associating RAN") + record, _ = buf.ReadString('\n') + assert.Contains(t, record, "#RnibDataService.UpdateNodebInfo") + record, _ = buf.ReadString('\n') + assert.Contains(t, record, "#E2TAssociationManager.AssociateRan - successfully associated RAN") +} + +func assertRequestBuiltLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Contains(t, record, "E2 Setup Request has been built") +} + +func assertNoMoreRecordsLog(buf *bytes.Buffer, t *testing.T) { + record, _ := buf.ReadString('\n') + assert.Empty(t, record) +} + +func stubMockSuccessFlowNewNodeb(t *testing.T) E2SetupRequestNotificationHandler{ + _, handler, readerMock, writerMock, _, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t) + var e2tInstance = &entities.E2TInstance{} + e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil) + var gnb *entities.NodebInfo + readerMock.On("GetNodeb", mock.Anything).Return(gnb, common.NewResourceNotFoundError("Not found")) + writerMock.On("SaveNodeb", mock.Anything, mock.Anything).Return(nil) + routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceAddress, mock.Anything).Return(nil) + writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil) + e2tInstancesManagerMock.On("AddRansToInstance", mock.Anything, mock.Anything).Return(nil) + return handler +} + +func stubMockSuccessFlowExistingNodeb(t *testing.T) E2SetupRequestNotificationHandler{ + _, handler, readerMock, writerMock, _, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t) + var e2tInstance = &entities.E2TInstance{} + e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil) + var gnb = &entities.NodebInfo{RanName: nodebRanName} + readerMock.On("GetNodeb", mock.Anything).Return(gnb, nil) + routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceAddress, mock.Anything).Return(nil) + writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil) + e2tInstancesManagerMock.On("AddRansToInstance", mock.Anything, mock.Anything).Return(nil) + return handler +} + +func stubMockInvalidStatusFlowExistingNodeb(t *testing.T) E2SetupRequestNotificationHandler{ + _, handler, readerMock, _, _, e2tInstancesManagerMock, _ := initMocks(t) + var e2tInstance = &entities.E2TInstance{} + e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil) + var gnb = &entities.NodebInfo{RanName: nodebRanName, ConnectionStatus:entities.ConnectionStatus_SHUTTING_DOWN} + readerMock.On("GetNodeb", mock.Anything).Return(gnb, nil) + return handler +} + +func initMocks(t *testing.T) (*logger.Logger, E2SetupRequestNotificationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock, *mocks.RoutingManagerClientMock) { + logger := tests.InitLog(t) + config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3} + rmrMessengerMock := &mocks.RmrMessengerMock{} + rmrSender := tests.InitRmrSender(rmrMessengerMock, logger) + readerMock := &mocks.RnibReaderMock{} + writerMock := &mocks.RnibWriterMock{} + routingManagerClientMock := &mocks.RoutingManagerClientMock{} + rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock) + e2tInstancesManagerMock := &mocks.E2TInstancesManagerMock{} + e2tAssociationManager := managers.NewE2TAssociationManager(logger, rnibDataService, e2tInstancesManagerMock, routingManagerClientMock) + handler := NewE2SetupRequestNotificationHandler(logger, e2tInstancesManagerMock, rmrSender, rnibDataService, e2tAssociationManager) + return logger, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock +} + +func changeStdout(old *os.File) { + os.Stdout = old +} + +func getLogFileBuffer(t *testing.T) *bytes.Buffer { + logFile, err := os.Open(logFilePath) + if err != nil { + t.Errorf("e2_setup_request_notification_handler_test.assertSuccessFlowNewNodebLogRecords - failed to open file, error: %s", err) + } + var buf bytes.Buffer + _, err = io.Copy(&buf, logFile) + if err != nil { + t.Errorf("e2_setup_request_notification_handler_test.assertSuccessFlowNewNodebLogRecords - failed to copy bytes, error: %s", err) + } + return &buf +} + diff --git a/E2Manager/handlers/rmrmsghandlers/e2_term_init_notification_handler_test.go b/E2Manager/handlers/rmrmsghandlers/e2_term_init_notification_handler_test.go index 9a258d0..95b818b 100644 --- a/E2Manager/handlers/rmrmsghandlers/e2_term_init_notification_handler_test.go +++ b/E2Manager/handlers/rmrmsghandlers/e2_term_init_notification_handler_test.go @@ -42,7 +42,6 @@ import ( "testing" ) -const e2tInstanceAddress = "10.0.2.15" const e2tInitPayload = "{\"address\":\"10.0.2.15\", \"fqdn\":\"\"}" func initRanLostConnectionTest(t *testing.T) (*logger.Logger, E2TermInitNotificationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.E2TInstancesManagerMock, *mocks.RoutingManagerClientMock) { @@ -96,7 +95,7 @@ func TestE2TermInitUnmarshalPayloadFailure(t *testing.T) { } func TestE2TermInitEmptyE2TAddress(t *testing.T) { - _, handler, _, _, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t) + _, handler, _, _, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t) notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte("{\"address\":\"\"}")} handler.Handle(notificationRequest) e2tInstancesManagerMock.AssertNotCalled(t, "GetE2TInstance") @@ -104,7 +103,7 @@ func TestE2TermInitEmptyE2TAddress(t *testing.T) { } func TestE2TermInitGetE2TInstanceFailure(t *testing.T) { - _, handler, _, _, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t) + _, handler, _, _, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t) var e2tInstance *entities.E2TInstance e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, common.NewInternalError(fmt.Errorf("internal error"))) notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)} @@ -163,7 +162,7 @@ func TestE2TermInitNewE2TInstance__RoutingManagerError(t *testing.T) { } func TestE2TermInitExistingE2TInstanceNoAssociatedRans(t *testing.T) { - _, handler, _, _, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t) + _, handler, _, _, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t) e2tInstance := entities.NewE2TInstance(e2tInstanceAddress) e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil) notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)} @@ -239,7 +238,7 @@ func TestE2TermInitHandlerSuccessOneRan_RoutingManagerError(t *testing.T) { } func TestE2TermInitHandlerSuccessOneRanShuttingdown(t *testing.T) { - _, _, handler, readerMock, writerMock,_ := initRanLostConnectionTestWithRealE2tInstanceManager(t) + _, _, handler, readerMock, writerMock, _ := initRanLostConnectionTestWithRealE2tInstanceManager(t) var rnibErr error var initialNodeb = &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST} @@ -259,7 +258,7 @@ func TestE2TermInitHandlerSuccessOneRanShuttingdown(t *testing.T) { } func TestE2TermInitHandlerSuccessOneRan_ToBeDeleted(t *testing.T) { - _, _, handler, readerMock, writerMock, httpClientMock:= initRanLostConnectionTestWithRealE2tInstanceManager(t) + _, _, handler, readerMock, writerMock, httpClientMock := initRanLostConnectionTestWithRealE2tInstanceManager(t) var rnibErr error var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST} @@ -299,7 +298,6 @@ func TestE2TermInitHandlerSuccessTwoRans(t *testing.T) { var updatedDisconnectedFirstRan = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, RanName: RanName, AssociatedE2TInstanceAddress: ""} writerMock.On("UpdateNodebInfo", updatedDisconnectedFirstRan).Return(rnibErr) - //Second RAN var secondRan = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, RanName: test2, AssociatedE2TInstanceAddress: "10.0.2.15"} var disconnectedSecondRan = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, RanName: test2, AssociatedE2TInstanceAddress: "10.0.2.15"} @@ -433,7 +431,7 @@ func TestE2TermInitHandlerSuccessTwoRansFirstRnibInternalErrorFailure(t *testing } func TestE2TermInitHandlerSuccessZeroRans(t *testing.T) { - _, handler, _, writerMock, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t) + _, handler, _, writerMock, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t) e2tInstance := entities.NewE2TInstance(e2tInstanceAddress) e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil) diff --git a/E2Manager/models/e2_setup_request_message.go b/E2Manager/models/e2_setup_request_message.go new file mode 100644 index 0000000..63c4a8e --- /dev/null +++ b/E2Manager/models/e2_setup_request_message.go @@ -0,0 +1,157 @@ +package models + +import ( + "encoding/xml" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" +) + +type E2SetupRequestMessage struct { + XMLName xml.Name `xml:"E2SetupRequestMessage"` + Text string `xml:",chardata"` + E2APPDU struct { + Text string `xml:",chardata"` + InitiatingMessage struct { + Text string `xml:",chardata"` + ProcedureCode string `xml:"procedureCode"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2setupRequest struct { + Text string `xml:",chardata"` + ProtocolIEs struct { + Text string `xml:",chardata"` + E2setupRequestIEs []struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + GlobalE2nodeID struct { + Text string `xml:",chardata"` + GNB struct { + Text string `xml:",chardata"` + GlobalGNBID struct { + Text string `xml:",chardata"` + PlmnID string `xml:"plmn-id"` + GnbID struct { + Text string `xml:",chardata"` + GnbID string `xml:"gnb-ID"` + } `xml:"gnb-id"` + } `xml:"global-gNB-ID"` + } `xml:"gNB"` + EnGNB struct { + Text string `xml:",chardata"` + GlobalGNBID struct { + Text string `xml:",chardata"` + PlmnID string `xml:"plmn-id"` + GnbID struct { + Text string `xml:",chardata"` + GnbID string `xml:"gnb-ID"` + } `xml:"gnb-id"` + } `xml:"global-gNB-ID"` + } `xml:"en-gNB"` + NgENB struct { + Text string `xml:",chardata"` + GlobalNgENBID struct { + Text string `xml:",chardata"` + PlmnID string `xml:"plmn-id"` + GnbID struct { + Text string `xml:",chardata"` + GnbID string `xml:"gnb-ID"` + } `xml:"gnb-id"` + } `xml:"global-ng-eNB-ID"` + } `xml:"ng-eNB"` + ENB struct { + Text string `xml:",chardata"` + GlobalENBID struct { + Text string `xml:",chardata"` + PlmnID string `xml:"plmn-id"` + GnbID struct { + Text string `xml:",chardata"` + GnbID string `xml:"gnb-ID"` + } `xml:"gnb-id"` + } `xml:"global-eNB-ID"` + } `xml:"eNB"` + } `xml:"GlobalE2node-ID"` + RANfunctionsList struct { + Text string `xml:",chardata"` + ProtocolIESingleContainer []struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + RANfunctionItem struct { + Text string `xml:",chardata"` + RanFunctionID string `xml:"ranFunctionID"` + RanFunctionDefinition string `xml:"ranFunctionDefinition"` + RanFunctionRevision string `xml:"ranFunctionRevision"` + } `xml:"RANfunction-Item"` + } `xml:"value"` + } `xml:"ProtocolIE-SingleContainer"` + } `xml:"RANfunctions-List"` + } `xml:"value"` + } `xml:"E2setupRequestIEs"` + } `xml:"protocolIEs"` + } `xml:"E2setupRequest"` + } `xml:"value"` + } `xml:"initiatingMessage"` + } `xml:"E2AP-PDU"` +} + +func (m *E2SetupRequestMessage) GetNodeType() entities.Node_Type{ + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.GNB.GlobalGNBID.PlmnID; id!= ""{ + return entities.Node_GNB + } + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.EnGNB.GlobalGNBID.PlmnID; id!= ""{ + return entities.Node_GNB + } + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.ENB.GlobalENBID.PlmnID; id!= ""{ + return entities.Node_ENB + } + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.NgENB.GlobalNgENBID.PlmnID; id!= ""{ + return entities.Node_GNB + } + return entities.Node_UNKNOWN +} + +func (m *E2SetupRequestMessage) GetPlmnId() string{ + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.GNB.GlobalGNBID.PlmnID; id!= ""{ + return id + } + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.EnGNB.GlobalGNBID.PlmnID; id!= ""{ + return id + } + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.ENB.GlobalENBID.PlmnID; id!= ""{ + return id + } + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.NgENB.GlobalNgENBID.PlmnID; id!= ""{ + return id + } + return "" +} + +func (m *E2SetupRequestMessage) GetNbId() string{ + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.GNB.GlobalGNBID.GnbID.GnbID; id!= ""{ + return id + } + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.EnGNB.GlobalGNBID.GnbID.GnbID; id!= ""{ + return id + } + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.ENB.GlobalENBID.GnbID.GnbID; id!= ""{ + return id + } + if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.NgENB.GlobalNgENBID.GnbID.GnbID; id!= ""{ + return id + } + return "" +} \ No newline at end of file diff --git a/E2Manager/models/e2_setup_success_response_message.go b/E2Manager/models/e2_setup_success_response_message.go new file mode 100644 index 0000000..f829651 --- /dev/null +++ b/E2Manager/models/e2_setup_success_response_message.go @@ -0,0 +1,54 @@ +package models +import ( + "encoding/xml" +) + +type E2SetupSuccessResponseMessage struct { + XMLName xml.Name `xml:"E2SetupSuccessResponseMessage"` + Text string `xml:",chardata"` + E2APPDU struct { + Text string `xml:",chardata"` + SuccessfulOutcome struct { + Text string `xml:",chardata"` + ProcedureCode string `xml:"procedureCode"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + E2setupResponse struct { + Text string `xml:",chardata"` + ProtocolIEs struct { + Text string `xml:",chardata"` + E2setupResponseIEs struct { + Text string `xml:",chardata"` + ID string `xml:"id"` + Criticality struct { + Text string `xml:",chardata"` + Reject string `xml:"reject"` + } `xml:"criticality"` + Value struct { + Text string `xml:",chardata"` + GlobalRICID struct { + Text string `xml:",chardata"` + PLMNIdentity string `xml:"pLMN-Identity"` + RicID string `xml:"ric-ID"` + } `xml:"GlobalRIC-ID"` + } `xml:"value"` + } `xml:"E2setupResponseIEs"` + } `xml:"protocolIEs"` + } `xml:"E2setupResponse"` + } `xml:"value"` + } `xml:"successfulOutcome"` + } `xml:"E2AP-PDU"` +} + + +func (m *E2SetupSuccessResponseMessage) SetPlmnId(plmnId string){ + m.E2APPDU.SuccessfulOutcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs.Value.GlobalRICID.PLMNIdentity = plmnId +} + +func (m *E2SetupSuccessResponseMessage) SetNbId(ricID string){ + m.E2APPDU.SuccessfulOutcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs.Value.GlobalRICID.RicID = ricID +} \ No newline at end of file diff --git a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go index 252e047..b161841 100644 --- a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go +++ b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go @@ -68,7 +68,7 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config x2ResetResponseExtractor := converters.NewX2ResetResponseExtractor(logger) // Init managers - ranDisconnectionManager := managers.NewRanDisconnectionManager(logger, config, rnibDataService, e2tAssociationManager) + ranReconnectionManager := managers.NewRanDisconnectionManager(logger, config, rnibDataService, e2tAssociationManager) ranStatusChangeManager := managers.NewRanStatusChangeManager(logger, rmrSender) x2SetupResponseManager := managers.NewX2SetupResponseManager(x2SetupResponseConverter) x2SetupFailureResponseManager := managers.NewX2SetupFailureResponseManager(x2SetupFailureResponseConverter) @@ -80,14 +80,15 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config x2SetupFailureResponseHandler := rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, x2SetupFailureResponseManager, nil, rmrCgo.RIC_X2_SETUP_FAILURE) endcSetupResponseHandler := rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, endcSetupResponseManager, ranStatusChangeManager, rmrCgo.RIC_ENDC_X2_SETUP_RESP) endcSetupFailureResponseHandler := rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, endcSetupFailureResponseManager, nil, rmrCgo.RIC_ENDC_X2_SETUP_FAILURE) - ranLostConnectionHandler := rmrmsghandlers.NewRanLostConnectionHandler(logger, ranDisconnectionManager) + ranLostConnectionHandler := rmrmsghandlers.NewRanLostConnectionHandler(logger, ranReconnectionManager) enbLoadInformationNotificationHandler := rmrmsghandlers.NewEnbLoadInformationNotificationHandler(logger, rnibDataService, enbLoadInformationExtractor) x2EnbConfigurationUpdateHandler := rmrmsghandlers.NewX2EnbConfigurationUpdateHandler(logger, rmrSender) endcConfigurationUpdateHandler := rmrmsghandlers.NewEndcConfigurationUpdateHandler(logger, rmrSender) x2ResetResponseHandler := rmrmsghandlers.NewX2ResetResponseHandler(logger, rnibDataService, ranStatusChangeManager, x2ResetResponseExtractor) x2ResetRequestNotificationHandler := rmrmsghandlers.NewX2ResetRequestNotificationHandler(logger, rnibDataService, ranStatusChangeManager, rmrSender) - e2TermInitNotificationHandler := rmrmsghandlers.NewE2TermInitNotificationHandler(logger, ranDisconnectionManager, e2tInstancesManager, routingManagerClient) + e2TermInitNotificationHandler := rmrmsghandlers.NewE2TermInitNotificationHandler(logger, ranReconnectionManager, e2tInstancesManager, routingManagerClient) e2TKeepAliveResponseHandler := rmrmsghandlers.NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManager) + e2SetupRequestNotificationHandler := rmrmsghandlers.NewE2SetupRequestNotificationHandler(logger, e2tInstancesManager, rmrSender, rnibDataService, e2tAssociationManager) provider.Register(rmrCgo.RIC_X2_SETUP_RESP, x2SetupResponseHandler) provider.Register(rmrCgo.RIC_X2_SETUP_FAILURE, x2SetupFailureResponseHandler) @@ -101,4 +102,5 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config provider.Register(rmrCgo.RIC_X2_RESET, x2ResetRequestNotificationHandler) provider.Register(rmrCgo.RIC_E2_TERM_INIT, e2TermInitNotificationHandler) provider.Register(rmrCgo.E2_TERM_KEEP_ALIVE_RESP, e2TKeepAliveResponseHandler) + provider.Register(rmrCgo.RIC_E2_SETUP_REQ, e2SetupRequestNotificationHandler) } diff --git a/E2Manager/rmrCgo/rmrCgoTypes.go b/E2Manager/rmrCgo/rmrCgoTypes.go index eff707c..4875e1e 100644 --- a/E2Manager/rmrCgo/rmrCgoTypes.go +++ b/E2Manager/rmrCgo/rmrCgoTypes.go @@ -76,6 +76,9 @@ const ( 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 + RIC_E2_SETUP_REQ = C.RIC_E2_SETUP_REQ + RIC_E2_SETUP_RESP = C.RIC_E2_SETUP_RESP + RIC_E2_SETUP_FAILURE = C.RIC_E2_SETUP_FAILURE ) const ( diff --git a/E2Manager/tests/resources/setupRequest_en-gNB.xml b/E2Manager/tests/resources/setupRequest_en-gNB.xml new file mode 100644 index 0000000..95b137a --- /dev/null +++ b/E2Manager/tests/resources/setupRequest_en-gNB.xml @@ -0,0 +1,62 @@ + + + + 1 + + + + + + 3 + + + + + + 13 10 14 + + + 10110101110001100111011110001000 + + + + + + + + + 10 + + + + + 8 + + + + 1 + 33 44 55 + 0 + + + + + 8 + + + + 7 + 33 44 55 + 0 + + + + + + + + + + + + \ No newline at end of file diff --git a/E2Manager/tests/resources/setupRequest_gnb.xml b/E2Manager/tests/resources/setupRequest_gnb.xml new file mode 100644 index 0000000..1a74a2a --- /dev/null +++ b/E2Manager/tests/resources/setupRequest_gnb.xml @@ -0,0 +1,60 @@ + + + + 1 + + + + + + 3 + + + + + + 13 10 14 + + 10110101110001100111011110001000 + + + + + + + + 10 + + + + + 8 + + + + 1 + 33 44 55 + 0 + + + + + 8 + + + + 7 + 33 44 55 + 0 + + + + + + + + + + + + \ No newline at end of file diff --git a/E2Manager/tests/resources/setupRequest_ng-eNB.xml b/E2Manager/tests/resources/setupRequest_ng-eNB.xml new file mode 100644 index 0000000..c60775c --- /dev/null +++ b/E2Manager/tests/resources/setupRequest_ng-eNB.xml @@ -0,0 +1,60 @@ + + + + 1 + + + + + + 3 + + + + + + 13 10 14 + + 10110101110001100111011110001000 + + + + + + + + 10 + + + + + 8 + + + + 1 + 33 44 55 + 0 + + + + + 8 + + + + 7 + 33 44 55 + 0 + + + + + + + + + + + + \ No newline at end of file