RIC-432 - Support Update eNB REST API 76/4376/1
authorIrina <ib565x@intl.att.com>
Mon, 13 Jul 2020 10:15:03 +0000 (13:15 +0300)
committerIrina <ib565x@intl.att.com>
Mon, 13 Jul 2020 10:15:17 +0000 (13:15 +0300)
Change-Id: I024eef6c21fb3a74c3fbc8351701a1e8ecae63bc
Signed-off-by: Irina <ib565x@intl.att.com>
E2Manager/container-tag.yaml
E2Manager/controllers/nodeb_controller.go
E2Manager/controllers/nodeb_controller_test.go
E2Manager/handlers/httpmsghandlers/update_nodeb_request_handler.go
E2Manager/managers/i_update_nodeb_manager.go
E2Manager/managers/update_enb_manager.go
E2Manager/models/update_enb_request.go
E2Manager/models/update_nodeb_request.go [deleted file]
E2Manager/rNibWriter/rNibWriter_test.go

index 91e8f86..6c99a8d 100644 (file)
@@ -1,4 +1,4 @@
 # The Jenkins job requires a tag to build the Docker image.
 # Global-JJB script assumes this file is in the repo root.
 ---
-tag: 5.2.10
+tag: 5.2.11
index 71b1160..809c5b3 100644 (file)
@@ -101,20 +101,31 @@ func (c *NodebController) UpdateGnb(writer http.ResponseWriter, r *http.Request)
 
 func (c *NodebController) UpdateEnb(writer http.ResponseWriter, r *http.Request) {
        c.logger.Infof("[Client -> E2 Manager] #NodebController.UpdateEnb - request: %v", c.prettifyRequest(r))
-       vars := mux.Vars(r)
-       ranName := vars[ParamRanName]
 
-       request := models.UpdateNodebRequest{}
+       defer r.Body.Close()
+       body, err := ioutil.ReadAll(r.Body)
+
+       if err != nil {
+               c.logger.Errorf("[Client -> E2 Manager] #NodebController.UpdateEnb - unable to read request body - error: %s", err)
+               c.handleErrorResponse(e2managererrors.NewInvalidJsonError(), writer)
+               return
+       }
 
-       enb := entities.Enb{}
+       updateEnbRequest := models.UpdateEnbRequest{}
+       err = json.Unmarshal(body, &updateEnbRequest)
 
-       if !c.extractRequestBodyToProto(r, &enb, writer) {
+       if err != nil {
+               c.logger.Errorf("[Client -> E2 Manager] #NodebController.UpdateEnb - unable to unmarshal json - error: %s", err)
+               c.handleErrorResponse(e2managererrors.NewInvalidJsonError(), writer)
                return
        }
 
-       request.Enb = &enb
-       request.RanName = ranName
-       c.handleRequest(writer, &r.Header, httpmsghandlerprovider.UpdateEnbRequest, request, true, http.StatusOK)
+       vars := mux.Vars(r)
+       ranName := vars[ParamRanName]
+
+       updateEnbRequest.RanName = ranName
+
+       c.handleRequest(writer, &r.Header, httpmsghandlerprovider.UpdateEnbRequest, &updateEnbRequest, true, http.StatusOK)
 }
 
 func (c *NodebController) AddEnb(writer http.ResponseWriter, r *http.Request) {
index d128dad..79df8ce 100644 (file)
@@ -67,6 +67,7 @@ var (
        ServedNrCellInformationRequiredFields = []string{"cellId", "choiceNrMode", "nrMode", "servedPlmns"}
        NrNeighbourInformationRequiredFields  = []string{"nrCgi", "choiceNrMode", "nrMode"}
        AddEnbRequestRequiredFields           = []string{"ranName", "enb", "globalNbId"}
+       UpdateEnbRequestRequiredFields        = []string{"enb"}
        GlobalIdRequiredFields                = []string{"plmnId", "nbId"}
        EnbRequiredFields                     = []string{"enbType", "servedCells"}
        ServedCellRequiredFields              = []string{"broadcastPlmns", "cellId", "choiceEutraMode", "eutraMode", "tac"}
@@ -96,17 +97,35 @@ type updateGnbCellsParams struct {
        err error
 }
 
+type updateEnbCellsParams struct {
+       err error
+}
+
 type saveNodebParams struct {
        nodebInfo  *entities.NodebInfo
        nbIdentity *entities.NbIdentity
        err        error
 }
 
+type removeServedCellsParams struct {
+       servedCellInfo []*entities.ServedCellInfo
+       err            error
+}
+
 type removeServedNrCellsParams struct {
        servedNrCells []*entities.ServedNRCell
        err           error
 }
 
+type controllerUpdateEnbTestContext struct {
+       getNodebInfoResult      *getNodebInfoResult
+       removeServedCellsParams *removeServedCellsParams
+       updateEnbCellsParams    *updateEnbCellsParams
+       requestBody             map[string]interface{}
+       expectedStatusCode      int
+       expectedJsonResponse    string
+}
+
 type controllerUpdateGnbTestContext struct {
        getNodebInfoResult        *getNodebInfoResult
        removeServedNrCellsParams *removeServedNrCellsParams
@@ -151,6 +170,24 @@ func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell {
        return servedNrCells
 }
 
+func generateServedCells(cellIds ...string) []*entities.ServedCellInfo {
+
+       var servedCells []*entities.ServedCellInfo
+
+       for i, v := range cellIds {
+               servedCells = append(servedCells, &entities.ServedCellInfo{
+                       CellId: v,
+                       ChoiceEutraMode: &entities.ChoiceEUTRAMode{
+                               Fdd: &entities.FddInfo{},
+                       },
+                       Pci:            uint32(i + 1),
+                       BroadcastPlmns: []string{"whatever"},
+               })
+       }
+
+       return servedCells
+}
+
 func buildNrNeighbourInformation(propToOmit string) map[string]interface{} {
        ret := map[string]interface{}{
                "nrCgi": "whatever",
@@ -209,6 +246,19 @@ func buildServedCell(propToOmit string) map[string]interface{} {
        return ret
 }
 
+func getUpdateEnbRequest(propToOmit string) map[string]interface{} {
+       ret := map[string]interface{}{
+               "enb":        buildEnb(propToOmit),
+       }
+
+       if len(propToOmit) != 0 {
+               delete(ret, propToOmit)
+       }
+
+       return ret
+}
+
+
 func getAddEnbRequest(propToOmit string) map[string]interface{} {
        ret := map[string]interface{}{
                "ranName":    RanName,
@@ -345,6 +395,23 @@ func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNo
        assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
 }
 
+func activateControllerUpdateEnbMocks(context *controllerUpdateEnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock,updateEnbRequest *models.UpdateEnbRequest) {
+       if context.getNodebInfoResult != nil {
+               readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
+       }
+
+       if context.removeServedCellsParams != nil {
+               writerMock.On("RemoveServedCells", RanName, context.removeServedCellsParams.servedCellInfo).Return(context.removeServedCellsParams.err)
+       }
+
+       if context.updateEnbCellsParams != nil {
+               updatedNodebInfo := *context.getNodebInfoResult.nodebInfo
+               updatedNodebInfo.Configuration = &entities.NodebInfo_Enb{Enb: updateEnbRequest.Enb}
+
+               writerMock.On("UpdateEnb", &updatedNodebInfo, updateEnbRequest.Enb.ServedCells).Return(context.updateEnbCellsParams.err)
+       }
+}
+
 func activateControllerUpdateGnbMocks(context *controllerUpdateGnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
        if context.getNodebInfoResult != nil {
                readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
@@ -372,6 +439,14 @@ func assertControllerUpdateGnb(t *testing.T, context *controllerUpdateGnbTestCon
        writerMock.AssertExpectations(t)
 }
 
+func assertControllerUpdateEnb(t *testing.T, context *controllerUpdateEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
+       assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
+       bodyBytes, _ := ioutil.ReadAll(writer.Body)
+       assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
+       readerMock.AssertExpectations(t)
+       writerMock.AssertExpectations(t)
+}
+
 func assertControllerAddEnb(t *testing.T, context *controllerAddEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
        assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
        bodyBytes, _ := ioutil.ReadAll(writer.Body)
@@ -388,6 +463,15 @@ func assertControllerDeleteEnb(t *testing.T, context *controllerDeleteEnbTestCon
        writerMock.AssertExpectations(t)
 }
 
+func buildUpdateEnbRequest(context *controllerUpdateEnbTestContext) *http.Request {
+       updateEnbUrl := fmt.Sprintf("/nodeb/enb/%s", RanName)
+       requestBody := getJsonRequestAsBuffer(context.requestBody)
+       req, _ := http.NewRequest(http.MethodPut, updateEnbUrl, requestBody)
+       req.Header.Set("Content-Type", "application/json")
+       req = mux.SetURLVars(req, map[string]string{"ranName": RanName})
+       return req
+}
+
 func buildUpdateGnbRequest(context *controllerUpdateGnbTestContext) *http.Request {
        updateGnbUrl := fmt.Sprintf("/nodeb/%s/update", RanName)
        requestBody := getJsonRequestAsBuffer(context.requestBody)
@@ -404,6 +488,25 @@ func buildAddEnbRequest(context *controllerAddEnbTestContext) *http.Request {
        return req
 }
 
+func controllerUpdateEnbTestExecuter(t *testing.T, context *controllerUpdateEnbTestContext) {
+       controller, readerMock, writerMock, _, _ := setupControllerTest(t)
+       writer := httptest.NewRecorder()
+
+       r := buildUpdateEnbRequest(context)
+       body, _ := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest))
+
+       updateEnbRequest := models.UpdateEnbRequest{}
+       _ = json.Unmarshal(body, &updateEnbRequest)
+
+       activateControllerUpdateEnbMocks(context, readerMock, writerMock, &updateEnbRequest)
+       r = buildUpdateEnbRequest(context)
+       defer r.Body.Close()
+
+       controller.UpdateEnb(writer, r)
+
+       assertControllerUpdateEnb(t, context, writer, readerMock, writerMock)
+}
+
 func controllerUpdateGnbTestExecuter(t *testing.T, context *controllerUpdateGnbTestContext) {
        controller, readerMock, writerMock, _, _ := setupControllerTest(t)
        writer := httptest.NewRecorder()
@@ -752,6 +855,187 @@ func TestControllerUpdateGnbSuccess(t *testing.T) {
        controllerUpdateGnbTestExecuter(t, &context)
 }
 
+func TestControllerUpdateEnbInvalidRequest(t *testing.T) {
+       controller, _, _, _, _ := setupControllerTest(t)
+
+       writer := httptest.NewRecorder()
+       invalidJson := strings.NewReader("{enb:\"whatever\"")
+
+       updateEnbUrl := fmt.Sprintf("/nodeb/enb/%s", RanName)
+       req, _ := http.NewRequest(http.MethodPut, updateEnbUrl, invalidJson)
+       req.Header.Set("Content-Type", "application/json")
+       req = mux.SetURLVars(req, map[string]string{"ranName": RanName})
+
+       controller.UpdateEnb(writer, req)
+
+       assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
+       bodyBytes, _ := ioutil.ReadAll(writer.Body)
+       assert.Equal(t, CorruptedJson, string(bodyBytes))
+}
+
+func TestControllerUpdateEnbEmptyEnbType(t *testing.T) {
+       context := controllerUpdateEnbTestContext{
+               getNodebInfoResult: nil,
+               requestBody: getUpdateEnbRequest(EnbRequiredFields[0]),
+               expectedStatusCode:   http.StatusBadRequest,
+               expectedJsonResponse: ValidationFailureJson,
+       }
+
+       controllerUpdateEnbTestExecuter(t, &context)
+}
+
+func TestControllerUpdateEnbEmptyServedCells(t *testing.T) {
+       context := controllerUpdateEnbTestContext{
+               getNodebInfoResult: nil,
+               requestBody: getUpdateEnbRequest(EnbRequiredFields[1]),
+               expectedStatusCode:   http.StatusBadRequest,
+               expectedJsonResponse: ValidationFailureJson,
+       }
+
+       controllerUpdateEnbTestExecuter(t, &context)
+}
+
+func TestControllerUpdateEnbMissingEnb(t *testing.T) {
+       context := controllerUpdateEnbTestContext{
+               getNodebInfoResult: nil,
+               requestBody: getUpdateEnbRequest(UpdateEnbRequestRequiredFields[0]),
+               expectedStatusCode:   http.StatusBadRequest,
+               expectedJsonResponse: ValidationFailureJson,
+       }
+
+       controllerUpdateEnbTestExecuter(t, &context)
+}
+
+func TestControllerUpdateEnbValidServedCellsGetNodebNotFound(t *testing.T) {
+       context := controllerUpdateEnbTestContext{
+               getNodebInfoResult: &getNodebInfoResult{
+                       nodebInfo: nil,
+                       rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
+               },
+               requestBody: getUpdateEnbRequest(""),
+               expectedStatusCode:   http.StatusNotFound,
+               expectedJsonResponse: ResourceNotFoundJson,
+       }
+
+       controllerUpdateEnbTestExecuter(t, &context)
+}
+
+func TestControllerUpdateEnbValidServedCellsGetNodebInternalError(t *testing.T) {
+       context := controllerUpdateEnbTestContext{
+               getNodebInfoResult: &getNodebInfoResult{
+                       nodebInfo: nil,
+                       rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
+               },
+               requestBody: getUpdateEnbRequest(""),
+               expectedStatusCode:   http.StatusInternalServerError,
+               expectedJsonResponse: RnibErrorJson,
+       }
+
+       controllerUpdateEnbTestExecuter(t, &context)
+}
+
+func TestControllerUpdateEnbGetNodebSuccessGnbTypeFailure(t *testing.T) {
+       oldServedCells := generateServedCells("whatever1", "whatever2")
+       context := controllerUpdateEnbTestContext{
+               getNodebInfoResult: &getNodebInfoResult{
+                       nodebInfo: &entities.NodebInfo{
+                               RanName:                      RanName,
+                               ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
+                               AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
+                               NodeType:                     entities.Node_GNB,
+                               Configuration:                &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells}},
+                       },
+                       rnibError: nil,
+               },
+               requestBody: getUpdateEnbRequest(""),
+               expectedStatusCode:   http.StatusBadRequest,
+               expectedJsonResponse: ValidationFailureJson,
+       }
+
+       controllerUpdateEnbTestExecuter(t, &context)
+}
+
+func TestControllerUpdateEnbGetNodebSuccessRemoveServedCellsFailure(t *testing.T) {
+       oldServedCells := generateServedCells("whatever1", "whatever2")
+       context := controllerUpdateEnbTestContext{
+               removeServedCellsParams: &removeServedCellsParams{
+                       err:            common.NewInternalError(errors.New("#writer.RemoveServedCells - Internal Error")),
+                       servedCellInfo: oldServedCells,
+               },
+               getNodebInfoResult: &getNodebInfoResult{
+                       nodebInfo: &entities.NodebInfo{
+                               RanName:                      RanName,
+                               ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
+                               AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
+                               NodeType:                     entities.Node_ENB,
+                               Configuration:                &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells}},
+                       },
+                       rnibError: nil,
+               },
+               requestBody: getUpdateEnbRequest(""),
+               expectedStatusCode:   http.StatusInternalServerError,
+               expectedJsonResponse: RnibErrorJson,
+       }
+
+       controllerUpdateEnbTestExecuter(t, &context)
+}
+
+func TestControllerUpdateEnbGetNodebSuccessUpdateEnbFailure(t *testing.T) {
+       oldServedCells := generateServedCells("whatever1", "whatever2")
+       context := controllerUpdateEnbTestContext{
+               removeServedCellsParams: &removeServedCellsParams{
+                       err:           nil,
+                       servedCellInfo: oldServedCells,
+               },
+               updateEnbCellsParams: &updateEnbCellsParams{
+                       err: common.NewInternalError(errors.New("#writer.UpdateEnb - Internal Error")),
+               },
+               getNodebInfoResult: &getNodebInfoResult{
+                       nodebInfo: &entities.NodebInfo{
+                               RanName:                      RanName,
+                               ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
+                               AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
+                               NodeType:                     entities.Node_ENB,
+                               Configuration:                &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells, EnbType: entities.EnbType_MACRO_ENB}},
+                       },
+                       rnibError: nil,
+               },
+               requestBody: getUpdateEnbRequest(""),
+               expectedStatusCode:   http.StatusInternalServerError,
+               expectedJsonResponse: RnibErrorJson,
+       }
+
+       controllerUpdateEnbTestExecuter(t, &context)
+}
+
+func TestControllerUpdateEnbSuccess(t *testing.T) {
+       oldServedCells := generateServedCells("whatever1", "whatever2")
+       context := controllerUpdateEnbTestContext{
+               removeServedCellsParams: &removeServedCellsParams{
+                       err:           nil,
+                       servedCellInfo: oldServedCells,
+               },
+               updateEnbCellsParams: &updateEnbCellsParams{
+                       err: nil,
+               },
+               getNodebInfoResult: &getNodebInfoResult{
+                       nodebInfo: &entities.NodebInfo{
+                               RanName:                      RanName,
+                               ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
+                               AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
+                               NodeType:                     entities.Node_ENB,
+                               Configuration:                &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells, EnbType: entities.EnbType_MACRO_ENB}},
+                       },
+                       rnibError: nil,
+               },
+               requestBody: getUpdateEnbRequest(""),
+               expectedStatusCode:   http.StatusOK,
+               expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"CONNECTED\",\"nodeType\":\"ENB\",\"enb\":{\"enbType\":\"MACRO_ENB\",\"servedCells\":[{\"pci\":1,\"cellId\":\"whatever\",\"tac\":\"whatever3\",\"broadcastPlmns\":[\"whatever\"],\"choiceEutraMode\":{\"fdd\":{}},\"eutraMode\":\"FDD\"}]},\"associatedE2tInstanceAddress\":\"10.0.2.15:38000\"}",
+       }
+
+       controllerUpdateEnbTestExecuter(t, &context)
+}
+
 func TestControllerAddEnbGetNodebInternalError(t *testing.T) {
        context := controllerAddEnbTestContext{
                getNodebInfoResult: &getNodebInfoResult{
@@ -859,6 +1143,29 @@ func TestControllerAddEnbMissingRequiredEnbProps(t *testing.T) {
        }
 }
 
+func TestControllerUpdateEnbMissingRequiredServedCellProps(t *testing.T) {
+
+       r := getUpdateEnbRequest("")
+
+       for _, v := range ServedCellRequiredFields {
+               enb := r["enb"]
+
+               enbMap, _ := enb.(map[string]interface{})
+
+               enbMap["servedCells"] = []interface{}{
+                       buildServedCell(v),
+               }
+
+               context := controllerUpdateEnbTestContext{
+                       requestBody:          r,
+                       expectedStatusCode:   http.StatusBadRequest,
+                       expectedJsonResponse: ValidationFailureJson,
+               }
+
+               controllerUpdateEnbTestExecuter(t, &context)
+       }
+}
+
 func TestControllerAddEnbMissingRequiredServedCellProps(t *testing.T) {
 
        r := getAddEnbRequest("")
@@ -917,7 +1224,7 @@ func TestControllerDeleteEnbGetNodebInternalError(t *testing.T) {
                        nodebInfo: nil,
                        rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
                },
-               expectedStatusCode: http.StatusInternalServerError,
+               expectedStatusCode:   http.StatusInternalServerError,
                expectedJsonResponse: RnibErrorJson,
        }
 
@@ -956,7 +1263,7 @@ func TestControllerDeleteEnbSuccess(t *testing.T) {
                        nodebInfo: &entities.NodebInfo{RanName: "ran1", NodeType: entities.Node_ENB, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED},
                        rnibError: nil,
                },
-               expectedStatusCode: http.StatusNoContent,
+               expectedStatusCode:   http.StatusNoContent,
                expectedJsonResponse: "",
        }
        controllerDeleteEnbTestExecuter(t, &context)
index 6afe87a..dae272a 100644 (file)
@@ -44,7 +44,10 @@ func NewUpdateNodebRequestHandler(logger *logger.Logger, rNibDataService service
 
 func (h *UpdateNodebRequestHandler) Handle(request models.Request) (models.IResponse, error) {
 
-       updateNodebRequest := request.(*models.UpdateNodebRequest)
+       updateNodebRequest, ok := request.(*models.UpdateEnbRequest)
+       if ok != true {
+               //TODO updateNodebRequest := request.(*models.UpdateGnbRequest)
+       }
 
        h.logger.Infof("#UpdateNodebRequestHandler.Handle - Ran name: %s", updateNodebRequest.RanName)
 
index 0828ce1..4f911f3 100644 (file)
@@ -25,8 +25,8 @@ import (
 )
 
 type IUpdateNodebManager interface {
-       Validate(request *models.UpdateNodebRequest) error
+       Validate(request models.Request) error
        RemoveNodebCells(nodeb *entities.NodebInfo) error
-       SetNodeb(nodeb *entities.NodebInfo, request *models.UpdateNodebRequest) error
+       SetNodeb(nodeb *entities.NodebInfo, request models.Request) error
        UpdateNodeb(nodeb *entities.NodebInfo) error
 }
index 6c9ae14..005e9bb 100644 (file)
@@ -25,6 +25,7 @@ import (
        "e2mgr/models"
        "e2mgr/services"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/pkg/errors"
 )
 
 type UpdateEnbManager struct {
@@ -41,12 +42,15 @@ func NewUpdateEnbManager(logger *logger.Logger, rnibDataService services.RNibDat
        }
 }
 
-func (h *UpdateEnbManager) Validate(request *models.UpdateNodebRequest) error {
+func (h *UpdateEnbManager) Validate(request models.Request) error {
 
-       h.logger.Infof("#UpdateEnbManager.Validate - Validate incoming request, ran name: %s", request.RanName)
+       updateEnbRequest := request.(*models.UpdateEnbRequest)
 
-       if err := h.nodebValidator.IsEnbValid(request.Enb); err != nil {
-               //TODO add log
+       h.logger.Infof("#UpdateEnbManager.Validate - Validate incoming request, ran name: %s", updateEnbRequest.RanName)
+
+
+       if err := h.validateRequestBody(updateEnbRequest); err != nil {
+               h.logger.Errorf("#UpdateEnbManager.Validate - validation failure: %s is a mandatory field and cannot be empty", err)
                return err
        }
 
@@ -55,6 +59,11 @@ func (h *UpdateEnbManager) Validate(request *models.UpdateNodebRequest) error {
 
 func (h *UpdateEnbManager) RemoveNodebCells(nodeb *entities.NodebInfo) error {
 
+       if nodeb.NodeType != entities.Node_ENB {
+               h.logger.Errorf("#UpdateEnbManager.RemoveNodebCells - RAN name: %s - nodeb missing eNB configuration", nodeb.GetRanName())
+               return e2managererrors.NewRequestValidationError()
+       }
+
        err := h.rnibDataService.RemoveServedCells(nodeb.GetRanName(), nodeb.GetEnb().GetServedCells())
        if err != nil {
                h.logger.Errorf("#UpdateEnbManager.RemoveNodebCells - RAN name: %s - Failed removing eNB served cells", nodeb.GetRanName())
@@ -65,15 +74,11 @@ func (h *UpdateEnbManager) RemoveNodebCells(nodeb *entities.NodebInfo) error {
        return nil
 }
 
-func (h *UpdateEnbManager) SetNodeb(nodeb *entities.NodebInfo, request *models.UpdateNodebRequest) error {
+func (h *UpdateEnbManager) SetNodeb(nodeb *entities.NodebInfo, request models.Request) error {
 
-       ranName := nodeb.GetRanName()
+       updateEnbRequest := request.(*models.UpdateEnbRequest)
 
-       if nodeb.NodeType != entities.Node_ENB {
-               h.logger.Errorf("#UpdateEnbManager.SetNodeb - RAN name: %s - nodeb missing eNB configuration", ranName)
-               return e2managererrors.NewRequestValidationError()
-       }
-       nodeb.Configuration = &entities.NodebInfo_Enb{Enb: request.Enb}
+       nodeb.Configuration = &entities.NodebInfo_Enb{Enb: updateEnbRequest.Enb}
 
        return nil
 }
@@ -89,3 +94,16 @@ func (h *UpdateEnbManager) UpdateNodeb(nodeb *entities.NodebInfo) error {
 
        return nil
 }
+
+func (h *UpdateEnbManager) validateRequestBody(request *models.UpdateEnbRequest) error {
+
+       if request.Enb == nil {
+               return errors.New("enb")
+       }
+
+       if err := h.nodebValidator.IsEnbValid(request.Enb); err != nil {
+               return err
+       }
+
+       return nil
+}
\ No newline at end of file
index 1d6a63a..79d970c 100644 (file)
 
 package models
 
-import "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+import (
+       "encoding/json"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/golang/protobuf/jsonpb"
+)
+
+type UpdateEnbRawRequest struct {
+       RanName    string
+       Enb        json.RawMessage
+}
 
 type UpdateEnbRequest struct {
-       RanName string
-       *entities.Enb
-       *entities.Gnb
+       RanName    string
+       Enb        *entities.Enb
+}
+
+func (r *UpdateEnbRequest) UnmarshalJSON(data []byte) error {
+       updateEnbRawRequest := UpdateEnbRawRequest{}
+       err := json.Unmarshal(data, &updateEnbRawRequest)
+
+       if err != nil {
+               return err
+       }
+
+       if updateEnbRawRequest.Enb != nil {
+               enb := entities.Enb{}
+               err = jsonpb.UnmarshalString(string(updateEnbRawRequest.Enb), &enb)
+
+               if err != nil {
+                       return err
+               }
+
+               r.Enb = &enb
+       }
+
+       return nil
 }
\ No newline at end of file
diff --git a/E2Manager/models/update_nodeb_request.go b/E2Manager/models/update_nodeb_request.go
deleted file mode 100644 (file)
index ad351bb..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright 2019 AT&T Intellectual Property
-// Copyright 2019 Nokia
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//  This source code is part of the near-RT RIC (RAN Intelligent Controller)
-//  platform project (RICP).
-
-package models
-
-import "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-
-type UpdateNodebRequest struct {
-       RanName string
-       *entities.Enb
-       *entities.Gnb
-}
\ No newline at end of file
index 75cf7b0..0685743 100644 (file)
@@ -157,6 +157,34 @@ func TestUpdateGnbCellsInvalidCellFailure(t *testing.T) {
        assert.IsType(t, &common.ValidationError{}, rNibErr)
 }
 
+func getUpdateEnbCellsSetExpected(t *testing.T, nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) []interface{} {
+
+       nodebInfoData, err := proto.Marshal(nodebInfo)
+       if err != nil {
+               t.Fatalf("#rNibWriter_test.getUpdateEnbCellsSetExpected - Failed to marshal NodeB entity. Error: %s", err)
+       }
+
+       nodebNameKey, _ := common.ValidateAndBuildNodeBNameKey(nodebInfo.RanName)
+       nodebIdKey, _ := common.ValidateAndBuildNodeBIdKey(nodebInfo.NodeType.String(), nodebInfo.GlobalNbId.PlmnId, nodebInfo.GlobalNbId.NbId)
+       setExpected := []interface{}{nodebNameKey, nodebInfoData, nodebIdKey, nodebInfoData}
+
+       for _, cell := range servedCells {
+
+               cellEntity := entities.Cell{Type: entities.Cell_LTE_CELL, Cell: &entities.Cell_ServedCellInfo{ServedCellInfo: cell}}
+               cellData, err := proto.Marshal(&cellEntity)
+
+               if err != nil {
+                       t.Fatalf("#rNibWriter_test.getUpdateEnbCellsSetExpected - Failed to marshal cell entity. Error: %s", err)
+               }
+
+               nrCellIdKey, _ := common.ValidateAndBuildCellIdKey(cell.GetCellId())
+               cellNamePciKey, _ := common.ValidateAndBuildCellNamePciKey(nodebInfo.RanName, cell.GetPci())
+               setExpected = append(setExpected, nrCellIdKey, cellData, cellNamePciKey, cellData)
+       }
+
+       return setExpected
+}
+
 func getUpdateGnbCellsSetExpected(t *testing.T, nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) []interface{} {
 
        nodebInfoData, err := proto.Marshal(nodebInfo)
@@ -884,6 +912,18 @@ func TestSaveGeneralConfigurationDbError(t *testing.T) {
 
        assert.NotNil(t, rNibErr)
 }
+
+func TestRemoveServedCellsFailure(t *testing.T) {
+       w, sdlInstanceMock := initSdlInstanceMock(namespace)
+       servedCellsToRemove := generateServedCells("whatever1", "whatever2")
+       expectedErr := errors.New("expected error")
+       sdlInstanceMock.On("Remove", buildServedCellInfoKeysToRemove(RanName, servedCellsToRemove)).Return(expectedErr)
+
+       rNibErr := w.RemoveServedCells(RanName, servedCellsToRemove)
+
+       assert.NotNil(t, rNibErr)
+}
+
 func TestRemoveServedCellsSuccess(t *testing.T) {
        w, sdlInstanceMock := initSdlInstanceMock(namespace)
        servedCellsToRemove := generateServedCells("whatever1", "whatever2")
@@ -914,35 +954,35 @@ func TestUpdateEnbInvalidCellFailure(t *testing.T) {
        assert.IsType(t, &common.ValidationError{}, rNibErr)
 }
 
-/*func TestUpdateEnbSdlFailure(t *testing.T) {
-       inventoryName := "ranName"
+func TestUpdateEnbSdlFailure(t *testing.T) {
+       inventoryName := "name"
        plmnId := "02f829"
        nbId := "4a952a0a"
        w, sdlInstanceMock := initSdlInstanceMock(namespace)
        servedCells := generateServedCells("test1", "test2")
-       nodebInfo := generateNodebInfo(inventoryName, entities.Node_GNB, plmnId, nbId)
+       nodebInfo := generateNodebInfo(inventoryName, entities.Node_ENB, plmnId, nbId)
        nodebInfo.GetEnb().ServedCells = servedCells
-       setExpected := getUpdateEnbSetExpected(t, nodebInfo, servedCells)
+       setExpected := getUpdateEnbCellsSetExpected(t, nodebInfo, servedCells)
        sdlInstanceMock.On("SetAndPublish", []string{"RAN_MANIPULATION", inventoryName + "_" + RanUpdatedEvent}, []interface{}{setExpected}).Return(errors.New("expected error"))
        rNibErr := w.UpdateEnb(nodebInfo, servedCells)
        assert.IsType(t, &common.InternalError{}, rNibErr)
-}*/
+}
 
-/*func TestUpdateEnbSuccess(t *testing.T) {
-       inventoryName := "ranName"
+func TestUpdateEnbSuccess(t *testing.T) {
+       inventoryName := "name"
        plmnId := "02f829"
        nbId := "4a952a0a"
        w, sdlInstanceMock := initSdlInstanceMock(namespace)
        servedCells := generateServedCells("test1", "test2")
-       nodebInfo := generateNodebInfo(inventoryName, entities.Node_GNB, plmnId, nbId)
+       nodebInfo := generateNodebInfo(inventoryName, entities.Node_ENB, plmnId, nbId)
        nodebInfo.GetEnb().ServedCells = servedCells
-       setExpected := getUpdateEnbSetExpected(t, nodebInfo, servedCells)
+       setExpected := getUpdateEnbCellsSetExpected(t, nodebInfo, servedCells)
 
        var e error
        sdlInstanceMock.On("SetAndPublish", []string{"RAN_MANIPULATION", inventoryName + "_" + RanUpdatedEvent}, []interface{}{setExpected}).Return(e)
        rNibErr := w.UpdateEnb(nodebInfo, servedCells)
        assert.Nil(t, rNibErr)
-}*/
+}
 
 func getUpdateEnbSetExpected(t *testing.T, nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) []interface{} {