[RIC-431] Add UTs | Update AddEnbRequest | Update Swagger 31/4331/1
authoridanshal <idan.shalom@intl.att.com>
Tue, 7 Jul 2020 11:53:39 +0000 (11:53 +0000)
committeridanshal <idan.shalom@intl.att.com>
Tue, 7 Jul 2020 11:53:44 +0000 (11:53 +0000)
Change-Id: If5a2a5a433d41f0b670a12d919f6c5157b789a1e
Signed-off-by: idanshal <idan.shalom@intl.att.com>
E2Manager/configuration/configuration_test.go
E2Manager/container-tag.yaml
E2Manager/controllers/nodeb_controller.go
E2Manager/controllers/nodeb_controller_test.go
E2Manager/handlers/httpmsghandlers/update_gnb_request_handler.go
E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go
E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go
E2Manager/models/add_enb_request.go
Swagger/E2Manager_API.yaml

index 8f5a411..01a0a83 100644 (file)
@@ -221,6 +221,38 @@ func TestGlobalRicIdConfigNotFoundFailure(t *testing.T) {
                func() { ParseConfiguration() })
 }
 
+func TestRnibWriterConfigNotFoundFailure(t *testing.T) {
+       configPath := "../resources/configuration.yaml"
+       configPathTmp := "../resources/configuration.yaml_tmp"
+       err := os.Rename(configPath, configPathTmp)
+       if err != nil {
+               t.Errorf("#TestGlobalRicIdConfigNotFoundFailure - failed to rename configuration file: %s\n", configPath)
+       }
+       defer func() {
+               err = os.Rename(configPathTmp, configPath)
+               if err != nil {
+                       t.Errorf("#TestGlobalRicIdConfigNotFoundFailure - failed to rename configuration file: %s\n", configPath)
+               }
+       }()
+       yamlMap := map[string]interface{}{
+               "rmr":            map[string]interface{}{"port": 3801, "maxMsgSize": 4096},
+               "logging":        map[string]interface{}{"logLevel": "info"},
+               "http":           map[string]interface{}{"port": 3800},
+               "routingManager": map[string]interface{}{"baseUrl": "http://localhost:8080/ric/v1/handles/"},
+               "globalRicId": map[string]interface{}{"mcc": 327, "mnc": 94, "ricId": "AACCE"},
+       }
+       buf, err := yaml.Marshal(yamlMap)
+       if err != nil {
+               t.Errorf("#TestGlobalRicIdConfigNotFoundFailure - failed to marshal configuration map\n")
+       }
+       err = ioutil.WriteFile("../resources/configuration.yaml", buf, 0644)
+       if err != nil {
+               t.Errorf("#TestGlobalRicIdConfigNotFoundFailure - failed to write configuration file: %s\n", configPath)
+       }
+       assert.PanicsWithValue(t, "#configuration.populateRnibWriterConfig - failed to populate Rnib Writer configuration: The entry 'rnibWriter' not found\n",
+               func() { ParseConfiguration() })
+}
+
 func TestEmptyRicIdFailure(t *testing.T) {
        configPath := "../resources/configuration.yaml"
        configPathTmp := "../resources/configuration.yaml_tmp"
index d452c65..1834024 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.7
+tag: 5.2.8
index a1f5b78..96d0067 100644 (file)
@@ -299,6 +299,10 @@ func (c *NodebController) handleErrorResponse(err error, writer http.ResponseWri
                        e2Error, _ := err.(*e2managererrors.RoutingManagerError)
                        errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
                        httpError = http.StatusServiceUnavailable
+               case *e2managererrors.NodebExistsError:
+                       e2Error, _ := err.(*e2managererrors.NodebExistsError)
+                       errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
+                       httpError = http.StatusBadRequest
                default:
                        e2Error := e2managererrors.NewInternalError()
                        errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
index 0cbeb50..c63d36b 100644 (file)
@@ -63,10 +63,11 @@ const (
 )
 
 var (
-       ServedNrCellInformationRequiredFields = []string{"cellId", "choiceNrMode", "nrMode", "nrPci", "servedPlmns"}
-       NrNeighbourInformationRequiredFields  = []string{"nrCgi", "choiceNrMode", "nrMode", "nrPci"}
+       ServedNrCellInformationRequiredFields = []string{"cellId", "choiceNrMode", "nrMode", "servedPlmns"}
+       NrNeighbourInformationRequiredFields  = []string{"nrCgi", "choiceNrMode", "nrMode"}
+       AddEnbRequestRequiredFields           = []string{"ranName", "enb", "globalNbId"}
        EnbRequiredFields                     = []string{"enbType", "servedCells"}
-       ServedCellRequiredFields              = []string{"broadcastPlmns", "cellId", "choiceEutraMode", "eutraMode", "pci", "tac"}
+       ServedCellRequiredFields              = []string{"broadcastPlmns", "cellId", "choiceEutraMode", "eutraMode", "tac"}
 )
 
 type controllerGetNodebTestContext struct {
@@ -94,9 +95,9 @@ type updateGnbCellsParams struct {
 }
 
 type saveNodebParams struct {
-       nodebInfo *entities.NodebInfo
+       nodebInfo  *entities.NodebInfo
        nbIdentity *entities.NbIdentity
-       err error
+       err        error
 }
 
 type removeServedNrCellsParams struct {
@@ -200,6 +201,37 @@ func buildServedCell(propToOmit string) map[string]interface{} {
        return ret
 }
 
+func getAddEnbRequest(propToOmit string) map[string]interface{} {
+       ret := map[string]interface{}{
+               "ranName": RanName,
+               "globalNbId": map[string]interface{}{
+                       "plmnId": "whatever",
+                       "nbId":   "whatever2",
+               },
+               "enb": buildEnb(""),
+       }
+
+       if len(propToOmit) != 0 {
+               delete(ret, propToOmit)
+       }
+
+       return ret
+}
+
+func buildEnb(propToOmit string) map[string]interface{} {
+       ret := map[string]interface{}{
+               "enbType": 1,
+               "servedCells": []interface{}{
+                       buildServedCell(""),
+               }}
+
+       if len(propToOmit) != 0 {
+               delete(ret, propToOmit)
+       }
+
+       return ret
+}
+
 func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock) {
        log := initLog(t)
        config := configuration.ParseConfiguration()
@@ -371,7 +403,7 @@ func activateControllerAddEnbMocks(context *controllerAddEnbTestContext, readerM
 
                nbIdentity := entities.NbIdentity{InventoryName: addEnbRequest.RanName, GlobalNbId: addEnbRequest.GlobalNbId}
 
-               writerMock.On("SaveNodeb",&nbIdentity, &nodebInfo).Return(context.saveNodebParams.err)
+               writerMock.On("SaveNodeb", &nbIdentity, &nodebInfo).Return(context.saveNodebParams.err)
        }
 }
 
@@ -379,14 +411,15 @@ func controllerAddEnbTestExecuter(t *testing.T, context *controllerAddEnbTestCon
        controller, readerMock, writerMock, _, _ := setupControllerTest(t)
        writer := httptest.NewRecorder()
        r := buildAddEnbRequest(context)
-       defer r.Body.Close()
        body, _ := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest))
 
        addEnbRequest := models.AddEnbRequest{}
 
        _ = json.Unmarshal(body, &addEnbRequest)
        activateControllerAddEnbMocks(context, readerMock, writerMock, &addEnbRequest)
-       controller.AddEnb(writer, buildAddEnbRequest(context))
+       r = buildAddEnbRequest(context)
+       defer r.Body.Close()
+       controller.AddEnb(writer, r)
        assertControllerAddEnb(t, context, writer, readerMock, writerMock)
 }
 
@@ -676,6 +709,104 @@ func TestControllerUpdateGnbSuccess(t *testing.T) {
        controllerUpdateGnbTestExecuter(t, &context)
 }
 
+func TestControllerAddEnbGetNodebInternalError(t *testing.T) {
+       context := controllerAddEnbTestContext{
+               getNodebInfoResult: &getNodebInfoResult{
+                       nodebInfo: nil,
+                       rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
+               },
+               requestBody:          getAddEnbRequest(""),
+               expectedStatusCode:   http.StatusInternalServerError,
+               expectedJsonResponse: RnibErrorJson,
+       }
+
+       controllerAddEnbTestExecuter(t, &context)
+}
+
+func TestControllerAddEnbNodebExistsFailure(t *testing.T) {
+       context := controllerAddEnbTestContext{
+               getNodebInfoResult: &getNodebInfoResult{
+                       nodebInfo: &entities.NodebInfo{},
+                       rnibError: nil,
+               },
+               requestBody:          getAddEnbRequest(""),
+               expectedStatusCode:   http.StatusBadRequest,
+               expectedJsonResponse: NodebExistsJson,
+       }
+
+       controllerAddEnbTestExecuter(t, &context)
+}
+
+func TestControllerAddEnbSaveNodebFailure(t *testing.T) {
+       context := controllerAddEnbTestContext{
+               saveNodebParams: &saveNodebParams{
+                       err: common.NewInternalError(errors.New("#reader.SaveeNodeb - Internal Error")),
+               },
+               getNodebInfoResult: &getNodebInfoResult{
+                       nodebInfo: nil,
+                       rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
+               },
+               requestBody:          getAddEnbRequest(""),
+               expectedStatusCode:   http.StatusInternalServerError,
+               expectedJsonResponse: RnibErrorJson,
+       }
+
+       controllerAddEnbTestExecuter(t, &context)
+}
+
+func TestControllerAddEnbMissingRequiredRequestProps(t *testing.T) {
+
+       for _, v := range AddEnbRequestRequiredFields {
+               context := controllerAddEnbTestContext{
+                       requestBody:          getAddEnbRequest(v),
+                       expectedStatusCode:   http.StatusBadRequest,
+                       expectedJsonResponse: ValidationFailureJson,
+               }
+
+               controllerAddEnbTestExecuter(t, &context)
+       }
+}
+
+func TestControllerAddEnbMissingRequiredEnbProps(t *testing.T) {
+
+       r := getAddEnbRequest("")
+
+       for _, v := range EnbRequiredFields {
+               r["enb"] = buildEnb(v)
+
+               context := controllerAddEnbTestContext{
+                       requestBody:          r,
+                       expectedStatusCode:   http.StatusBadRequest,
+                       expectedJsonResponse: ValidationFailureJson,
+               }
+
+               controllerAddEnbTestExecuter(t, &context)
+       }
+}
+
+func TestControllerAddEnbMissingRequiredServedCellProps(t *testing.T) {
+
+       r := getAddEnbRequest("")
+
+       for _, v := range ServedCellRequiredFields {
+               enb := r["enb"]
+
+               enbMap, _ := enb.(map[string]interface{})
+
+               enbMap["servedCells"] = []interface{}{
+                       buildServedCell(v),
+               }
+
+               context := controllerAddEnbTestContext{
+                       requestBody:          r,
+                       expectedStatusCode:   http.StatusBadRequest,
+                       expectedJsonResponse: ValidationFailureJson,
+               }
+
+               controllerAddEnbTestExecuter(t, &context)
+       }
+}
+
 func TestControllerAddEnbSuccess(t *testing.T) {
        context := controllerAddEnbTestContext{
                saveNodebParams: &saveNodebParams{
index 5d9d2b2..3648563 100644 (file)
@@ -161,10 +161,6 @@ func isServedNrCellInformationValid(servedNrCellInformation *entities.ServedNRCe
                return errors.New("nrMode")
        }
 
-       if servedNrCellInformation.NrPci == 0 {
-               return errors.New("nrPci")
-       }
-
        if len(servedNrCellInformation.ServedPlmns) == 0 {
                return errors.New("servedPlmns")
        }
@@ -205,10 +201,6 @@ func isNrNeighbourInformationValid(nrNeighbourInformation *entities.NrNeighbourI
                return errors.New("nrMode")
        }
 
-       if nrNeighbourInformation.NrPci == 0 {
-               return errors.New("nrPci")
-       }
-
        return isNrNeighbourInfoChoiceNrModeValid(nrNeighbourInformation.ChoiceNrMode)
 }
 
index d229e8c..0b8ce33 100644 (file)
@@ -152,12 +152,6 @@ func (h *E2SetupRequestNotificationHandler) handleNewRan(ranName string, e2tIpAd
                return nil, err
        }
 
-       err = h.ranConnectStatusChangeManager.ChangeStatus(nodebInfo, entities.ConnectionStatus_CONNECTED)
-
-       if err != nil {
-               return nil, err
-       }
-
        return nodebInfo, nil
 }
 
index 1bbf66f..c8b49eb 100644 (file)
@@ -208,26 +208,7 @@ func testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t *testing.T, xml
        e2tInstancesManagerMock.AssertExpectations(t)
 }
 
-func TestE2SetupRequestNotificationHandler_HandleUpdateNodebInfoOnConnectionStatusInversionFailureForNewGnb(t *testing.T) {
-       xml := readXmlFile(t, GnbSetupRequestXmlPath)
-       handler, readerMock, writerMock, _, 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)
-       nbIdentity := &entities.NbIdentity{InventoryName: nodebRanName, GlobalNbId: nodebInfo.GlobalNbId}
-       writerMock.On("SaveNodeb", nbIdentity, nodebInfo).Return(nil)
-       updatedNodebInfo := *nodebInfo
-       updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTED
-       writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo, StateChangeMessageChannel, nodebRanName+"_CONNECTED").Return(common.NewInternalError(errors.New("some error")))
-       handler.Handle(notificationRequest)
-       readerMock.AssertExpectations(t)
-       writerMock.AssertExpectations(t)
-       routingManagerClientMock.AssertExpectations(t)
-       e2tInstancesManagerMock.AssertExpectations(t)
-}
+
 
 func TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess(t *testing.T) {
        testE2SetupRequestNotificationHandler_HandleNewRanSuccess(t, GnbSetupRequestXmlPath)
index a15c94b..c2fa520 100644 (file)
@@ -53,22 +53,27 @@ func (r *AddEnbRequest) UnmarshalJSON(data []byte) error {
        r.Ip = addEnbRawRequest.Ip
        r.Port = addEnbRawRequest.Port
 
-       globalNbId := entities.GlobalNbId{}
-       err = jsonpb.UnmarshalString(string(addEnbRawRequest.GlobalNbId), &globalNbId)
+       if addEnbRawRequest.GlobalNbId != nil {
+               globalNbId := entities.GlobalNbId{}
+               err = jsonpb.UnmarshalString(string(addEnbRawRequest.GlobalNbId), &globalNbId)
 
-       if err != nil {
-               return err
+               if err != nil {
+                       return err
+               }
+
+               r.GlobalNbId = &globalNbId
        }
 
-       r.GlobalNbId = &globalNbId
+       if addEnbRawRequest.Enb != nil {
+               enb := entities.Enb{}
+               err = jsonpb.UnmarshalString(string(addEnbRawRequest.Enb), &enb)
 
-       enb := entities.Enb{}
-       err = jsonpb.UnmarshalString(string(addEnbRawRequest.Enb), &enb)
+               if err != nil {
+                       return err
+               }
 
-       if err != nil {
-               return err
+               r.Enb = &enb
        }
 
-       r.Enb = &enb
        return nil
 }
\ No newline at end of file
index 1ab3766..7e0dd20 100644 (file)
@@ -2,7 +2,7 @@ openapi: 3.0.0
 info:
   title: E2 Manager Service
   description: E2 Manager Service APIs
-  version: 5.2.2
+  version: 5.2.8
 servers:
   - url: 'http://{apiRoot}/v1'
     variables:
@@ -85,6 +85,38 @@ paths:
             application/problem+json:
               schema:
                 $ref: '#/components/schemas/ErrorResponse'
+  '/nodeb/enb':
+    post:
+      summary: Add ENB
+      tags:
+        - nodeb
+      operationId: AddEnb
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/AddEnbRequest'
+        required: true
+      responses:
+        '200':
+          description: Successful operation
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/AddEnbResponse'
+        '400':
+          description: Invalid input
+          content:
+            application/problem+json:
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
+        '500':
+          description: Internal error
+          content:
+            application/problem+json:
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
+
   /nodeb/shutdown:
     put:
       tags:
@@ -187,6 +219,64 @@ paths:
                 $ref: '#/components/schemas/ErrorResponse'
 components:
   schemas:
+    AddEnbRequest:
+      type: object
+      required:
+        - ranName
+        - globalNbId
+        - enb
+      properties:
+        ranName:
+          type: string
+        globalNbId:
+          properties:
+            nbId:
+              type: string
+            plmnId:
+              type: string
+        ip:
+          type: string
+        port:
+          type: integer
+        enb:
+          $ref: '#/components/schemas/Enb'
+      additionalProperties: false
+
+    AddEnbResponse:
+      properties:
+        connectionStatus:
+          oneOf:
+            - type: string
+            - type: integer
+        failureType:
+          oneOf:
+            - type: string
+            - type: integer
+        globalNbId:
+          properties:
+            nbId:
+              type: string
+            plmnId:
+              type: string
+          additionalProperties: false
+          type: object
+        enb:
+          $ref: '#/components/schemas/Enb'
+        ip:
+          type: string
+        nodeType:
+          oneOf:
+            - type: string
+            - type: integer
+        port:
+          type: integer
+        ranName:
+          type: string
+        setupFailure:
+          $ref: '#/components/schemas/SetupFailure'
+      additionalProperties: false
+      type: object
+
     UpdateGnbRequest:
       type: object
       required:
@@ -504,6 +594,8 @@ components:
                 type: object
               tac:
                 type: string
+              additionalCellInformation:
+                $ref: '#/components/schemas/AdditionalCellInformation'
             type: object
           type: array
       type: object
@@ -856,6 +948,8 @@ components:
                 type: array
               stac5g:
                 type: string
+              additionalCellInformation:
+                $ref: '#/components/schemas/AdditionalCellInformation'
             additionalProperties: false
             type: object
         additionalProperties: false
@@ -915,3 +1009,22 @@ components:
             - type: integer
       additionalProperties: false
       type: object
+    AdditionalCellInformation:
+      properties:
+        cellLatitude:
+          type: number
+        cellLongitude:
+          type: number
+        antennaHeight:
+          type: number
+        antennaAzimuthDirection:
+          type: number
+        antennaTiltAngle:
+          type: number
+        antennaMaxTransmit:
+          type: number
+        antennaMaxGain:
+          type: number
+        sectorId:
+          type: integer
+      type: object
\ No newline at end of file