From: Amichai Date: Thu, 23 Jul 2020 11:28:40 +0000 (+0000) Subject: [RIC-571] Setup request of new eNB X-Git-Tag: R5_RC~25 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F34%2F4434%2F3;hp=74f9752fae845468e4f8948265c892fa8fe9fdb7;p=ric-plt%2Fe2mgr.git [RIC-571] Setup request of new eNB Change-Id: I2c5d153d82bd38faeb589a59568be967fc26a5d9 Signed-off-by: Amichai --- diff --git a/E2Manager/container-tag.yaml b/E2Manager/container-tag.yaml index d0105e3..45daa1d 100644 --- a/E2Manager/container-tag.yaml +++ b/E2Manager/container-tag.yaml @@ -1,4 +1,4 @@ # The Jenkins job requires a tag to build the Docker image. # Global-JJB script assumes this file is in the repo root. --- -tag: 5.2.20 \ No newline at end of file +tag: 5.2.21 \ No newline at end of file diff --git a/E2Manager/controllers/nodeb_controller_test.go b/E2Manager/controllers/nodeb_controller_test.go index a8a4e9f..1b3a7db 100644 --- a/E2Manager/controllers/nodeb_controller_test.go +++ b/E2Manager/controllers/nodeb_controller_test.go @@ -101,7 +101,7 @@ type updateEnbCellsParams struct { err error } -type saveNodebParams struct { +type addEnbParams struct { err error } @@ -139,7 +139,7 @@ type controllerUpdateGnbTestContext struct { type controllerAddEnbTestContext struct { getNodebInfoResult *getNodebInfoResult - saveNodebParams *saveNodebParams + addEnbParams *addEnbParams addNbIdentityParams *addNbIdentityParams requestBody map[string]interface{} expectedStatusCode int @@ -432,7 +432,7 @@ func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNo controller.GetNodebIdList(writer, req) assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode) bodyBytes, _ := ioutil.ReadAll(writer.Body) - assert.Equal(t, context.expectedJsonResponse, string(bodyBytes)) + assert.Contains(t, context.expectedJsonResponse, string(bodyBytes)) } func activateControllerUpdateEnbMocks(context *controllerUpdateEnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock, updateEnbRequest *models.UpdateEnbRequest) { @@ -562,7 +562,7 @@ func activateControllerAddEnbMocks(context *controllerAddEnbTestContext, readerM readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError) } - if context.saveNodebParams != nil { + if context.addEnbParams != nil { nodebInfo := entities.NodebInfo{ RanName: addEnbRequest.RanName, Ip: addEnbRequest.Ip, @@ -573,7 +573,7 @@ func activateControllerAddEnbMocks(context *controllerAddEnbTestContext, readerM ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, } - writerMock.On("SaveNodeb", &nodebInfo).Return(context.saveNodebParams.err) + writerMock.On("AddEnb", &nodebInfo).Return(context.addEnbParams.err) } if context.addNbIdentityParams != nil { @@ -1220,8 +1220,8 @@ func TestControllerAddEnbNodebExistsFailure(t *testing.T) { func TestControllerAddEnbSaveNodebFailure(t *testing.T) { context := controllerAddEnbTestContext{ - saveNodebParams: &saveNodebParams{ - err: common.NewInternalError(errors.New("#reader.SaveeNodeb - Internal Error")), + addEnbParams: &addEnbParams{ + err: common.NewInternalError(errors.New("#reader.AddEnb - Internal Error")), }, getNodebInfoResult: &getNodebInfoResult{ nodebInfo: nil, @@ -1237,7 +1237,7 @@ func TestControllerAddEnbSaveNodebFailure(t *testing.T) { func TestControllerAddEnbAddNbIdentityFailure(t *testing.T) { context := controllerAddEnbTestContext{ - saveNodebParams: &saveNodebParams{ + addEnbParams: &addEnbParams{ err: nil, }, addNbIdentityParams: &addNbIdentityParams{ @@ -1342,7 +1342,7 @@ func TestControllerAddEnbMissingRequiredServedCellProps(t *testing.T) { func TestControllerAddEnbSuccess(t *testing.T) { context := controllerAddEnbTestContext{ - saveNodebParams: &saveNodebParams{ + addEnbParams: &addEnbParams{ err: nil, }, addNbIdentityParams: &addNbIdentityParams{ @@ -1479,7 +1479,7 @@ func TestControllerGetNodebIdListSuccess(t *testing.T) { nodebIdList: nodebIdList, rnibError: rnibError, expectedStatusCode: http.StatusOK, - expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}]", + expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}][{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}},{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}}]", } controllerGetNodebIdListTestExecuter(t, &context) diff --git a/E2Manager/e2managererrors/unknown_setup_request_ranname_error.go b/E2Manager/e2managererrors/unknown_setup_request_ranname_error.go new file mode 100644 index 0000000..72f7f56 --- /dev/null +++ b/E2Manager/e2managererrors/unknown_setup_request_ranname_error.go @@ -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. +// + +// This source code is part of the near-RT RIC (RAN Intelligent Controller) +// platform project (RICP). + +package e2managererrors + +import "fmt" + +type UnknownSetupRequestRanNameError struct { + *BaseError + ranName string +} + +func NewUnknownSetupRequestRanNameError(ranName string) *UnknownSetupRequestRanNameError { + return &UnknownSetupRequestRanNameError{ + &BaseError{ + Code: 599, + Message: fmt.Sprintf("Can't extract node-type out of RAN name %s", ranName), + }, + ranName, + } +} + +func (e *UnknownSetupRequestRanNameError) Error() string { + return e.Message +} diff --git a/E2Manager/go.mod b/E2Manager/go.mod index 9cf5006..344bac4 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.46 - gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.46 - gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.46 + gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.47 + gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.47 + gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.47 gerrit.o-ran-sc.org/r/ric-plt/sdlgo v0.5.2 github.com/golang/protobuf v1.4.2 github.com/gorilla/mux v1.7.0 diff --git a/E2Manager/go.sum b/E2Manager/go.sum index 62ac537..6cea29b 100644 --- a/E2Manager/go.sum +++ b/E2Manager/go.sum @@ -1,22 +1,10 @@ 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.44 h1:rda7Ubx7ZW579wWNduk/MD/9Fl7fsKo08KE+2ngIkZM= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.44/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.45 h1:2zwckksGVcIkXJeymAPvtyaO3bb+8UCyRENY8/q1yZs= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.45/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.46 h1:mUn8CsJYcliKK35Xm7xMjkrTnhksZ9AinPkTu44ABKA= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.46/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.44 h1:/Kye3C5ZAJkK1ux1mNrQEE4Jph537EV6DJ1qOCtKPqQ= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.44/go.mod h1:YaQ+XEI4PcAoISxp9wUpUr2TP0J7JihpQTD0G1Lpd4A= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.45 h1:YuNGHpf6UsHkvi4qqxbE6ijuceRqoz5+qdWe6nUTNIU= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.45/go.mod h1:YaQ+XEI4PcAoISxp9wUpUr2TP0J7JihpQTD0G1Lpd4A= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.46 h1:bd1nDjy20ia7vUWw3Dqvxf9shMSAtJOObSotr4iwGxM= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.46/go.mod h1:YaQ+XEI4PcAoISxp9wUpUr2TP0J7JihpQTD0G1Lpd4A= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.44 h1:VCOBMhSZJE3hZJLA+eJOZCrCoifCDi7ZmR3aMdV5mP8= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.44/go.mod h1:eRI+ExoQG8rEzexqRtW5Shn2tT/7w9l+WqaiPZqOsEA= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.45 h1:p+yPMhomeiQy+qermMGzBhwh/i9T2gaL8cWOT3V5DG4= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.45/go.mod h1:3p1bZS4GA2MGVg5CHZEnMlCuO7KXpfW3Y38HTAbo6/4= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.46 h1:GlwpSMYc0wuARKfiEfF0p0ttsinWhmvKVpFZknGor24= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.46/go.mod h1:O83fcA6x8B7tPBgr2ihBXsfRkcL0m3NWYMLsD/gvGWU= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.47 h1:ANQeff4O93le30a0pLrN51feB+jMTCSQZ1txzlGodZU= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.47/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.47 h1:wIiT6TjsCHBw1J9ro9FcjtnU6R9TPHPPFrIzc7LejQM= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.47/go.mod h1:YaQ+XEI4PcAoISxp9wUpUr2TP0J7JihpQTD0G1Lpd4A= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.47 h1:jMK6IoI7ibAzV96WtVDo4BJzENUYAQ3Y47kqdNgW0Ts= +gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.47/go.mod h1:cicCB/v15pTNovRNhyL6MBEHCwNsF/RU8xBc5vdoA7k= 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/httpmsghandlers/add_enb_request_handler.go b/E2Manager/handlers/httpmsghandlers/add_enb_request_handler.go index 46cd802..6f7fcd6 100644 --- a/E2Manager/handlers/httpmsghandlers/add_enb_request_handler.go +++ b/E2Manager/handlers/httpmsghandlers/add_enb_request_handler.go @@ -73,10 +73,10 @@ func (h *AddEnbRequestHandler) Handle(request models.Request) (models.IResponse, } nodebInfo := h.createNodebInfo(addEnbRequest) - err = h.rNibDataService.SaveNodeb(nodebInfo) + err = h.rNibDataService.AddEnb(nodebInfo) if err != nil { - h.logger.Errorf("#AddEnbRequestHandler.Handle - RAN name: %s - failed to save nodeb entity in RNIB. Error: %s", addEnbRequest.RanName, err) + h.logger.Errorf("#AddEnbRequestHandler.Handle - RAN name: %s - failed to add eNB entity in RNIB. Error: %s", addEnbRequest.RanName, err) return nil, e2managererrors.NewRnibDbError() } diff --git a/E2Manager/handlers/httpmsghandlers/delete_all_request_handler_test.go b/E2Manager/handlers/httpmsghandlers/delete_all_request_handler_test.go index 3cf5b46..cd2a4f2 100644 --- a/E2Manager/handlers/httpmsghandlers/delete_all_request_handler_test.go +++ b/E2Manager/handlers/httpmsghandlers/delete_all_request_handler_test.go @@ -147,8 +147,10 @@ func TestTwoRansGetE2TAddressesEmptyListOneGetNodebFailure(t *testing.T) { readerMock.On("GetNodeb", "RanName_2").Return(nb2, common.NewInternalError(errors.New("error"))) _, err = h.Handle(nil) assert.IsType(t, &e2managererrors.RnibDbError{}, err) - writerMock.AssertExpectations(t) - readerMock.AssertExpectations(t) + writerMock.AssertNotCalled(t, "UpdateNodebInfo", nb2) + readerMock.AssertCalled(t, "GetE2TAddresses") + readerMock.AssertCalled(t, "GetListNodebIds") + readerMock.AssertCalled(t, "GetNodeb", "RanName_2") } func TestUpdateNodebInfoOnConnectionStatusInversionFailure(t *testing.T) { @@ -163,6 +165,10 @@ func TestUpdateNodebInfoOnConnectionStatusInversionFailure(t *testing.T) { nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED} readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil) + nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN} + readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil) + writerMock.On("UpdateNodebInfo", nb2) + updatedNb1 := *nb1 updatedNb1.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNb1, "RanName_1_DISCONNECTED").Return(common.NewInternalError(errors.New("error"))) @@ -170,8 +176,10 @@ func TestUpdateNodebInfoOnConnectionStatusInversionFailure(t *testing.T) { _, err := h.Handle(nil) assert.IsType(t, &e2managererrors.RnibDbError{}, err) - writerMock.AssertExpectations(t) - readerMock.AssertExpectations(t) + writerMock.AssertCalled(t, "UpdateNodebInfoOnConnectionStatusInversion", &updatedNb1, "RanName_1_DISCONNECTED") + readerMock.AssertCalled(t, "GetE2TAddresses") + readerMock.AssertCalled(t, "GetListNodebIds") + readerMock.AssertCalled(t, "GetNodeb", "RanName_1") } func TestTwoRansGetE2TAddressesEmptyListOneUpdateNodebInfoFailure(t *testing.T) { @@ -197,8 +205,10 @@ func TestTwoRansGetE2TAddressesEmptyListOneUpdateNodebInfoFailure(t *testing.T) writerMock.On("UpdateNodebInfo", updatedNb2).Return(common.NewInternalError(errors.New("error"))) _, err = h.Handle(nil) assert.IsType(t, &e2managererrors.RnibDbError{}, err) - readerMock.AssertExpectations(t) - writerMock.AssertExpectations(t) + readerMock.AssertCalled(t, "GetE2TAddresses") + readerMock.AssertCalled(t, "GetListNodebIds") + readerMock.AssertCalled(t, "GetNodeb", "RanName_2") + writerMock.AssertCalled(t, "UpdateNodebInfo", updatedNb2) } func TestOneRanWithStateShutDown(t *testing.T) { diff --git a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go index 04b33d7..5565513 100644 --- a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go +++ b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go @@ -39,8 +39,21 @@ import ( ) var ( - emptyTagsToReplaceToSelfClosingTags = []string{"reject", "ignore", "transport-resource-unavailable", "om-intervention", + emptyTagsToReplaceToSelfClosingTags = []string{"reject", "ignore", "transport-resource-unavailable", "om-intervention", "request-id-unknown", "v60s", "v20s", "v10s", "v5s", "v2s", "v1s"} + gnbTypesMap = map[string]entities.GnbType{ + "gnb":entities.GnbType_GNB, + "en_gnb":entities.GnbType_EN_GNB, + } + enbTypesMap = map[string]entities.EnbType{ + "enB_macro":entities.EnbType_MACRO_ENB, + "enB_home":entities.EnbType_HOME_ENB, + "enB_shortmacro":entities.EnbType_SHORT_MACRO_ENB, + "enB_longmacro":entities.EnbType_LONG_MACRO_ENB, + "ng_enB_macro":entities.EnbType_MACRO_NG_ENB, + "ng_enB_shortmacro":entities.EnbType_SHORT_MACRO_NG_ENB, + "ng_enB_longmacro":entities.EnbType_LONG_MACRO_NG_ENB, + } ) type E2SetupRequestNotificationHandler struct { @@ -113,6 +126,10 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR } if nodebInfo, err = h.handleNewRan(ranName, e2tIpAddress, setupRequest); err != nil { + if _, ok := err.(*e2managererrors.UnknownSetupRequestRanNameError); ok { + cause := models.Cause{RicRequest: &models.CauseRic{RequestIdUnknown: &struct{}{}}} + h.handleUnsuccessfulResponse(ranName, request, cause) + } return } @@ -139,9 +156,13 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR func (h *E2SetupRequestNotificationHandler) handleNewRan(ranName string, e2tIpAddress string, setupRequest *models.E2SetupRequestMessage) (*entities.NodebInfo, error) { - nodebInfo := h.buildNodebInfo(ranName, e2tIpAddress, setupRequest) - err := h.rNibDataService.SaveNodeb(nodebInfo) + nodebInfo, err := h.buildNodebInfo(ranName, e2tIpAddress, setupRequest) + if err != nil { + h.logger.Errorf("#E2SetupRequestNotificationHandler.handleNewRan - RAN name: %s - failed building nodebInfo. Error: %s", ranName, err) + return nil, err + } + err = h.rNibDataService.SaveNodeb(nodebInfo) if err != nil { h.logger.Errorf("#E2SetupRequestNotificationHandler.handleNewRan - RAN name: %s - failed saving nodebInfo. Error: %s", ranName, err) return nil, err @@ -149,7 +170,7 @@ func (h *E2SetupRequestNotificationHandler) handleNewRan(ranName string, e2tIpAd nbIdentity := h.buildNbIdentity(ranName, setupRequest) - err = h.ranListManager.AddNbIdentity(entities.Node_GNB, nbIdentity) + err = h.ranListManager.AddNbIdentity(nodebInfo.GetNodeType(), nbIdentity) if err != nil { return nil, err @@ -159,8 +180,11 @@ func (h *E2SetupRequestNotificationHandler) handleNewRan(ranName string, e2tIpAd } func (h *E2SetupRequestNotificationHandler) setGnbFunctions(nodebInfo *entities.NodebInfo, setupRequest *models.E2SetupRequestMessage) { - ranFunctions := setupRequest.ExtractRanFunctionsList() + if nodebInfo.GetNodeType() == entities.Node_ENB { + return + } + ranFunctions := setupRequest.ExtractRanFunctionsList() if ranFunctions != nil { nodebInfo.GetGnb().RanFunctions = ranFunctions } @@ -289,17 +313,38 @@ func normalizeXml(payload []byte) []byte { return []byte(normalized) } -func (h *E2SetupRequestNotificationHandler) buildNodebInfo(ranName string, e2tAddress string, request *models.E2SetupRequestMessage) *entities.NodebInfo { +func (h *E2SetupRequestNotificationHandler) buildNodebInfo(ranName string, e2tAddress string, request *models.E2SetupRequestMessage) (*entities.NodebInfo, error) { nodebInfo := &entities.NodebInfo{ AssociatedE2TInstanceAddress: e2tAddress, RanName: ranName, - NodeType: entities.Node_GNB, - Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}}, GlobalNbId: h.buildGlobalNbId(request), + SetupFromNetwork: true, + } + err := h.setNodeTypeAndConfiguration(nodebInfo) + if err != nil { + return nil, err } - h.setGnbFunctions(nodebInfo, request) - return nodebInfo + return nodebInfo, nil +} + +func (h *E2SetupRequestNotificationHandler) setNodeTypeAndConfiguration(nodebInfo *entities.NodebInfo) error { + for k, v := range gnbTypesMap { + if strings.HasPrefix(nodebInfo.RanName, k) { + nodebInfo.NodeType = entities.Node_GNB + nodebInfo.Configuration = &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{GnbType: v}} + return nil + } + } + for k, v := range enbTypesMap { + if strings.HasPrefix(nodebInfo.RanName, k) { + nodebInfo.NodeType = entities.Node_ENB + nodebInfo.Configuration = &entities.NodebInfo_Enb{Enb: &entities.Enb{EnbType: v}} + return nil + } + } + + return e2managererrors.NewUnknownSetupRequestRanNameError(nodebInfo.RanName) } func (h *E2SetupRequestNotificationHandler) buildGlobalNbId(setupRequest *models.E2SetupRequestMessage) *entities.GlobalNbId { diff --git a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go index a52e8f5..f0af881 100644 --- a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go +++ b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go @@ -42,7 +42,8 @@ import ( const ( e2tInstanceFullAddress = "10.0.2.15:9999" e2SetupMsgPrefix = e2tInstanceFullAddress + "|" - nodebRanName = "gnb:310-410-b5c67788" + gnbNodebRanName = "gnb:310-410-b5c67788" + enbNodebRanName = "enB_macro:P310-410-b5c67788" GnbSetupRequestXmlPath = "../../tests/resources/setupRequest_gnb.xml" EnGnbSetupRequestXmlPath = "../../tests/resources/setupRequest_en-gNB.xml" NgEnbSetupRequestXmlPath = "../../tests/resources/setupRequest_ng-eNB.xml" @@ -50,6 +51,7 @@ const ( GnbWithoutFunctionsSetupRequestXmlPath = "../../tests/resources/setupRequest_gnb_without_functions.xml" E2SetupFailureResponseWithMiscCause = "1131" E2SetupFailureResponseWithTransportCause = "1131" + E2SetupFailureResponseWithRicCause = "1131" StateChangeMessageChannel = "RAN_CONNECTION_STATUS_CHANGE" ) @@ -129,7 +131,7 @@ func TestE2SetupRequestNotificationHandler_GetGeneralConfigurationFailure(t *tes xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath) handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t) readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{}, common.NewInternalError(errors.New("some error"))) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} handler.Handle(notificationRequest) rmrMessengerMock.AssertNotCalled(t, "SendMsg") e2tInstancesManagerMock.AssertNotCalled(t, "GetE2TInstance") @@ -138,9 +140,9 @@ func TestE2SetupRequestNotificationHandler_GetGeneralConfigurationFailure(t *tes writerMock.AssertNotCalled(t, "SaveNodeb") } -func getMbuf(msgType int, payloadStr string, request *models.NotificationRequest) *rmrCgo.MBuf { +func getMbuf(ranName string, msgType int, payloadStr string, request *models.NotificationRequest) *rmrCgo.MBuf { payload := []byte(payloadStr) - mbuf := rmrCgo.NewMBuf(msgType, len(payload), nodebRanName, &payload, &request.TransactionId, request.GetMsgSrc()) + mbuf := rmrCgo.NewMBuf(msgType, len(payload), ranName, &payload, &request.TransactionId, request.GetMsgSrc()) return mbuf } @@ -148,8 +150,8 @@ func TestE2SetupRequestNotificationHandler_EnableRicFalse(t *testing.T) { xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath) handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t) readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: false}, nil) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} - mbuf := getMbuf(rmrCgo.RIC_E2_SETUP_FAILURE, E2SetupFailureResponseWithMiscCause, notificationRequest) + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} + mbuf := getMbuf(gnbNodebRanName, rmrCgo.RIC_E2_SETUP_FAILURE, E2SetupFailureResponseWithMiscCause, notificationRequest) rmrMessengerMock.On("WhSendMsg", mbuf, true).Return(&rmrCgo.MBuf{}, nil) handler.Handle(notificationRequest) rmrMessengerMock.AssertCalled(t, "WhSendMsg", mbuf, true) @@ -159,16 +161,15 @@ func TestE2SetupRequestNotificationHandler_EnableRicFalse(t *testing.T) { writerMock.AssertNotCalled(t, "SaveNodeb") } - func TestE2SetupRequestNotificationHandler_HandleNewRanSaveNodebFailure(t *testing.T) { xml := readXmlFile(t, GnbSetupRequestXmlPath) handler, readerMock, writerMock, _, e2tInstancesManagerMock, _ := initMocks(t) readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil) e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil) var gnb *entities.NodebInfo - readerMock.On("GetNodeb", nodebRanName).Return(gnb, common.NewResourceNotFoundError("Not found")) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xml...)} - nodebInfo := getExpectedNodebForNewRan(notificationRequest.Payload) + readerMock.On("GetNodeb", gnbNodebRanName).Return(gnb, common.NewResourceNotFoundError("Not found")) + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xml...)} + nodebInfo := getExpectedGnbNodebForNewRan(notificationRequest.Payload) writerMock.On("SaveNodeb", nodebInfo).Return(common.NewInternalError(errors.New("error"))) handler.Handle(notificationRequest) @@ -177,17 +178,36 @@ func TestE2SetupRequestNotificationHandler_HandleNewRanSaveNodebFailure(t *testi e2tInstancesManagerMock.AssertExpectations(t) } +func TestE2SetupRequestNotificationHandler_HandleNewRan_invalidRanName(t *testing.T) { + xml := readXmlFile(t, EnbSetupRequestXmlPath) + handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, _ := initMocks(t) + readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil) + e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil) + var enb *entities.NodebInfo + invalidEnbRanName := "enB-macro:P310-410-b5c67788" + readerMock.On("GetNodeb", invalidEnbRanName).Return(enb, common.NewResourceNotFoundError("Not found")) + notificationRequest := &models.NotificationRequest{RanName: invalidEnbRanName, Payload: append([]byte(e2SetupMsgPrefix), xml...)} + mbuf := getMbuf(invalidEnbRanName, rmrCgo.RIC_E2_SETUP_FAILURE, E2SetupFailureResponseWithRicCause, notificationRequest) + rmrMessengerMock.On("WhSendMsg", mbuf, true).Return(&rmrCgo.MBuf{}, nil) + handler.Handle(notificationRequest) + + readerMock.AssertExpectations(t) + writerMock.AssertExpectations(t) + rmrMessengerMock.AssertCalled(t, "WhSendMsg", mbuf, true) + e2tInstancesManagerMock.AssertExpectations(t) +} + func TestE2SetupRequestNotificationHandler_HandleNewRanAddNbIdentityFailure(t *testing.T) { xml := readXmlFile(t, GnbSetupRequestXmlPath) handler, readerMock, writerMock, _, e2tInstancesManagerMock, _ := initMocks(t) readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil) e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil) var gnb *entities.NodebInfo - readerMock.On("GetNodeb", nodebRanName).Return(gnb, common.NewResourceNotFoundError("Not found")) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xml...)} - nodebInfo := getExpectedNodebForNewRan(notificationRequest.Payload) + readerMock.On("GetNodeb", gnbNodebRanName).Return(gnb, common.NewResourceNotFoundError("Not found")) + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xml...)} + nodebInfo := getExpectedGnbNodebForNewRan(notificationRequest.Payload) writerMock.On("SaveNodeb", nodebInfo).Return(nil) - nbIdentity := &entities.NbIdentity{InventoryName: nodebRanName, GlobalNbId: nodebInfo.GlobalNbId} + nbIdentity := &entities.NbIdentity{InventoryName: gnbNodebRanName, GlobalNbId: nodebInfo.GlobalNbId} writerMock.On("AddNbIdentity", entities.Node_GNB, nbIdentity).Return(common.NewInternalError(errors.New("error"))) handler.Handle(notificationRequest) readerMock.AssertExpectations(t) @@ -195,27 +215,38 @@ func TestE2SetupRequestNotificationHandler_HandleNewRanAddNbIdentityFailure(t *t e2tInstancesManagerMock.AssertExpectations(t) } -func testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t *testing.T, xmlPath string) { +func testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t *testing.T, xmlPath string, nodeType entities.Node_Type) { xml := readXmlFile(t, xmlPath) + var ranName string + if nodeType == entities.Node_GNB { + ranName = gnbNodebRanName + } else { + ranName = enbNodebRanName + } handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t) readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil) e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil) var gnb *entities.NodebInfo - readerMock.On("GetNodeb", nodebRanName).Return(gnb, common.NewResourceNotFoundError("Not found")) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xml...)} - nodebInfo := getExpectedNodebForNewRan(notificationRequest.Payload) - writerMock.On("SaveNodeb", nodebInfo).Return(nil) - nbIdentity := &entities.NbIdentity{InventoryName: nodebRanName, GlobalNbId: nodebInfo.GlobalNbId} - writerMock.On("AddNbIdentity", entities.Node_GNB, nbIdentity).Return(nil) - updatedNodebInfo := *nodebInfo + readerMock.On("GetNodeb", ranName).Return(gnb, common.NewResourceNotFoundError("Not found")) + notificationRequest := &models.NotificationRequest{RanName: ranName, Payload: append([]byte(e2SetupMsgPrefix), xml...)} + var expectedNodebInfo *entities.NodebInfo + if nodeType == entities.Node_GNB { + expectedNodebInfo = getExpectedGnbNodebForNewRan(notificationRequest.Payload) + } else { + expectedNodebInfo = getExpectedEnbNodebForNewRan(notificationRequest.Payload) + } + writerMock.On("SaveNodeb", expectedNodebInfo).Return(nil) + nbIdentity := &entities.NbIdentity{InventoryName: ranName, GlobalNbId: expectedNodebInfo.GlobalNbId} + writerMock.On("AddNbIdentity", nodeType, nbIdentity).Return(nil) + updatedNodebInfo := *expectedNodebInfo updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTED - writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo, nodebRanName+"_CONNECTED").Return(nil) + writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo, ranName+"_CONNECTED").Return(nil) routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceFullAddress, mock.Anything).Return(nil) - updatedNodebInfo2 := *nodebInfo + updatedNodebInfo2 := *expectedNodebInfo updatedNodebInfo2.ConnectionStatus = entities.ConnectionStatus_CONNECTED updatedNodebInfo2.AssociatedE2TInstanceAddress = e2tInstanceFullAddress writerMock.On("UpdateNodebInfo", &updatedNodebInfo2).Return(nil) - e2tInstancesManagerMock.On("AddRansToInstance", e2tInstanceFullAddress, []string{nodebRanName}).Return(nil) + e2tInstancesManagerMock.On("AddRansToInstance", e2tInstanceFullAddress, []string{ranName}).Return(nil) rmrMessengerMock.On("SendMsg", mock.Anything, mock.Anything).Return(&rmrCgo.MBuf{}, nil) handler.Handle(notificationRequest) @@ -225,22 +256,36 @@ func testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t *testing.T, xml e2tInstancesManagerMock.AssertExpectations(t) } - - func TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess(t *testing.T) { - testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t, GnbSetupRequestXmlPath) + testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t, GnbSetupRequestXmlPath, entities.Node_GNB) } func TestE2SetupRequestNotificationHandler_HandleNewGnbWithoutFunctionsSuccess(t *testing.T) { - testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t, GnbWithoutFunctionsSetupRequestXmlPath) + testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t, GnbWithoutFunctionsSetupRequestXmlPath, entities.Node_GNB) } func TestE2SetupRequestNotificationHandler_HandleNewEnGnbSuccess(t *testing.T) { - testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t, EnGnbSetupRequestXmlPath) + testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t, EnGnbSetupRequestXmlPath, entities.Node_GNB) } func TestE2SetupRequestNotificationHandler_HandleNewNgEnbSuccess(t *testing.T) { - testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t, NgEnbSetupRequestXmlPath) + testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t, NgEnbSetupRequestXmlPath, entities.Node_ENB) +} + +func TestExtractionOfNodeTypeFromRanName(t *testing.T) { + handler, _, _, _, _, _ := initMocks(t) + validRanNames := []string {"gnb_P310_410_b5c67788","en_gnb_P310_410_b5c67788","ng_enB_macro_P310_410_b5c67788","ng_enB_shortmacro_P310_410_b5c67788","ng_enB_longmacro_P310_410_b5c67788","enB_macro_P310_410_b5c67788","enB_home_P310_410_b5c67788","enB_shortmacro_P310_410_b5c67788","enB_longmacro_P310_410_b5c67788"} + for _,v := range validRanNames { + nodeb := &entities.NodebInfo{RanName: v} + err := handler.setNodeTypeAndConfiguration(nodeb) + assert.Nil(t, err) + } + inValidRanNames := []string {"P310_410_b5c67788","blabla_P310_410_b5c67788","ng_enB-macro_P310_410_b5c67788","ng_enb_shortmacro_P310_410_b5c67788","ng_enB-longmacro_P310_410_b5c67788","enB_new_macro_P310_410_b5c67788"} + for _,v := range inValidRanNames { + nodeb := &entities.NodebInfo{RanName: v} + err := handler.setNodeTypeAndConfiguration(nodeb) + assert.NotNil(t, err, v) + } } func testE2SetupRequestNotificationHandler_HandleExistingConnectedGnbSuccess(t *testing.T, withFunctions bool) { @@ -249,7 +294,7 @@ func testE2SetupRequestNotificationHandler_HandleExistingConnectedGnbSuccess(t * readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil) e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil) var nodebInfo = &entities.NodebInfo{ - RanName: nodebRanName, + RanName: gnbNodebRanName, AssociatedE2TInstanceAddress: e2tInstanceFullAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, NodeType: entities.Node_GNB, @@ -261,13 +306,13 @@ func testE2SetupRequestNotificationHandler_HandleExistingConnectedGnbSuccess(t * gnb.RanFunctions = []*entities.RanFunction{{RanFunctionId: 2, RanFunctionRevision: 2}} } - readerMock.On("GetNodeb", nodebRanName).Return(nodebInfo, nil) + readerMock.On("GetNodeb", gnbNodebRanName).Return(nodebInfo, nil) routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceFullAddress, mock.Anything).Return(nil) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} gnbToUpdate := getExpectedNodebForExistingRan(*nodebInfo, notificationRequest.Payload) writerMock.On("UpdateNodebInfo", gnbToUpdate).Return(nil) - e2tInstancesManagerMock.On("AddRansToInstance", e2tInstanceFullAddress, []string{nodebRanName}).Return(nil) + e2tInstancesManagerMock.On("AddRansToInstance", e2tInstanceFullAddress, []string{gnbNodebRanName}).Return(nil) var errEmpty error rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(&rmrCgo.MBuf{}, errEmpty) handler.Handle(notificationRequest) @@ -292,27 +337,27 @@ func TestE2SetupRequestNotificationHandler_HandleExistingDisconnectedGnbSuccess( readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil) e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil) var nodebInfo = &entities.NodebInfo{ - RanName: nodebRanName, + RanName: gnbNodebRanName, AssociatedE2TInstanceAddress: e2tInstanceFullAddress, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, NodeType: entities.Node_GNB, Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}}, } - readerMock.On("GetNodeb", nodebRanName).Return(nodebInfo, nil) + readerMock.On("GetNodeb", gnbNodebRanName).Return(nodebInfo, nil) routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceFullAddress, mock.Anything).Return(nil) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} gnbToUpdate := getExpectedNodebForExistingRan(*nodebInfo, notificationRequest.Payload) writerMock.On("UpdateNodebInfo", gnbToUpdate).Return(nil) gnbToUpdate2 := *gnbToUpdate gnbToUpdate2.ConnectionStatus = entities.ConnectionStatus_CONNECTED - writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &gnbToUpdate2, nodebRanName+"_CONNECTED").Return(nil) + writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &gnbToUpdate2, gnbNodebRanName+"_CONNECTED").Return(nil) gnbToUpdate3 := *gnbToUpdate gnbToUpdate3.ConnectionStatus = entities.ConnectionStatus_CONNECTED gnbToUpdate3.AssociatedE2TInstanceAddress = e2tInstanceFullAddress writerMock.On("UpdateNodebInfo", &gnbToUpdate3).Return(nil) - e2tInstancesManagerMock.On("AddRansToInstance", e2tInstanceFullAddress, []string{nodebRanName}).Return(nil) + e2tInstancesManagerMock.On("AddRansToInstance", e2tInstanceFullAddress, []string{gnbNodebRanName}).Return(nil) var errEmpty error rmrMessengerMock.On("SendMsg", mock.Anything, mock.Anything).Return(&rmrCgo.MBuf{}, errEmpty) handler.Handle(notificationRequest) @@ -330,17 +375,19 @@ func getExpectedNodebForExistingRan(nodeb entities.NodebInfo, payload []byte) *e return &nodeb } -func getExpectedNodebForNewRan(payload []byte) *entities.NodebInfo { +func getExpectedGnbNodebForNewRan(payload []byte) *entities.NodebInfo { pipInd := bytes.IndexByte(payload, '|') setupRequest := &models.E2SetupRequestMessage{} _ = xml.Unmarshal(normalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU) nodeb := &entities.NodebInfo{ AssociatedE2TInstanceAddress: e2tInstanceFullAddress, - RanName: nodebRanName, + RanName: gnbNodebRanName, + SetupFromNetwork: true, NodeType: entities.Node_GNB, Configuration: &entities.NodebInfo_Gnb{ Gnb: &entities.Gnb{ + GnbType: entities.GnbType_GNB, RanFunctions: setupRequest.ExtractRanFunctionsList(), }, }, @@ -353,11 +400,35 @@ func getExpectedNodebForNewRan(payload []byte) *entities.NodebInfo { return nodeb } +func getExpectedEnbNodebForNewRan(payload []byte) *entities.NodebInfo { + pipInd := bytes.IndexByte(payload, '|') + setupRequest := &models.E2SetupRequestMessage{} + _ = xml.Unmarshal(normalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU) + + nodeb := &entities.NodebInfo{ + AssociatedE2TInstanceAddress: e2tInstanceFullAddress, + RanName: enbNodebRanName, + SetupFromNetwork: true, + NodeType: entities.Node_ENB, + Configuration: &entities.NodebInfo_Enb{ + Enb: &entities.Enb{ + EnbType: entities.EnbType_MACRO_ENB, + }, + }, + GlobalNbId: &entities.GlobalNbId{ + PlmnId: setupRequest.GetPlmnId(), + NbId: setupRequest.GetNbId(), + }, + } + + return nodeb +} + func TestE2SetupRequestNotificationHandler_HandleParseError(t *testing.T) { xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath) handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t) readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte("invalid_prefix"), xmlGnb...)} + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte("invalid_prefix"), xmlGnb...)} handler.Handle(notificationRequest) readerMock.AssertNotCalled(t, "GetNodeb", mock.Anything) writerMock.AssertNotCalled(t, "SaveNodeb", mock.Anything, mock.Anything) @@ -370,7 +441,7 @@ func TestE2SetupRequestNotificationHandler_HandleParseError(t *testing.T) { func TestE2SetupRequestNotificationHandler_HandleUnmarshalError(t *testing.T) { handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t) readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte(e2SetupMsgPrefix), "xmlGnb"...)} + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), "xmlGnb"...)} handler.Handle(notificationRequest) readerMock.AssertNotCalled(t, "GetNodeb", mock.Anything) writerMock.AssertNotCalled(t, "SaveNodeb", mock.Anything, mock.Anything) @@ -386,7 +457,7 @@ func TestE2SetupRequestNotificationHandler_HandleGetE2TInstanceError(t *testing. readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil) e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, common.NewResourceNotFoundError("Not found")) prefBytes := []byte(e2SetupMsgPrefix) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)} + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append(prefBytes, xmlGnb...)} handler.Handle(notificationRequest) e2tInstancesManagerMock.AssertCalled(t, "GetE2TInstance", e2tInstanceFullAddress) readerMock.AssertNotCalled(t, "GetNodeb", mock.Anything) @@ -404,7 +475,7 @@ func TestE2SetupRequestNotificationHandler_HandleGetNodebError(t *testing.T) { e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil) var gnb *entities.NodebInfo readerMock.On("GetNodeb", mock.Anything).Return(gnb, common.NewInternalError(errors.New("some error"))) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} handler.Handle(notificationRequest) e2tInstancesManagerMock.AssertCalled(t, "GetE2TInstance", e2tInstanceFullAddress) readerMock.AssertCalled(t, "GetNodeb", mock.Anything) @@ -423,22 +494,22 @@ func TestE2SetupRequestNotificationHandler_HandleAssociationError(t *testing.T) e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil) var gnb *entities.NodebInfo readerMock.On("GetNodeb", mock.Anything).Return(gnb, common.NewResourceNotFoundError("Not found")) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} - nodebInfo := getExpectedNodebForNewRan(notificationRequest.Payload) + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)} + nodebInfo := getExpectedGnbNodebForNewRan(notificationRequest.Payload) writerMock.On("SaveNodeb", nodebInfo).Return(nil) - nbIdentity := &entities.NbIdentity{InventoryName: nodebRanName, GlobalNbId: nodebInfo.GlobalNbId} + nbIdentity := &entities.NbIdentity{InventoryName: gnbNodebRanName, GlobalNbId: nodebInfo.GlobalNbId} writerMock.On("AddNbIdentity", entities.Node_GNB, nbIdentity).Return(nil) updatedNodebInfo := *nodebInfo updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTED - writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo, nodebRanName+"_CONNECTED").Return(nil) + writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo, gnbNodebRanName+"_CONNECTED").Return(nil) writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil) e2tInstancesManagerMock.On("AddRansToInstance", mock.Anything, mock.Anything).Return(nil) routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceFullAddress, mock.Anything).Return(errors.New("association error")) updatedNodebInfo2 := *nodebInfo updatedNodebInfo2.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED - writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo2, nodebRanName+"_DISCONNECTED").Return(nil) + writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo2, gnbNodebRanName+"_DISCONNECTED").Return(nil) var errEmpty error - mbuf := getMbuf(rmrCgo.RIC_E2_SETUP_FAILURE, E2SetupFailureResponseWithTransportCause, notificationRequest) + mbuf := getMbuf(gnbNodebRanName, rmrCgo.RIC_E2_SETUP_FAILURE, E2SetupFailureResponseWithTransportCause, notificationRequest) rmrMessengerMock.On("WhSendMsg", mbuf, true).Return(&rmrCgo.MBuf{}, errEmpty) handler.Handle(notificationRequest) readerMock.AssertCalled(t, "GetNodeb", mock.Anything) @@ -490,7 +561,7 @@ func TestE2SetupRequestNotificationHandler_ConvertTo20BitStringError(t *testing. rmrMessage := &rmrCgo.MBuf{} rmrMessengerMock.On("SendMsg", mock.Anything, mock.Anything).Return(rmrMessage, errEmpty) prefBytes := []byte(e2SetupMsgPrefix) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlEnGnb...)} + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append(prefBytes, xmlEnGnb...)} handler.Handle(notificationRequest) readerMock.AssertCalled(t, "GetNodeb", mock.Anything) e2tInstancesManagerMock.AssertCalled(t, "GetE2TInstance", e2tInstanceFullAddress) @@ -504,12 +575,12 @@ func TestE2SetupRequestNotificationHandler_ConvertTo20BitStringError(t *testing. func TestE2SetupRequestNotificationHandler_HandleExistingGnbInvalidStatusError(t *testing.T) { xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath) handler, readerMock, writerMock, routingManagerClientMock, e2tInstancesManagerMock, rmrMessengerMock := initMocks(t) - var gnb = &entities.NodebInfo{RanName: nodebRanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN} + var gnb = &entities.NodebInfo{RanName: gnbNodebRanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN} readerMock.On("GetNodeb", mock.Anything).Return(gnb, nil) readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil) e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil) prefBytes := []byte(e2SetupMsgPrefix) - notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)} + notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append(prefBytes, xmlGnb...)} handler.Handle(notificationRequest) readerMock.AssertCalled(t, "GetNodeb", mock.Anything) e2tInstancesManagerMock.AssertCalled(t, "GetE2TInstance", e2tInstanceFullAddress) diff --git a/E2Manager/mocks/rnibWriterMock.go b/E2Manager/mocks/rnibWriterMock.go index fa711fb..35a255a 100644 --- a/E2Manager/mocks/rnibWriterMock.go +++ b/E2Manager/mocks/rnibWriterMock.go @@ -130,3 +130,8 @@ func (rnibWriterMock *RnibWriterMock) RemoveNbIdentity(nodeType entities.Node_Ty args := rnibWriterMock.Called(nodeType, nbIdentity) return args.Error(0) } + +func (rnibWriterMock *RnibWriterMock) AddEnb(nodebInfo *entities.NodebInfo) error { + args := rnibWriterMock.Called(nodebInfo) + return args.Error(0) +} \ No newline at end of file diff --git a/E2Manager/rNibWriter/rNibWriter.go b/E2Manager/rNibWriter/rNibWriter.go index 3069258..7678fb3 100644 --- a/E2Manager/rNibWriter/rNibWriter.go +++ b/E2Manager/rNibWriter/rNibWriter.go @@ -59,6 +59,7 @@ type RNibWriter interface { UpdateEnb(nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) error AddNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error RemoveNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error + AddEnb(nodebInfo *entities.NodebInfo) error } /* @@ -166,13 +167,48 @@ func (w *rNibWriterInstance) SaveNodeb(nodebInfo *entities.NodebInfo) error { } } - if nodebInfo.GetNodeType() == entities.Node_ENB { - channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanAddedEvent) - err = w.sdl.SetAndPublish(channelsAndEvents, pairs) - } else { - err = w.sdl.Set(pairs) + err = w.sdl.Set(pairs) + + if err != nil { + return common.NewInternalError(err) } + return nil +} + +func (w *rNibWriterInstance) AddEnb(nodebInfo *entities.NodebInfo) error { + + data, err := proto.Marshal(nodebInfo) + + if err != nil { + return common.NewInternalError(err) + } + + var pairs []interface{} + key, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.RanName) + + if rNibErr != nil { + return rNibErr + } + + pairs = append(pairs, key, data) + + if nodebInfo.GlobalNbId != nil { + + key, rNibErr = common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId()) + if rNibErr != nil { + return rNibErr + } + pairs = append(pairs, key, data) + } + + pairs, rNibErr = appendEnbCells(nodebInfo.RanName, nodebInfo.GetEnb().GetServedCells(), pairs) + if rNibErr != nil { + return rNibErr + } + + channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanAddedEvent) + err = w.sdl.SetAndPublish(channelsAndEvents, pairs) if err != nil { return common.NewInternalError(err) } diff --git a/E2Manager/rNibWriter/rNibWriter_test.go b/E2Manager/rNibWriter/rNibWriter_test.go index 0c92aa8..4e0cdfc 100644 --- a/E2Manager/rNibWriter/rNibWriter_test.go +++ b/E2Manager/rNibWriter/rNibWriter_test.go @@ -379,8 +379,7 @@ func TestSaveEnb(t *testing.T) { setExpected = append(setExpected, fmt.Sprintf("CELL:%s", cell.GetCellId()), cellData) setExpected = append(setExpected, fmt.Sprintf("PCI:%s:%02x", RanName, cell.GetPci()), cellData) - sdlInstanceMock.On("SetAndPublish", []string{"RAN_MANIPULATION", RanName + "_" + RanAddedEvent}, []interface{}{setExpected}).Return(e) - + sdlInstanceMock.On("Set", []interface{}{setExpected}).Return(e) rNibErr := w.SaveNodeb(&nb) assert.Nil(t, rNibErr) } @@ -648,14 +647,23 @@ func TestSaveUnknownTypeEntityFailure(t *testing.T) { assert.IsType(t, &common.ValidationError{}, actualErr) } -func TestSaveEntityFailure(t *testing.T) { +func TestSaveEntitySetFailure(t *testing.T) { name := "name" plmnId := "02f829" nbId := "4a952a0a" w, sdlInstanceMock := initSdlInstanceMock(namespace) - gnb := entities.NodebInfo{} - gnb.NodeType = entities.Node_GNB + gnb := entities.NodebInfo{ + RanName: name, + NodeType: entities.Node_GNB, + ConnectionStatus: 1, + GlobalNbId: &entities.GlobalNbId{ + NbId: nbId, + PlmnId: plmnId, + }, + Ip: "localhost", + Port: 5656, + } data, err := proto.Marshal(&gnb) if err != nil { t.Errorf("#rNibWriter_test.TestSaveEntityFailure - Failed to marshal NodeB entity. Error: %v", err) @@ -668,6 +676,35 @@ func TestSaveEntityFailure(t *testing.T) { assert.NotEmpty(t, rNibErr) } +func TestSaveEntitySetAndPublishFailure(t *testing.T) { + name := "name" + plmnId := "02f829" + nbId := "4a952a0a" + + w, sdlInstanceMock := initSdlInstanceMock(namespace) + enb := entities.NodebInfo{ + RanName: name, + NodeType: entities.Node_ENB, + ConnectionStatus: 1, + GlobalNbId: &entities.GlobalNbId{ + NbId: nbId, + PlmnId: plmnId, + }, + Ip: "localhost", + Port: 5656, + } + data, err := proto.Marshal(&enb) + if err != nil { + t.Errorf("#rNibWriter_test.TestSaveEntityFailure - Failed to marshal NodeB entity. Error: %v", err) + } + setExpected := []interface{}{"RAN:" + name, data} + setExpected = append(setExpected, "ENB:"+plmnId+":"+nbId, data) + expectedErr := errors.New("expected error") + sdlInstanceMock.On("SetAndPublish", []string{"RAN_MANIPULATION", name + "_" + RanAddedEvent}, []interface{}{setExpected}).Return(expectedErr) + rNibErr := w.AddEnb(&enb) + assert.NotEmpty(t, rNibErr) +} + func TestGetRNibWriter(t *testing.T) { received, _ := initSdlInstanceMock(namespace) assert.NotEmpty(t, received) @@ -1105,6 +1142,88 @@ func TestRemoveNbIdentityError(t *testing.T) { sdlInstanceMock.AssertExpectations(t) } +func TestAddEnb(t *testing.T) { + ranName := "RAN:" + RanName + w, sdlInstanceMock := initSdlInstanceMock(namespace) + nb := entities.NodebInfo{ + RanName: RanName, + NodeType: entities.Node_ENB, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + Ip: "localhost", + Port: 5656, + GlobalNbId: &entities.GlobalNbId{ + NbId: "4a952a0a", + PlmnId: "02f829", + }, + } + + enb := entities.Enb{} + cell := &entities.ServedCellInfo{CellId: "aaff", Pci: 3} + cellEntity := entities.Cell{Type: entities.Cell_LTE_CELL, Cell: &entities.Cell_ServedCellInfo{ServedCellInfo: cell}} + enb.ServedCells = []*entities.ServedCellInfo{cell} + nb.Configuration = &entities.NodebInfo_Enb{Enb: &enb} + data, err := proto.Marshal(&nb) + if err != nil { + t.Errorf("#rNibWriter_test.TestSaveEnb - Failed to marshal NodeB entity. Error: %v", err) + } + var e error + + cellData, err := proto.Marshal(&cellEntity) + if err != nil { + t.Errorf("#rNibWriter_test.TestSaveEnb - Failed to marshal Cell entity. Error: %v", err) + } + var setExpected []interface{} + setExpected = append(setExpected, ranName, data) + setExpected = append(setExpected, "ENB:02f829:4a952a0a", data) + setExpected = append(setExpected, fmt.Sprintf("CELL:%s", cell.GetCellId()), cellData) + setExpected = append(setExpected, fmt.Sprintf("PCI:%s:%02x", RanName, cell.GetPci()), cellData) + + sdlInstanceMock.On("SetAndPublish", []string{"RAN_MANIPULATION", RanName + "_" + RanAddedEvent}, []interface{}{setExpected}).Return(e) + + rNibErr := w.AddEnb(&nb) + assert.Nil(t, rNibErr) +} + +func TestAddEnbCellIdValidationFailure(t *testing.T) { + w, _ := initSdlInstanceMock(namespace) + nb := entities.NodebInfo{} + nb.RanName = "name" + nb.NodeType = entities.Node_ENB + nb.ConnectionStatus = 1 + nb.Ip = "localhost" + nb.Port = 5656 + enb := entities.Enb{} + cell := &entities.ServedCellInfo{Pci: 3} + enb.ServedCells = []*entities.ServedCellInfo{cell} + nb.Configuration = &entities.NodebInfo_Enb{Enb: &enb} + rNibErr := w.AddEnb(&nb) + assert.NotNil(t, rNibErr) + assert.IsType(t, &common.ValidationError{}, rNibErr) + assert.Equal(t, "#utils.ValidateAndBuildCellIdKey - an empty cell id received", rNibErr.Error()) +} + +func TestAddEnbInventoryNameValidationFailure(t *testing.T) { + w, _ := initSdlInstanceMock(namespace) + nb := entities.NodebInfo{ + NodeType: entities.Node_ENB, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + Ip: "localhost", + Port: 5656, + GlobalNbId: &entities.GlobalNbId{ + NbId: "4a952a0a", + PlmnId: "02f829", + }, + } + enb := entities.Enb{} + cell := &entities.ServedCellInfo{CellId: "aaa", Pci: 3} + enb.ServedCells = []*entities.ServedCellInfo{cell} + nb.Configuration = &entities.NodebInfo_Enb{Enb: &enb} + rNibErr := w.AddEnb(&nb) + assert.NotNil(t, rNibErr) + assert.IsType(t, &common.ValidationError{}, rNibErr) + assert.Equal(t, "#utils.ValidateAndBuildNodeBNameKey - an empty inventory name received", rNibErr.Error()) +} + //Integration tests // //func TestSaveEnbGnbInteg(t *testing.T){ diff --git a/E2Manager/services/rnib_data_service.go b/E2Manager/services/rnib_data_service.go index 7125271..7d3d6c5 100644 --- a/E2Manager/services/rnib_data_service.go +++ b/E2Manager/services/rnib_data_service.go @@ -57,6 +57,7 @@ type RNibDataService interface { UpdateEnb(nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) error AddNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error RemoveNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error + AddEnb(nodebInfo *entities.NodebInfo) error } type rNibDataService struct { @@ -368,6 +369,17 @@ func (w *rNibDataService) UpdateNodebInfoOnConnectionStatusInversion(nodebInfo * return err } +func (w *rNibDataService) AddEnb(nodebInfo *entities.NodebInfo) error { + w.logger.Infof("#RnibDataService.AddEnb - nodebInfo: %s", nodebInfo) + + err := w.retry("AddEnb", func() (err error) { + err = w.rnibWriter.AddEnb(nodebInfo) + return + }) + + return err +} + func (w *rNibDataService) retry(rnibFunc string, f func() error) (err error) { attempts := w.maxAttempts