Replacing ModelMapper with MapStruct 89/127489/7
authorlukegleeson <luke.gleeson@est.tech>
Wed, 2 Mar 2022 14:32:47 +0000 (14:32 +0000)
committerlukegleeson <luke.gleeson@est.tech>
Thu, 10 Mar 2022 17:58:57 +0000 (17:58 +0000)
- Removed Model Mapper from pom files
- Replaced ModelMapper with MapStruct
- Added Tests for MapStruct
- Changed mapstruct annotations for individual variables to be null safe rather than all variables
- Excluded generated code from code coverage
- Set ModuleReferences input to required for SchemaSet so that ModuleReferences list set to empty list rather than null

Issue-ID: CPS-127
Signed-off-by: lukegleeson <luke.gleeson@est.tech>
Change-Id: I43f874aea79f58dda5526c6fdead27d8474d90af

21 files changed:
cps-dependencies/pom.xml
cps-ncmp-rest/docs/openapi/components.yaml
cps-ncmp-rest/docs/openapi/ncmp.yml
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapper.java [moved from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java with 63% similarity]
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy [moved from cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy with 69% similarity]
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
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/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
cps-ncmp-service/pom.xml
cps-rest/docs/openapi/components.yml
cps-rest/pom.xml
cps-rest/src/main/java/org/onap/cps/config/CpsConfig.java [deleted file]
cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java
cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestInputMapper.java [moved from cps-rest/src/test/groovy/org/onap/cps/config/CpsConfigSpec.groovy with 51% similarity]
cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy
cps-rest/src/test/groovy/org/onap/cps/rest/controller/CpsRestInputMapperSpec.groovy [new file with mode: 0644]
cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy
cps-ri/pom.xml
jacoco-report/pom.xml

index 80513ba..f04213d 100755 (executable)
@@ -2,6 +2,7 @@
 <!--
   ============LICENSE_START=======================================================
   Copyright (c) 2021 Linux Foundation.
+  Modifications Copyright (C) 2020-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.
                 <artifactId>commons-lang3</artifactId>
                 <version>3.11</version>
             </dependency>
-            <dependency>
-                <groupId>org.modelmapper</groupId>
-                <artifactId>modelmapper</artifactId>
-                <version>2.3.8</version>
-            </dependency>
             <dependency>
                 <groupId>org.jetbrains</groupId>
                 <artifactId>annotations</artifactId>
index d82813b..8343c1c 100644 (file)
@@ -135,7 +135,7 @@ components:
           type: string
           example: my-cm-handle-id
 
-    ModuleReference:
+    RestModuleReference:
       type: object
       title: Module reference details
       properties:
index a267fb4..c096898 100755 (executable)
@@ -224,7 +224,7 @@ fetchModuleReferencesByCmHandle:
             schema:
               type: array
               items:
-                $ref: 'components.yaml#/components/schemas/ModuleReference'
+                $ref: 'components.yaml#/components/schemas/RestModuleReference'
       400:
         $ref: 'components.yaml#/components/responses/BadRequest'
       401:
@@ -22,17 +22,27 @@ package org.onap.cps.ncmp.rest.controller;
 
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
-import org.mapstruct.NullValueMappingStrategy;
+import org.mapstruct.NullValueCheckStrategy;
 import org.mapstruct.NullValuePropertyMappingStrategy;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration;
 import org.onap.cps.ncmp.rest.model.RestInputCmHandle;
+import org.onap.cps.ncmp.rest.model.RestModuleReference;
+import org.onap.cps.spi.model.ModuleReference;
 
