NCMP Java API depends on NCM-Rest-API (cyclic) through json properties on Java API 21/127221/15
authorDylanB95EST <dylan.byrne@est.tech>
Mon, 21 Feb 2022 12:57:08 +0000 (12:57 +0000)
committerBruno Sakoto <bruno.sakoto@bell.ca>
Mon, 28 Feb 2022 21:52:25 +0000 (21:52 +0000)
Using POJO and new converter class instead
of previous object mapper

Issue-ID: CPS-893
Change-Id: I75531f386f08cb172d2901a4bbe97ae22cc5937e
Signed-off-by: DylanB95EST <dylan.byrne@est.tech>
20 files changed:
cps-dependencies/pom.xml
cps-ncmp-rest/docs/openapi/components.yaml
cps-ncmp-rest/pom.xml
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java [new file with mode: 0644]
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy [new file with mode: 0644]
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
cps-ncmp-rest/src/test/resources/dmi-registration.json [deleted file]
cps-ncmp-rest/src/test/resources/dmi_registration_all_singing_and_dancing.json [new file with mode: 0644]
cps-ncmp-rest/src/test/resources/dmi_registration_combined_valid.json [deleted file]
cps-ncmp-rest/src/test/resources/dmi_registration_updates_only.json [new file with mode: 0644]
cps-ncmp-rest/src/test/resources/dmi_registration_without_properties.json [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandle.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/PersistenceCmHandlesList.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
csit/tests/cps-model-sync/cps-model-sync.robot

index a76cd3d..5c2ff56 100755 (executable)
@@ -44,6 +44,7 @@
         <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
         <sonar.skip>true</sonar.skip>
         <testcontainers.version>1.15.1</testcontainers.version>
+        <mapstruct.version>1.4.2.Final</mapstruct.version>
     </properties>
 
     <distributionManagement>
                 <artifactId>log4j-to-slf4j</artifactId>
                 <version>2.17.1</version>
             </dependency>
+            <dependency>
+                <groupId>org.mapstruct</groupId>
+                <artifactId>mapstruct</artifactId>
+                <version>${mapstruct.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.mapstruct</groupId>
+                <artifactId>mapstruct-processor</artifactId>
+                <version>${mapstruct.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 </project>
index cda6ca3..fd02b6e 100644 (file)
@@ -38,12 +38,15 @@ components:
         dmiPlugin:
           type: string
           example: my-dmi-plugin
+          default: ""
         dmiDataPlugin:
           type: string
           example: my-dmi-data-plugin
+          default: ""
         dmiModelPlugin:
           type: string
           example: my-dmi-model-plugin
+          default: ""
         createdCmHandles:
           type: array
           items:
index b3ae81b..97305cf 100644 (file)
             <groupId>io.swagger.core.v3</groupId>
             <artifactId>swagger-annotations</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct-processor</artifactId>
+        </dependency>
         <!-- T E S T   D E P E N D E N C I E S -->
         <dependency>
             <groupId>org.codehaus.groovy</groupId>
index 9e888fb..3699195 100755 (executable)
 
 package org.onap.cps.ncmp.rest.controller;
 
-
-import com.fasterxml.jackson.databind.ObjectMapper;
 import javax.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
-import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
 import org.onap.cps.ncmp.rest.api.NetworkCmProxyInventoryApi;
 import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration;
 import org.springframework.http.HttpStatus;
@@ -40,7 +37,7 @@ import org.springframework.web.bind.annotation.RestController;
 public class NetworkCmProxyInventoryController implements NetworkCmProxyInventoryApi {
 
     private final NetworkCmProxyDataService networkCmProxyDataService;
-    private final ObjectMapper objectMapper;
+    private final RestInputMapper restInputMapper;
 
     /**
      * Update DMI Plugin Registration (used for first registration also).
@@ -49,14 +46,11 @@ public class NetworkCmProxyInventoryController implements NetworkCmProxyInventor
     @Override
     public ResponseEntity<Void> updateDmiPluginRegistration(
         final @Valid RestDmiPluginRegistration restDmiPluginRegistration) {
-        final DmiPluginRegistration dmiPluginRegistration =
-            convertRestObjectToJavaApiObject(restDmiPluginRegistration);
-        networkCmProxyDataService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration);
+        networkCmProxyDataService.updateDmiRegistrationAndSyncModule(
+            restInputMapper.toDmiPluginRegistration(restDmiPluginRegistration));
         return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
-    private DmiPluginRegistration convertRestObjectToJavaApiObject(
-        final RestDmiPluginRegistration restDmiPluginRegistration) {
-        return objectMapper.convertValue(restDmiPluginRegistration, DmiPluginRegistration.class);
-    }
 }
+
+
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java
new file mode 100644 (file)
index 0000000..d38204c
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation
+ *  ================================================================================
+ *  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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.rest.controller;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.NullValueMappingStrategy;
+import org.mapstruct.NullValuePropertyMappingStrategy;
+import org.onap.cps.ncmp.api.models.CmHandle;
+import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
+import org.onap.cps.ncmp.rest.model.RestCmHandle;
+import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration;
+
+@Mapper(componentModel = "spring", nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT,
+    nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
+public interface RestInputMapper {
+
+    DmiPluginRegistration toDmiPluginRegistration(final RestDmiPluginRegistration restDmiPluginRegistration);
+
+    @Mappings({
+        @Mapping(source = "cmHandle", target = "cmHandleID"),
+        @Mapping(source = "cmHandleProperties", target = "dmiProperties"),
+        @Mapping(source = "publicCmHandleProperties", target = "publicProperties")
+    })
+    CmHandle toCmHandle(final RestCmHandle restCmHandle);
+
+}
index 7dc6284..fd01096 100755 (executable)
@@ -33,6 +33,7 @@ import org.onap.cps.spi.exceptions.CpsException;
 import org.onap.cps.spi.exceptions.DataValidationException;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 
@@ -73,8 +74,8 @@ public class NetworkCmProxyRestExceptionHandler {
         return buildErrorResponse(HttpStatus.BAD_REQUEST, exception);
     }
 
-    @ExceptionHandler({DataValidationException.class})
-    public static ResponseEntity<Object> handleDataValidatedExceptions(final DataValidationException exception) {
+    @ExceptionHandler({DataValidationException.class, HttpMessageNotReadableException.class})
+    public static ResponseEntity<Object> handleDataValidatedExceptions(final Exception exception) {
         return buildErrorResponse(HttpStatus.BAD_REQUEST, exception);
     }
 
index 3c603ed..079554a 100644 (file)
@@ -24,8 +24,9 @@ package org.onap.cps.ncmp.rest.controller
 import com.fasterxml.jackson.databind.ObjectMapper
 import org.onap.cps.TestUtils
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
-import org.onap.cps.ncmp.api.models.CmHandle
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
+import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration
+import org.onap.cps.utils.JsonObjectMapper
 import org.spockframework.spring.SpringBean
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.beans.factory.annotation.Value
@@ -47,46 +48,51 @@ class NetworkCmProxyInventoryControllerSpec extends Specification {
     @SpringBean
     NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
 
+    @SpringBean
+    RestInputMapper restInputMapper = Mock()
+
+    DmiPluginRegistration mockDmiPluginRegistration = Mock()
+
+    JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+
     @Value('${rest.api.ncmp-inventory-base-path}/v1')
     def ncmpBasePathV1
 
-    def 'Register CM Handle Event' () {
-        given: 'jsonData'
-            def jsonData = TestUtils.getResourceFileContent('dmi-registration.json')
-        when: 'post request is performed'
+    def 'Dmi plugin registration #scenario' () {
+        given: 'a dmi plugin registration with #scenario'
+            def jsonData = TestUtils.getResourceFileContent(dmiRegistrationJson)
+        and: 'the expected rest input as an object'
+            def expectedRestDmiPluginRegistration = jsonObjectMapper.convertJsonString(jsonData, RestDmiPluginRegistration)
+        and: 'the converter returns a dmi registration (only for the expected input object)'
+            restInputMapper.toDmiPluginRegistration(expectedRestDmiPluginRegistration) >> mockDmiPluginRegistration
+        when: 'post request is performed & registration is called with correct DMI plugin information'
             def response = mvc.perform(
                 post("$ncmpBasePathV1/ch")
-                .contentType(MediaType.APPLICATION_JSON)
-                .content(jsonData)
+                    .contentType(MediaType.APPLICATION_JSON)
+                    .content(jsonData)
             ).andReturn().response
-        then: 'the cm handles are registered with the service'
-            1 * mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(_)
-        and: 'response status is No Content'
-            response.status == HttpStatus.NO_CONTENT.value()
+        then: 'the converted object is forwarded to the registration service'
+            1 * mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(mockDmiPluginRegistration)
+        and: 'response status is no content'
+            response.status ==  HttpStatus.NO_CONTENT.value()
+        where: 'the following registration json is used'
+            scenario                                                                       | dmiRegistrationJson
+            'multiple services, added, updated and removed cm handles and many properties' | 'dmi_registration_all_singing_and_dancing.json'
+            'updated cm handle with updated/new and removed properties'                    | 'dmi_registration_updates_only.json'
+            'without any properties'                                                       | 'dmi_registration_without_properties.json'
     }
 
-    def 'Dmi plugin registration with #scenario' () {
-        given: 'jsonData, cmHandle, & DmiPluginRegistration'
-            def jsonData = TestUtils.getResourceFileContent('dmi_registration_combined_valid.json' )
-            def cmHandle = new CmHandle(cmHandleID : 'example-name')
-            def expectedDmiPluginRegistration = new DmiPluginRegistration(
-                dmiPlugin: 'service1',
-                dmiDataPlugin: '',
-                dmiModelPlugin: '',
-                createdCmHandles: [cmHandle])
+    def 'Dmi plugin registration with invalid json' () {
+        given: 'a dmi plugin registration with #scenario'
+            def jsonDataWithUndefinedDataLabel = '{"notAdmiPlugin":""}'
         when: 'post request is performed & registration is called with correct DMI plugin information'
             def response = mvc.perform(
                 post("$ncmpBasePathV1/ch")
                     .contentType(MediaType.APPLICATION_JSON)
-                    .content(jsonData)
+                    .content(jsonDataWithUndefinedDataLabel)
             ).andReturn().response
-        then: 'no NcmpException is thrown & updateDmiRegistrationAndSyncModule is called with correct parameters'
-            1 * mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule({
-                it.getDmiPlugin() == expectedDmiPluginRegistration.getDmiPlugin()
-                it.getDmiDataPlugin() == expectedDmiPluginRegistration.getDmiDataPlugin()
-                it.getDmiModelPlugin() == expectedDmiPluginRegistration.getDmiModelPlugin()
-                it.getCreatedCmHandles().get(0).getCmHandleID() == expectedDmiPluginRegistration.getCreatedCmHandles().get(0).getCmHandleID()
-            })
+        then: 'response status is bad request'
+            response.status == HttpStatus.BAD_REQUEST.value()
     }
-}
 
+}
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy
new file mode 100644 (file)
index 0000000..c48a8ed
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation
+ *  ================================================================================
+ *  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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.rest.controller
+
+import org.mapstruct.factory.Mappers
+import org.onap.cps.ncmp.rest.model.RestCmHandle
+import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration
+import spock.lang.Specification
+
+class RestInputMapperSpec extends Specification {
+
+    def objectUnderTest = Mappers.getMapper(RestInputMapper.class)
+
+    def 'Convert a created REST CM Handle Input to an NCMP Service CM Handle with #scenario'() {
+        given: 'a rest cm handle input'
+            def inputRestCmHandle = new RestCmHandle(cmHandle : 'example-id', cmHandleProperties: dmiProperties,
+                publicCmHandleProperties: publicProperties)
+            def restDmiPluginRegistration = new RestDmiPluginRegistration(
+                createdCmHandles: [inputRestCmHandle])
+        when: 'to plugin dmi registration is called'
+            def result  = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration)
+        then: 'the result returns the correct number of cm handles'
+            result.createdCmHandles.size() == 1
+        and: 'the converted cm handle has the same id'
+            result.createdCmHandles[0].cmHandleID == 'example-id'
+        and: '(empty) properties are converted correctly'
+            result.createdCmHandles[0].dmiProperties == expectedDmiProperties
+            result.createdCmHandles[0].publicProperties == expectedPublicProperties
+        where: 'the following parameters are used'
+            scenario                    | dmiProperties                            | publicProperties                                         || expectedDmiProperties                     | expectedPublicProperties
+            'dmi and public properties' | ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property']   || ['Property-Example': 'example property']  | ['Public-Property-Example': 'public example property']
+            'no properties'             | null                                     | null                                                     || [:]                                       | [:]
+    }
+
+    def 'Handling empty dmi registration'() {
+        given: 'a rest cm handle input without any cm handles'
+            def restDmiPluginRegistration = new RestDmiPluginRegistration()
+        when: 'to plugin dmi registration is called'
+            def result  = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration)
+        then: 'unspecified lists remain as empty lists'
+            assert result.createdCmHandles == []
+            assert result.updatedCmHandles == []
+            assert result.removedCmHandles == []
+    }
+
+}
index 35544d9..306f546 100644 (file)
@@ -27,6 +27,7 @@ import org.onap.cps.TestUtils
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
 import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
 import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException
+import org.onap.cps.ncmp.rest.controller.RestInputMapper
 import org.onap.cps.spi.exceptions.CpsException
 import org.onap.cps.spi.exceptions.DataValidationException
 import org.onap.cps.utils.JsonObjectMapper
@@ -61,6 +62,9 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
     @SpringBean
     JsonObjectMapper jsonObjectMapper = Stub()
 
+    @SpringBean
+    RestInputMapper restInputMapper = Mock()
+
     @Value('${rest.api.ncmp-base-path}')
     def basePathNcmp
 
@@ -105,17 +109,17 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
     }
 
     def setupTestException(exception, apiType) {
-        if (NCMP.equals(apiType)) {
+        if (NCMP == apiType) {
             mockNetworkCmProxyDataService.getYangResourcesModuleReferences(*_) >> { throw exception }
         }
         mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(*_) >> { throw exception }
     }
 
     def performTestRequest(apiType) {
-        if (NCMP.equals(apiType)) {
+        if (NCMP == apiType) {
             return mvc.perform(get("$dataNodeBaseEndpointNcmp/ch/testCmHandle/modules")).andReturn().response
         }
-        def jsonData = TestUtils.getResourceFileContent('dmi-registration.json')
+        def jsonData = TestUtils.getResourceFileContent('dmi_registration_all_singing_and_dancing.json')
         return mvc.perform(post("$dataNodeBaseEndpointNcmpInventory/ch").contentType(MediaType.APPLICATION_JSON).content(jsonData)).andReturn().response
     }
 
diff --git a/cps-ncmp-rest/src/test/resources/dmi-registration.json b/cps-ncmp-rest/src/test/resources/dmi-registration.json
deleted file mode 100644 (file)
index 4f27e11..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "dmiPlugin": "onap-dmi-plugin",
-  "createdCmHandles": [
-    {
-      "cmHandle": "example-name",
-      "cmHandleProperties": {
-        "subSystemId" : "system-001"
-      },
-      "publicCmHandleProperties": {
-          "area" : "south"
-        }
-    }
-  ]
-}
\ No newline at end of file
diff --git a/cps-ncmp-rest/src/test/resources/dmi_registration_all_singing_and_dancing.json b/cps-ncmp-rest/src/test/resources/dmi_registration_all_singing_and_dancing.json
new file mode 100644 (file)
index 0000000..fd8b56b
--- /dev/null
@@ -0,0 +1,43 @@
+{
+  "dmiDataPlugin":"service2",
+  "dmiModelPlugin":"service3",
+  "createdCmHandles":[
+    {
+      "cmHandle":"ch1(new)",
+      "cmHandleProperties":{
+        "dmiProp1":"ch1-dmi1",
+        "dmiProp2":"ch1-dmi2"
+      },
+      "publicCmHandleProperties":{
+        "pubProp1":"ch1-pub1",
+        "pubProp2":"ch1-pub2"
+      }
+    },
+    {
+      "cmHandle":"ch2(new)",
+      "cmHandleProperties":{
+        "dmiProp1":"ch2-dmi1",
+        "dmiProp2":"ch2-dmi2"
+      },
+      "publicCmHandleProperties":{
+        "pubProp1":"ch2-pub1",
+        "pubProp2":"ch2-pub2"
+      }
+    }
+  ],
+  "updatedCmHandles":[
+    {
+      "cmHandle":"ch3(upd)",
+      "cmHandleProperties":{
+        "dmiProp1":"ch3-dmi1"
+      },
+      "publicCmHandleProperties":{
+        "pubProp2":"ch3-pub1"
+      }
+    }
+  ],
+  "removedCmHandles":[
+    "ch4",
+    "ch5"
+  ]
+}
diff --git a/cps-ncmp-rest/src/test/resources/dmi_registration_combined_valid.json b/cps-ncmp-rest/src/test/resources/dmi_registration_combined_valid.json
deleted file mode 100644 (file)
index bded4f2..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "dmiPlugin": "service1",
-  "dmiDataPlugin": "",
-  "dmiModelPlugin": "",
-  "createdCmHandles": [{
-    "cmHandle": "example-name"
-  }]
-}
\ No newline at end of file
diff --git a/cps-ncmp-rest/src/test/resources/dmi_registration_updates_only.json b/cps-ncmp-rest/src/test/resources/dmi_registration_updates_only.json
new file mode 100644 (file)
index 0000000..58a1a98
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "dmiPlugin": "service1",
+  "updatedCmHandles":[
+    {
+      "cmHandle":"ch3(upd)",
+      "cmHandleProperties":{
+        "dmiProp1":"ch3-dmi1",
+        "dmiProp2":null
+      }
+    }
+  ]
+}
diff --git a/cps-ncmp-rest/src/test/resources/dmi_registration_without_properties.json b/cps-ncmp-rest/src/test/resources/dmi_registration_without_properties.json
new file mode 100644 (file)
index 0000000..395c098
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "dmiPlugin":"",
+  "dmiDataPlugin":"service2",
+  "dmiModelPlugin":"service3",
+  "createdCmHandles":[
+    {
+      "cmHandle": "ch1(new)"
+    }
+  ]
+}
index aac44e4..446e45b 100755 (executable)
@@ -81,15 +81,13 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     public void updateDmiRegistrationAndSyncModule(final DmiPluginRegistration dmiPluginRegistration) {
         dmiPluginRegistration.validateDmiPluginRegistration();
         try {
-            if (dmiPluginRegistration.getCreatedCmHandles() != null) {
+            if (!dmiPluginRegistration.getCreatedCmHandles().isEmpty()) {
                 parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(dmiPluginRegistration);
             }
-            if (dmiPluginRegistration.getUpdatedCmHandles() != null) {
+            if (!dmiPluginRegistration.getUpdatedCmHandles().isEmpty()) {
                 parseAndUpdateCmHandlesInDmiRegistration(dmiPluginRegistration);
             }
-            if (dmiPluginRegistration.getRemovedCmHandles() != null) {
-                parseAndRemoveCmHandlesInDmiRegistration(dmiPluginRegistration);
-            }
+            parseAndRemoveCmHandlesInDmiRegistration(dmiPluginRegistration);
         } catch (final JsonProcessingException | DataNodeNotFoundException e) {
             final String errorMessage = String.format(
                     "Error occurred while processing the CM-handle registration request, caused by : [%s]",
index 9a9b6fa..88c6f33 100644 (file)
@@ -20,7 +20,6 @@
 
 package org.onap.cps.ncmp.api.models;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 import com.fasterxml.jackson.annotation.Nulls;
 import java.util.Collections;
@@ -39,15 +38,12 @@ import org.springframework.validation.annotation.Validated;
 @NoArgsConstructor
 public class CmHandle {
 
-    @JsonProperty("cmHandle")
     private String cmHandleID;
 
     @JsonSetter(nulls = Nulls.AS_EMPTY)
-    @JsonProperty("cmHandleProperties")
     private Map<String, String> dmiProperties = Collections.emptyMap();
 
     @JsonSetter(nulls = Nulls.AS_EMPTY)
-    @JsonProperty("publicCmHandleProperties")
     private Map<String, String> publicProperties = Collections.emptyMap();
 
 }
index f1b3888..c302f7d 100644 (file)
@@ -22,9 +22,8 @@ package org.onap.cps.ncmp.api.models;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.annotation.JsonSetter;
-import com.fasterxml.jackson.annotation.Nulls;
 import com.google.common.base.Strings;
+import java.util.Collections;
 import java.util.List;
 import lombok.Getter;
 import lombok.Setter;
@@ -39,20 +38,17 @@ import org.onap.cps.ncmp.api.impl.exception.NcmpException;
 @JsonInclude(Include.NON_NULL)
 public class DmiPluginRegistration {
 
-    @JsonSetter(nulls = Nulls.AS_EMPTY)
     private String dmiPlugin;
 
-    @JsonSetter(nulls = Nulls.AS_EMPTY)
     private String dmiDataPlugin;
 
-    @JsonSetter(nulls = Nulls.AS_EMPTY)
     private String dmiModelPlugin;
 
-    private List<CmHandle> createdCmHandles;
+    private List<CmHandle> createdCmHandles = Collections.emptyList();
 
-    private List<CmHandle> updatedCmHandles;
+    private List<CmHandle> updatedCmHandles = Collections.emptyList();
 
-    private List<String> removedCmHandles;
+    private List<String> removedCmHandles = Collections.emptyList();
 
     /**
      * Validates plugin service names.
index d4f6e95..9762ac4 100644 (file)
@@ -30,7 +30,7 @@ import lombok.Getter;
 public class PersistenceCmHandlesList {
 
     @JsonProperty("cm-handles")
-    private List<PersistenceCmHandle> persistenceCmHandles = new ArrayList<>();
+    private final List<PersistenceCmHandle> persistenceCmHandles = new ArrayList<>();
 
     /**
      * Create a PersistenceCmHandleList given all service names and a collection of cmHandles.
index 00fda14..a475f9c 100644 (file)
@@ -76,19 +76,19 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             expectedCallsToSaveNode * mockCpsDataService.saveListElements('NCMP-Admin', 'ncmp-dmi-registry',
                 '/dmi-registry', expectedJsonData, noTimestamp)
         and: 'update data node leaves is called with correct parameters'
-            expectedCallsToPropertyHandler * mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(updatedCmHandles)
+            expectedCallsToUpdateCmHandleProperty * mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(updatedCmHandles)
         and: 'delete schema set is invoked with the correct parameters'
             expectedCallsToDeleteSchemaSetAndListElement * mockCpsModuleService.deleteSchemaSet('NFP-Operational', 'cmHandle001', CASCADE_DELETE_ALLOWED)
         and: 'delete list or list element is invoked with the correct parameters'
             expectedCallsToDeleteSchemaSetAndListElement * mockCpsDataService.deleteListOrListElement('NCMP-Admin',
                 'ncmp-dmi-registry', "/dmi-registry/cm-handles[@id='cmHandle001']", noTimestamp)
         where:
-            scenario                    | createdCmHandles      | updatedCmHandles      | removedCmHandles || expectedCallsToSaveNode | expectedCallsToDeleteSchemaSetAndListElement | expectedCallsToPropertyHandler
-            'create'                    | [persistenceCmHandle] | []                    | []               || 1                       | 0                                            | 1
+            scenario                    | createdCmHandles      | updatedCmHandles      | removedCmHandles || expectedCallsToSaveNode | expectedCallsToDeleteSchemaSetAndListElement | expectedCallsToUpdateCmHandleProperty
+            'create'                    | [persistenceCmHandle] | []                    | []               || 1                       | 0                                            | 0
             'update'                    | []                    | [persistenceCmHandle] | []               || 0                       | 0                                            | 1
-            'delete'                    | []                    | []                    | cmHandlesArray   || 0                       | 1                                            | 1
+            'delete'                    | []                    | []                    | cmHandlesArray   || 0                       | 1                                            | 0
             'create, update and delete' | [persistenceCmHandle] | [persistenceCmHandle] | cmHandlesArray   || 1                       | 1                                            | 1
-            'no valid data'             | null                  | null                  | null             || 0                       | 0                                            | 0
+            'no valid data'             | []                    | []                    | []               || 0                       | 0                                            | 0
     }
 
     def 'Register a DMI Plugin for the given cm-handle(s) without DMI properties.'() {
@@ -107,22 +107,17 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
                     '/dmi-registry', expectedJsonData, noTimestamp)
     }
 
-    def 'Register a DMI Plugin for a given cm-handle(s) with JSON processing errors during #scenario process.'() {
+    def 'Register a DMI Plugin for a given cm-handle(s) with JSON processing errors during process.'() {
         given: 'a registration without cm-handle properties '
             NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:'some-plugin')
-            dmiPluginRegistration.createdCmHandles = createdCmHandles
-            dmiPluginRegistration.updatedCmHandles = updatedCmHandles
+            dmiPluginRegistration.createdCmHandles = [persistenceCmHandle]
         and: 'an json processing exception occurs'
             spiedJsonObjectMapper.asJsonString(_) >> { throw (new JsonProcessingException('')) }
         when: 'registration is updated and modules are synced'
             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
         then: 'a data validation exception is thrown'
             thrown(DataValidationException)
-        where:
-            scenario | createdCmHandles      | updatedCmHandles
-            'create' | [persistenceCmHandle] | []
-            'update' | []                    | [persistenceCmHandle]
     }
 
     def 'Register a DMI Plugin for the given cm-handle(s) with no data found during delete process.'() {
index 99b9caa..5021f77 100644 (file)
@@ -34,7 +34,7 @@ ${auth}                   Basic Y3BzdXNlcjpjcHNyMGNrcyE=
 ${ncmpInventoryBasePath}  /ncmpInventory
 ${ncmpBasePath}           /ncmp
 ${dmiUrl}                 http://${DMI_HOST}:${DMI_PORT}
-${jsonData}               {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":null,"dmiModelPlugin":null,"createdCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Sci-Fi Book"},"publicCmHandleProperties":{"Contact":"storeemail@bookstore.com"}}],"updatedCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Romance Book"},"publicCmHandleProperties":{"Contact":"newemailforstore@bookstore.com"}}]}
+${jsonData}               {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","createdCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Sci-Fi Book"},"publicCmHandleProperties":{"Contact":"storeemail@bookstore.com"}}],"updatedCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Romance Book"},"publicCmHandleProperties":{"Contact":"newemailforstore@bookstore.com"}}]}
 
 *** Test Cases ***
 Register node, update data node and sync modules.