From d5bda8848a661465f214b0bf11211e63b272cfd6 Mon Sep 17 00:00:00 2001 From: lukegleeson Date: Wed, 2 Mar 2022 14:32:47 +0000 Subject: [PATCH] Replacing ModelMapper with MapStruct - 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 Change-Id: I43f874aea79f58dda5526c6fdead27d8474d90af --- cps-dependencies/pom.xml | 6 +- cps-ncmp-rest/docs/openapi/components.yaml | 2 +- cps-ncmp-rest/docs/openapi/ncmp.yml | 2 +- ...stInputMapper.java => NcmpRestInputMapper.java} | 22 +++++-- .../rest/controller/NetworkCmProxyController.java | 13 ++-- .../NetworkCmProxyInventoryController.java | 4 +- ...rSpec.groovy => NcmpRestInputMapperSpec.groovy} | 30 +++++++++- .../controller/NetworkCmProxyControllerSpec.groovy | 7 +-- .../NetworkCmProxyInventoryControllerSpec.groovy | 4 +- .../NetworkCmProxyRestExceptionHandlerSpec.groovy | 11 ++-- cps-ncmp-service/pom.xml | 4 -- cps-rest/docs/openapi/components.yml | 2 + cps-rest/pom.xml | 9 ++- .../main/java/org/onap/cps/config/CpsConfig.java | 41 ------------- .../cps/rest/controller/AdminRestController.java | 25 ++++---- .../cps/rest/controller/CpsRestInputMapper.java} | 30 ++++++---- .../rest/controller/AdminRestControllerSpec.groovy | 14 ++--- .../rest/controller/CpsRestInputMapperSpec.groovy | 69 ++++++++++++++++++++++ .../exceptions/CpsRestExceptionHandlerSpec.groovy | 8 ++- cps-ri/pom.xml | 6 +- jacoco-report/pom.xml | 3 + 21 files changed, 188 insertions(+), 124 deletions(-) rename cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/{RestInputMapper.java => NcmpRestInputMapper.java} (63%) rename cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/{RestInputMapperSpec.groovy => NcmpRestInputMapperSpec.groovy} (69%) delete mode 100755 cps-rest/src/main/java/org/onap/cps/config/CpsConfig.java rename cps-rest/src/{test/groovy/org/onap/cps/config/CpsConfigSpec.groovy => main/java/org/onap/cps/rest/controller/CpsRestInputMapper.java} (51%) create mode 100644 cps-rest/src/test/groovy/org/onap/cps/rest/controller/CpsRestInputMapperSpec.groovy diff --git a/cps-dependencies/pom.xml b/cps-dependencies/pom.xml index 80513ba94..f04213d43 100755 --- a/cps-dependencies/pom.xml +++ b/cps-dependencies/pom.xml @@ -2,6 +2,7 @@ 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 index 4f4501afb..000000000 --- a/cps-rest/src/main/java/org/onap/cps/config/CpsConfig.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. - * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2021 Bell Canada. - * ================================================================================ - * 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.config; - -import org.modelmapper.ModelMapper; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.retry.annotation.EnableRetry; - -@Configuration -@EnableRetry -public class CpsConfig { - - /** - * ModelMapper configuration. - */ - @Bean - public ModelMapper modelMapper() { - return new ModelMapper(); - } -} diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java index 52e64a95b..2707d9f29 100755 --- a/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java +++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java @@ -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 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 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> getAnchors(final String dataspaceName) { final Collection anchors = cpsAdminService.getAnchors(dataspaceName); - final List anchorDetails = anchors.stream().map(anchor -> - modelMapper.map(anchor, AnchorDetails.class)).collect(Collectors.toList()); + final List anchorDetails = anchors.stream().map(cpsRestInputMapper::toAnchorDetails) + .collect(Collectors.toList()); return new ResponseEntity<>(anchorDetails, HttpStatus.OK); } } diff --git a/cps-rest/src/test/groovy/org/onap/cps/config/CpsConfigSpec.groovy b/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestInputMapper.java similarity index 51% rename from cps-rest/src/test/groovy/org/onap/cps/config/CpsConfigSpec.groovy rename to cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestInputMapper.java index fc96f0447..d0a4a108c 100644 --- a/cps-rest/src/test/groovy/org/onap/cps/config/CpsConfigSpec.groovy +++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestInputMapper.java @@ -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. @@ -19,16 +18,25 @@ * ============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 - } } diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy index e8cfcfb6f..58a5ebf04 100755 --- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy +++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy @@ -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. @@ -22,17 +22,16 @@ 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 index 000000000..9ff1a9fe9 --- /dev/null +++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/CpsRestInputMapperSpec.groovy @@ -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 + } +} diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy index a2eaa525e..2aa4ddd1e 100644 --- a/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy +++ b/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy @@ -22,12 +22,14 @@ 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 diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml index 37d93156a..6e92894fc 100644 --- a/cps-ri/pom.xml +++ b/cps-ri/pom.xml @@ -3,7 +3,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) 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. @@ -79,10 +79,6 @@ org.projectlombok lombok - - org.modelmapper - modelmapper - org.liquibase liquibase-core diff --git a/jacoco-report/pom.xml b/jacoco-report/pom.xml index 6c2729cc9..d42d89ab0 100644 --- a/jacoco-report/pom.xml +++ b/jacoco-report/pom.xml @@ -61,11 +61,14 @@ org.jacoco jacoco-maven-plugin + org/onap/cps/event/model/* org/onap/cps/rest/model/* org/onap/cps/cpspath/parser/antlr4/* org/onap/cps/ncmp/rest/model/* + org/onap/cps/ncmp/rest/controller/*MapperImpl.class + org/onap/cps/rest/controller/*MapperImpl.class -- 2.16.6