-@Mapper(componentModel = "spring", nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT,
-    nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
-public interface RestInputMapper {
+@Mapper(componentModel = "spring")
+public interface NcmpRestInputMapper {
 
+    @Mapping(source = "createdCmHandles", target = "createdCmHandles",
+        nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
+        nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
+    @Mapping(source = "updatedCmHandles", target = "updatedCmHandles",
+        nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
+        nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
+    @Mapping(source = "removedCmHandles", target = "removedCmHandles",
+        nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
+        nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
     DmiPluginRegistration toDmiPluginRegistration(final RestDmiPluginRegistration restDmiPluginRegistration);
 
     @Mapping(source = "cmHandle", target = "cmHandleID")
@@ -40,4 +50,6 @@ public interface RestInputMapper {
     @Mapping(source = "publicCmHandleProperties", target = "publicProperties")
     NcmpServiceCmHandle toNcmpServiceCmHandle(final RestInputCmHandle restInputCmHandle);
 
-}
+    RestModuleReference toRestModuleReference(
+        final ModuleReference moduleReference);
+}
\ No newline at end of file
index 2a336d5..01b8922 100755 (executable)
@@ -37,7 +37,6 @@ import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.modelmapper.ModelMapper;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi;
@@ -49,7 +48,7 @@ import org.onap.cps.ncmp.rest.model.ConditionProperties;
 import org.onap.cps.ncmp.rest.model.Conditions;
 import org.onap.cps.ncmp.rest.model.ModuleNameAsJsonObject;
 import org.onap.cps.ncmp.rest.model.ModuleNamesAsJsonArray;
-import org.onap.cps.ncmp.rest.model.ModuleReference;
+import org.onap.cps.ncmp.rest.model.RestModuleReference;
 import org.onap.cps.ncmp.rest.model.RestOutputCmHandle;
 import org.onap.cps.utils.JsonObjectMapper;
 import org.springframework.http.HttpStatus;
@@ -65,9 +64,9 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
 
     private static final String NO_BODY = null;
 
-    private final ModelMapper modelMapper;
     private final NetworkCmProxyDataService networkCmProxyDataService;
     private final JsonObjectMapper jsonObjectMapper;
+    private final NcmpRestInputMapper ncmpRestInputMapper;
 
     /**
      * Get resource data from operational datastore.
@@ -207,12 +206,12 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
      * @param cmHandle the cm handle
      * @return module references for cm handle. Namespace will be always blank because restConf does not include this.
      */
-    public ResponseEntity<List<ModuleReference>> getModuleReferencesByCmHandle(final String cmHandle) {
-        final List<ModuleReference> moduleReferences =
+    public ResponseEntity<List<RestModuleReference>> getModuleReferencesByCmHandle(final String cmHandle) {
+        final List<RestModuleReference> restModuleReferences =
             networkCmProxyDataService.getYangResourcesModuleReferences(cmHandle).stream()
-            .map(moduleReference -> modelMapper.map(moduleReference, ModuleReference.class))
+            .map(ncmpRestInputMapper::toRestModuleReference)
                 .collect(Collectors.toList());
-        return new ResponseEntity<>(moduleReferences, HttpStatus.OK);
+        return new ResponseEntity<>(restModuleReferences, HttpStatus.OK);
     }
 
     private Collection<String> processConditions(final List<ConditionProperties> conditionProperties) {
index 3699195..c9d26f2 100755 (executable)
@@ -37,7 +37,7 @@ import org.springframework.web.bind.annotation.RestController;
 public class NetworkCmProxyInventoryController implements NetworkCmProxyInventoryApi {
 
     private final NetworkCmProxyDataService networkCmProxyDataService;
-    private final RestInputMapper restInputMapper;
+    private final NcmpRestInputMapper ncmpRestInputMapper;
 
     /**
      * Update DMI Plugin Registration (used for first registration also).
@@ -47,7 +47,7 @@ public class NetworkCmProxyInventoryController implements NetworkCmProxyInventor
     public ResponseEntity<Void> updateDmiPluginRegistration(
         final @Valid RestDmiPluginRegistration restDmiPluginRegistration) {
         networkCmProxyDataService.updateDmiRegistrationAndSyncModule(
-            restInputMapper.toDmiPluginRegistration(restDmiPluginRegistration));
+            ncmpRestInputMapper.toDmiPluginRegistration(restDmiPluginRegistration));
         return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
 package org.onap.cps.ncmp.rest.controller
 
 import org.mapstruct.factory.Mappers
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
 import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration
 import org.onap.cps.ncmp.rest.model.RestInputCmHandle
+import org.onap.cps.ncmp.rest.model.RestModuleReference
+import org.onap.cps.spi.model.ModuleReference
 import spock.lang.Specification
 
-class RestInputMapperSpec extends Specification {
+class NcmpRestInputMapperSpec extends Specification {
 
-    def objectUnderTest = Mappers.getMapper(RestInputMapper.class)
+    def objectUnderTest = Mappers.getMapper(NcmpRestInputMapper.class)
 
     def 'Convert a created REST CM Handle Input to an NCMP Service CM Handle with #scenario'() {
         given: 'a rest cm handle input'
@@ -61,4 +64,27 @@ class RestInputMapperSpec extends Specification {
             assert result.removedCmHandles == []
     }
 
+    def 'Handling non-empty dmi registration'() {
+        given: 'a rest cm handle input with cm handles'
+            def restDmiPluginRegistration = new RestDmiPluginRegistration(
+                createdCmHandles: [new RestInputCmHandle()],
+                updatedCmHandles: [new RestInputCmHandle()],
+                removedCmHandles: ["some-cmHandle"]
+            )
+        when: 'to dmi plugin registration is called'
+            def result  = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration)
+        then: 'Lists contain values'
+            assert result.createdCmHandles[0].class == NcmpServiceCmHandle.class
+            assert result.updatedCmHandles[0].class == NcmpServiceCmHandle.class
+            assert result.removedCmHandles == ["some-cmHandle"]
+    }
+
+    def 'Convert a ModuleReference to a RestModuleReference'() {
+        given: 'a ModuleReference'
+            def moduleReference = new ModuleReference()
+        when: 'toRestModuleReference is called'
+            def result = objectUnderTest.toRestModuleReference(moduleReference)
+        then: 'the result is of the correct class RestModuleReference'
+            result.class == RestModuleReference.class
+    }
 }
index c997714..a506e6a 100644 (file)
@@ -22,7 +22,7 @@
 
 package org.onap.cps.ncmp.rest.controller
 
-
+import org.mapstruct.factory.Mappers
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
 
 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH
@@ -36,7 +36,6 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.DELETE
 
 import com.fasterxml.jackson.databind.ObjectMapper
-import org.modelmapper.ModelMapper
 import org.onap.cps.TestUtils
 import org.onap.cps.spi.model.ModuleReference
 import org.onap.cps.utils.JsonObjectMapper
@@ -60,10 +59,10 @@ class NetworkCmProxyControllerSpec extends Specification {
     NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
 
     @SpringBean
-    ModelMapper modelMapper = new ModelMapper()
+    JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
 
     @SpringBean
-    JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+    NcmpRestInputMapper ncmpRestInputMapper = Mappers.getMapper(NcmpRestInputMapper)
 
     @Value('${rest.api.ncmp-base-path}/v1')
     def ncmpBasePathV1
index 079554a..9b1c2e8 100644 (file)
@@ -49,7 +49,7 @@ class NetworkCmProxyInventoryControllerSpec extends Specification {
     NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
 
     @SpringBean
-    RestInputMapper restInputMapper = Mock()
+    NcmpRestInputMapper ncmpRestInputMapper = Mock()
 
     DmiPluginRegistration mockDmiPluginRegistration = Mock()
 
@@ -64,7 +64,7 @@ class NetworkCmProxyInventoryControllerSpec extends Specification {
         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
+            ncmpRestInputMapper.toDmiPluginRegistration(expectedRestDmiPluginRegistration) >> mockDmiPluginRegistration
         when: 'post request is performed & registration is called with correct DMI plugin information'
             def response = mvc.perform(
                 post("$ncmpBasePathV1/ch")
index 8004328..3c39a33 100644 (file)
 
 package org.onap.cps.ncmp.rest.exceptions
 
+import com.fasterxml.jackson.databind.ObjectMapper
 import groovy.json.JsonSlurper
-import org.modelmapper.ModelMapper
+import org.mapstruct.factory.Mappers
 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.ncmp.api.models.NcmpServiceCmHandle
+import org.onap.cps.ncmp.rest.controller.NcmpRestInputMapper
 import org.onap.cps.spi.exceptions.CpsException
 import org.onap.cps.spi.exceptions.DataNodeNotFoundException
 import org.onap.cps.spi.exceptions.DataValidationException
@@ -57,14 +59,11 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
     @SpringBean
     NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
 
-    @SpringBean
-    ModelMapper modelMapper = Stub()
-
     @SpringBean
     JsonObjectMapper jsonObjectMapper = Stub()
 
     @SpringBean
-    RestInputMapper restInputMapper = Mock()
+    NcmpRestInputMapper ncmpRestInputMapper = Mappers.getMapper(NcmpRestInputMapper)
 
     @Value('${rest.api.ncmp-base-path}')
     def basePathNcmp
index 5145a12..fe061ea 100644 (file)
@@ -66,9 +66,5 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-validation</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.modelmapper</groupId>
-            <artifactId>modelmapper</artifactId>
-        </dependency>
     </dependencies>
 </project>
index ae0326d..269e724 100644 (file)
@@ -73,6 +73,8 @@ components:
     SchemaSetDetails:
       type: object
       title: Schema set details by dataspace and schemasetName
+      required:
+        - "moduleReferences"
       properties:
         dataspaceName:
           type: string
index 20870c3..5a21957 100755 (executable)
@@ -2,6 +2,7 @@
 <!--
   ============LICENSE_START=======================================================
   Copyright (c) 2020 Linux Foundation.
+  Modifications Copyright (C) 2020-2022 Nordix Foundation.
   Modifications Copyright (C) 2021 Bell Canada.
   ================================================================================
   Licensed under the Apache License, Version 2.0 (the "License");
             <artifactId>commons-lang3</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.modelmapper</groupId>
-            <artifactId>modelmapper</artifactId>
+            <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>
diff --git a/cps-rest/src/main/java/org/onap/cps/config/CpsConfig.java b/cps-rest/src/main/java/org/onap/cps/config/CpsConfig.java
deleted file mode 100755 (executable)
index 4f4501a..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*\r
- * ============LICENSE_START=======================================================\r
- * Copyright (C) 2020 Nordix Foundation.\r
- * Modifications Copyright (C) 2021 Pantheon.tech\r
- * Modifications Copyright (C) 2021 Bell Canada.\r
- * ================================================================================\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- * SPDX-License-Identifier: Apache-2.0\r
- * ============LICENSE_END=========================================================\r
- */\r
-\r
-package org.onap.cps.config;\r
-\r
-import org.modelmapper.ModelMapper;\r
-import org.springframework.context.annotation.Bean;\r
-import org.springframework.context.annotation.Configuration;\r
-import org.springframework.retry.annotation.EnableRetry;\r
-\r
-@Configuration\r
-@EnableRetry\r
-public class CpsConfig {\r
-\r
-    /**\r
-     * ModelMapper configuration.\r
-     */\r
-    @Bean\r
-    public ModelMapper modelMapper() {\r
-        return new ModelMapper();\r
-    }\r
-}\r
index 52e64a9..2707d9f 100755 (executable)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2020 Nordix Foundation
+ *  Copyright (C) 2020-2022 Nordix Foundation
  *  Modifications Copyright (C) 2020-2021 Bell Canada.
  *  Modifications Copyright (C) 2021 Pantheon.tech
  *  ================================================================================
@@ -30,7 +30,7 @@ import java.util.List;
 import java.util.stream.Collectors;
 import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
-import org.modelmapper.ModelMapper;
+import lombok.RequiredArgsConstructor;
 import org.onap.cps.api.CpsAdminService;
 import org.onap.cps.api.CpsModuleService;
 import org.onap.cps.rest.api.CpsAdminApi;
@@ -38,7 +38,6 @@ import org.onap.cps.rest.model.AnchorDetails;
 import org.onap.cps.rest.model.SchemaSetDetails;
 import org.onap.cps.spi.model.Anchor;
 import org.onap.cps.spi.model.SchemaSet;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -47,16 +46,12 @@ import org.springframework.web.multipart.MultipartFile;
 
 @RestController
 @RequestMapping("${rest.api.cps-base-path}")
+@RequiredArgsConstructor
 public class AdminRestController implements CpsAdminApi {
 
-    @Autowired
-    private CpsAdminService cpsAdminService;
-
-    @Autowired
-    private CpsModuleService cpsModuleService;
-
-    @Autowired
-    private ModelMapper modelMapper;
+    private final CpsAdminService cpsAdminService;
+    private final CpsModuleService cpsModuleService;
+    private final CpsRestInputMapper cpsRestInputMapper;
 
     /**
      * Create a dataspace.
@@ -107,7 +102,7 @@ public class AdminRestController implements CpsAdminApi {
     @Override
     public ResponseEntity<SchemaSetDetails> getSchemaSet(final String dataspaceName, final String schemaSetName) {
         final var schemaSet = cpsModuleService.getSchemaSet(dataspaceName, schemaSetName);
-        final var schemaSetDetails = modelMapper.map(schemaSet, SchemaSetDetails.class);
+        final var schemaSetDetails = cpsRestInputMapper.toSchemaSetDetails(schemaSet);
         return new ResponseEntity<>(schemaSetDetails, HttpStatus.OK);
     }
 
@@ -162,7 +157,7 @@ public class AdminRestController implements CpsAdminApi {
     @Override
     public ResponseEntity<AnchorDetails> getAnchor(final String dataspaceName, final String anchorName) {
         final var anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
-        final var anchorDetails = modelMapper.map(anchor, AnchorDetails.class);
+        final var anchorDetails = cpsRestInputMapper.toAnchorDetails(anchor);
         return new ResponseEntity<>(anchorDetails, HttpStatus.OK);
     }
 
@@ -175,8 +170,8 @@ public class AdminRestController implements CpsAdminApi {
     @Override
     public ResponseEntity<List<AnchorDetails>> getAnchors(final String dataspaceName) {
         final Collection<Anchor> anchors = cpsAdminService.getAnchors(dataspaceName);
-        final List<AnchorDetails> anchorDetails = anchors.stream().map(anchor ->
-            modelMapper.map(anchor, AnchorDetails.class)).collect(Collectors.toList());
+        final List<AnchorDetails> anchorDetails = anchors.stream().map(cpsRestInputMapper::toAnchorDetails)
+            .collect(Collectors.toList());
         return new ResponseEntity<>(anchorDetails, HttpStatus.OK);
     }
 }
@@ -1,7 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2021 Nordix Foundation
- *  Modifications Copyright (C) 2021 Bell Canada.
+ *  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.
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.config
+package org.onap.cps.rest.controller;
 
-import org.modelmapper.ModelMapper
-import spock.lang.Specification
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.NullValueCheckStrategy;
+import org.mapstruct.NullValuePropertyMappingStrategy;
+import org.onap.cps.rest.model.AnchorDetails;
+import org.onap.cps.rest.model.SchemaSetDetails;
+import org.onap.cps.spi.model.Anchor;
+import org.onap.cps.spi.model.SchemaSet;
 
-class CpsConfigSpec extends Specification {
-    def objectUnderTest = new CpsConfig()
+@Mapper(componentModel = "spring")
+public interface CpsRestInputMapper {
+
+    @Mapping(source = "moduleReferences", target = "moduleReferences",
+        nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
+        nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
+    SchemaSetDetails toSchemaSetDetails(final SchemaSet schemaSet);
+
+    AnchorDetails toAnchorDetails(final Anchor anchor);
 
-    def 'CPS configuration has a Model Mapper'() {
-        expect: 'the CPS configuration has a Model Mapper'
-            objectUnderTest.modelMapper() instanceof ModelMapper
-    }
 }
index e8cfcfb..58a5ebf 100755 (executable)
@@ -2,7 +2,7 @@
  *  ============LICENSE_START=======================================================
  *  Copyright (C) 2020-2021 Pantheon.tech
  *  Modifications Copyright (C) 2020-2021 Bell Canada.
- *  Modifications Copyright (C) 2021 Nordix Foundation
+ *  Modifications Copyright (C) 2021-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.
 
 package org.onap.cps.rest.controller
 
+import org.mapstruct.factory.Mappers
+
 import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
 
-import org.modelmapper.ModelMapper
 import org.onap.cps.api.CpsAdminService
-import org.onap.cps.api.CpsDataService
 import org.onap.cps.api.CpsModuleService
-import org.onap.cps.api.CpsQueryService
 import org.onap.cps.spi.exceptions.AlreadyDefinedException
 import org.onap.cps.spi.exceptions.SchemaSetInUseException
 import org.onap.cps.spi.model.Anchor
@@ -59,7 +58,7 @@ class AdminRestControllerSpec extends Specification {
     CpsAdminService mockCpsAdminService = Mock()
 
     @SpringBean
-    ModelMapper modelMapper = Spy()
+    CpsRestInputMapper cpsRestInputMapper = Mappers.getMapper(CpsRestInputMapper)
 
     @Autowired
     MockMvc mvc
@@ -68,10 +67,9 @@ class AdminRestControllerSpec extends Specification {
     def basePath
 
     def dataspaceName = 'my_dataspace'
-    def anchor = new Anchor(name: 'my_anchor')
-    def anchorList = [anchor]
     def anchorName = 'my_anchor'
     def schemaSetName = 'my_schema_set'
+    def anchor = new Anchor(name: anchorName, dataspaceName: dataspaceName, schemaSetName: schemaSetName)
 
     def 'Create new dataspace.'() {
         given: 'an endpoint'
@@ -274,7 +272,7 @@ class AdminRestControllerSpec extends Specification {
 
     def 'Get existing anchor.'() {
         given: 'service method returns a list of anchors'
-            mockCpsAdminService.getAnchors(dataspaceName) >> anchorList
+            mockCpsAdminService.getAnchors(dataspaceName) >> [anchor]
         and: 'an endpoint'
             def anchorEndpoint = "$basePath/v1/dataspaces/$dataspaceName/anchors"
         when: 'get all anchors API is invoked'
diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/CpsRestInputMapperSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/CpsRestInputMapperSpec.groovy
new file mode 100644 (file)
index 0000000..9ff1a9f
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  ============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.rest.controller
+
+import org.mapstruct.factory.Mappers
+import org.onap.cps.rest.model.AnchorDetails
+import org.onap.cps.rest.model.SchemaSetDetails
+import org.onap.cps.spi.model.Anchor
+import org.onap.cps.rest.model.ModuleReferences
+import org.onap.cps.spi.model.ModuleReference
+import org.onap.cps.spi.model.SchemaSet
+import spock.lang.Specification
+
+class CpsRestInputMapperSpec extends Specification {
+
+    def objectUnderTest = Mappers.getMapper(CpsRestInputMapper.class)
+
+    def 'Convert a SchemaSet to a SchemaSetDetails a ModuleReference'() {
+        given: 'a ModuleReference'
+            def moduleReference = new ModuleReference()
+        and: 'a SchemaSet containing the ModuleReference'
+            def schemaSet = new SchemaSet(name: 'some-schema-set', dataspaceName: 'some-dataspace',
+                moduleReferences: [moduleReference])
+        when: 'to schemaSetDetails is called'
+            def result = objectUnderTest.toSchemaSetDetails(schemaSet)
+        then: 'the result returns a SchemaSetDetails'
+            result.class == SchemaSetDetails.class
+        and: 'the results ModuleReferences are of type ModuleReference'
+            result.moduleReferences[0].class == ModuleReferences.class
+    }
+
+    def 'Convert a schemaSet to a SchemaSetDetails without an ModuleReference'() {
+        given: 'a SchemaSet'
+            def schemaSet = new SchemaSet()
+        when: 'to schemaSetDetails is called'
+            def result = objectUnderTest.toSchemaSetDetails(schemaSet)
+        then: 'the result returns a SchemaSetDetails'
+            result.class == SchemaSetDetails.class
+        and: 'the ModuleReferences of SchemaSetDetails is an empty collection'
+            result.moduleReferences.size() == 0
+    }
+
+    def 'Convert an Anchor to an AnchorDetails'() {
+        given: 'an Anchor'
+            def anchor = new Anchor()
+        when: 'to anchorDetails is called'
+            def result = objectUnderTest.toAnchorDetails(anchor)
+        then: 'the result returns an AnchorDetails'
+            result.class == AnchorDetails.class
+    }
+}
index a2eaa52..2aa4ddd 100644 (file)
 
 package org.onap.cps.rest.exceptions
 
+import com.fasterxml.jackson.databind.ObjectMapper
 import groovy.json.JsonSlurper
-import org.modelmapper.ModelMapper
+import org.mapstruct.factory.Mappers
 import org.onap.cps.api.CpsAdminService
 import org.onap.cps.api.CpsDataService
 import org.onap.cps.api.CpsModuleService
 import org.onap.cps.api.CpsQueryService
+import org.onap.cps.rest.controller.CpsRestInputMapper
 import org.onap.cps.spi.exceptions.AlreadyDefinedException
 import org.onap.cps.spi.exceptions.CpsException
 import org.onap.cps.spi.exceptions.CpsPathException
@@ -71,10 +73,10 @@ class CpsRestExceptionHandlerSpec extends Specification {
     CpsQueryService mockCpsQueryService = Stub()
 
     @SpringBean
-    ModelMapper modelMapper = Stub()
+    JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
 
     @SpringBean
-    JsonObjectMapper jsonObjectMapper = Stub()
+    CpsRestInputMapper cpsRestInputMapper = Stub()
 
     @Autowired
     MockMvc mvc
index 37d9315..6e92894 100644 (file)
@@ -3,7 +3,7 @@
   ============LICENSE_START=======================================================\r
   Copyright (C) 2020-2021 Pantheon.tech\r
   Modifications Copyright (C) 2020-2021 Bell Canada\r
-  Modifications Copyright (C) 2021 Nordix Foundation\r
+  Modifications Copyright (C) 2020-2022 Nordix Foundation\r
   ================================================================================\r
   Licensed under the Apache License, Version 2.0 (the "License");\r
   you may not use this file except in compliance with the License.\r
             <groupId>org.projectlombok</groupId>\r
             <artifactId>lombok</artifactId>\r
         </dependency>\r
-        <dependency>\r
-            <groupId>org.modelmapper</groupId>\r
-            <artifactId>modelmapper</artifactId>\r
-        </dependency>\r
         <dependency>\r
             <groupId>org.liquibase</groupId>\r
             <artifactId>liquibase-core</artifactId>\r
index 6c2729c..d42d89a 100644 (file)
                 <groupId>org.jacoco</groupId>
                 <artifactId>jacoco-maven-plugin</artifactId>
                 <configuration>
+                <!--All exclusions below are referring to generated code-->
                     <excludes>
                         <exclude>org/onap/cps/event/model/*</exclude>
                         <exclude>org/onap/cps/rest/model/*</exclude>
                         <exclude>org/onap/cps/cpspath/parser/antlr4/*</exclude>
                         <exclude>org/onap/cps/ncmp/rest/model/*</exclude>
+                        <exclude>org/onap/cps/ncmp/rest/controller/*MapperImpl.class</exclude>
+                        <exclude>org/onap/cps/rest/controller/*MapperImpl.class</exclude>
                     </excludes>
                 </configuration>
                 <executions>