From a966bab93a17fcba4e7fc28354c01b3f0878fbbe Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Mon, 18 Dec 2023 12:25:41 +0000 Subject: Remove the dependency-cycle between beans - Splitting admin service into AnchorService and DataspaceService (this resolves the cyclic dependency) - Improved Delete dataspace integration error tests (were depending on execution order, now independent) Issue-ID: CPS-871 Change-Id: I47efedb6eb4bd2900f72d689616b7b7b62df2938 Signed-off-by: halil.cakal Signed-off-by: ToineSiebelink --- .../cps/rest/controller/AdminRestController.java | 26 +++++++------ .../rest/controller/AdminRestControllerSpec.groovy | 44 ++++++++++++---------- .../exceptions/CpsRestExceptionHandlerSpec.groovy | 10 +++-- 3 files changed, 46 insertions(+), 34 deletions(-) (limited to 'cps-rest') 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 993dad58c..9b78f8520 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 @@ -33,7 +33,8 @@ import java.util.Collection; import java.util.List; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; -import org.onap.cps.api.CpsAdminService; +import org.onap.cps.api.CpsAnchorService; +import org.onap.cps.api.CpsDataspaceService; import org.onap.cps.api.CpsModuleService; import org.onap.cps.rest.api.CpsAdminApi; import org.onap.cps.rest.model.AnchorDetails; @@ -53,9 +54,10 @@ import org.springframework.web.multipart.MultipartFile; @RequiredArgsConstructor public class AdminRestController implements CpsAdminApi { - private final CpsAdminService cpsAdminService; + private final CpsDataspaceService cpsDataspaceService; private final CpsModuleService cpsModuleService; private final CpsRestInputMapper cpsRestInputMapper; + private final CpsAnchorService cpsAnchorService; /** * Create a dataspace. @@ -65,7 +67,7 @@ public class AdminRestController implements CpsAdminApi { */ @Override public ResponseEntity createDataspace(@NotNull @Valid final String dataspaceName) { - cpsAdminService.createDataspace(dataspaceName); + cpsDataspaceService.createDataspace(dataspaceName); return new ResponseEntity<>(dataspaceName, HttpStatus.CREATED); } @@ -77,7 +79,7 @@ public class AdminRestController implements CpsAdminApi { */ @Override public ResponseEntity createDataspaceV2(@NotNull @Valid final String dataspaceName) { - cpsAdminService.createDataspace(dataspaceName); + cpsDataspaceService.createDataspace(dataspaceName); return new ResponseEntity<>(HttpStatus.CREATED); } @@ -89,7 +91,7 @@ public class AdminRestController implements CpsAdminApi { */ @Override public ResponseEntity deleteDataspace(final String apiVersion, final String dataspaceName) { - cpsAdminService.deleteDataspace(dataspaceName); + cpsDataspaceService.deleteDataspace(dataspaceName); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } @@ -184,7 +186,7 @@ public class AdminRestController implements CpsAdminApi { @Override public ResponseEntity createAnchor(final String dataspaceName, @NotNull @Valid final String schemaSetName, @NotNull @Valid final String anchorName) { - cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorName); + cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorName); return new ResponseEntity<>(anchorName, HttpStatus.CREATED); } @@ -199,7 +201,7 @@ public class AdminRestController implements CpsAdminApi { @Override public ResponseEntity createAnchorV2(final String dataspaceName, @NotNull @Valid final String schemaSetName, @NotNull @Valid final String anchorName) { - cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorName); + cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorName); return new ResponseEntity<>(HttpStatus.CREATED); } @@ -214,7 +216,7 @@ public class AdminRestController implements CpsAdminApi { @Override public ResponseEntity deleteAnchor(final String apiVersion, final String dataspaceName, final String anchorName) { - cpsAdminService.deleteAnchor(dataspaceName, anchorName); + cpsAnchorService.deleteAnchor(dataspaceName, anchorName); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } @@ -229,7 +231,7 @@ public class AdminRestController implements CpsAdminApi { @Override public ResponseEntity getAnchor(final String apiVersion, final String dataspaceName, final String anchorName) { - final var anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); + final var anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName); final var anchorDetails = cpsRestInputMapper.toAnchorDetails(anchor); return new ResponseEntity<>(anchorDetails, HttpStatus.OK); } @@ -244,7 +246,7 @@ public class AdminRestController implements CpsAdminApi { @Override public ResponseEntity> getAnchors(final String apiVersion, final String dataspaceName) { - final Collection anchors = cpsAdminService.getAnchors(dataspaceName); + final Collection anchors = cpsAnchorService.getAnchors(dataspaceName); final List anchorDetails = anchors.stream().map(cpsRestInputMapper::toAnchorDetails) .collect(Collectors.toList()); return new ResponseEntity<>(anchorDetails, HttpStatus.OK); @@ -252,7 +254,7 @@ public class AdminRestController implements CpsAdminApi { @Override public ResponseEntity> getAllDataspaces(final String apiVersion) { - final Collection dataspaces = cpsAdminService.getAllDataspaces(); + final Collection dataspaces = cpsDataspaceService.getAllDataspaces(); final List dataspaceDetails = dataspaces.stream().map(cpsRestInputMapper::toDataspaceDetails) .collect(Collectors.toList()); return new ResponseEntity<>(dataspaceDetails, HttpStatus.OK); @@ -260,7 +262,7 @@ public class AdminRestController implements CpsAdminApi { @Override public ResponseEntity getDataspace(final String apiVersion, final String dataspaceName) { - final Dataspace dataspace = cpsAdminService.getDataspace(dataspaceName); + final Dataspace dataspace = cpsDataspaceService.getDataspace(dataspaceName); final DataspaceDetails dataspaceDetails = cpsRestInputMapper.toDataspaceDetails(dataspace); return new ResponseEntity<>(dataspaceDetails, HttpStatus.OK); } 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 f81efd669..81ac511a9 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 @@ -23,6 +23,8 @@ package org.onap.cps.rest.controller +import org.onap.cps.api.CpsAnchorService + 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 @@ -30,7 +32,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post import org.mapstruct.factory.Mappers -import org.onap.cps.api.CpsAdminService +import org.onap.cps.api.CpsDataspaceService import org.onap.cps.api.CpsModuleService import org.onap.cps.spi.exceptions.AlreadyDefinedException import org.onap.cps.spi.exceptions.SchemaSetInUseException @@ -56,7 +58,10 @@ class AdminRestControllerSpec extends Specification { CpsModuleService mockCpsModuleService = Mock() @SpringBean - CpsAdminService mockCpsAdminService = Mock() + CpsDataspaceService mockCpsDataspaceService = Mock() + + @SpringBean + CpsAnchorService mockCpsAnchorService = Mock() @SpringBean CpsRestInputMapper cpsRestInputMapper = Mappers.getMapper(CpsRestInputMapper) @@ -76,26 +81,27 @@ class AdminRestControllerSpec extends Specification { def 'Create new dataspace with #scenario.'() { when: 'post is invoked' def response = - mvc.perform( - post("/cps/api/${apiVersion}/dataspaces") - .param('dataspace-name', dataspaceName)) - .andReturn().response + mvc.perform( + post("/cps/api/${apiVersion}/dataspaces") + .param('dataspace-name', dataspaceName)) + .andReturn().response then: 'service method is invoked with expected parameters' - 1 * mockCpsAdminService.createDataspace(dataspaceName) + 1 * mockCpsDataspaceService.createDataspace(dataspaceName) and: 'dataspace is create successfully' response.status == HttpStatus.CREATED.value() assert response.getContentAsString() == expectedResponseBody where: 'following cases are tested' - scenario | apiVersion || expectedResponseBody - 'V1 API' | 'v1' || 'my_dataspace' - 'V2 API' | 'v2' || '' - } + scenario | apiVersion || expectedResponseBody + 'V1 API' | 'v1' || 'my_dataspace' + 'V2 API' | 'v2' || '' + } + def 'Create dataspace over existing with same name.'() { given: 'an endpoint' def createDataspaceEndpoint = "$basePath/v1/dataspaces" and: 'the service method throws an exception indicating the dataspace is already defined' def thrownException = new AlreadyDefinedException(dataspaceName, new RuntimeException()) - mockCpsAdminService.createDataspace(dataspaceName) >> { throw thrownException } + mockCpsDataspaceService.createDataspace(dataspaceName) >> { throw thrownException } when: 'post is invoked' def response = mvc.perform( @@ -108,7 +114,7 @@ class AdminRestControllerSpec extends Specification { def 'Get a dataspace.'() { given: 'service method returns a dataspace' - mockCpsAdminService.getDataspace(dataspaceName) >> dataspace + mockCpsDataspaceService.getDataspace(dataspaceName) >> dataspace and: 'an endpoint' def getDataspaceEndpoint = "$basePath/v1/admin/dataspaces/$dataspaceName" when: 'get dataspace API is invoked' @@ -120,7 +126,7 @@ class AdminRestControllerSpec extends Specification { def 'Get all dataspaces.'() { given: 'service method returns all dataspace' - mockCpsAdminService.getAllDataspaces() >> [dataspace, new Dataspace(name: "dataspace-test2")] + mockCpsDataspaceService.getAllDataspaces() >> [dataspace, new Dataspace(name: "dataspace-test2")] and: 'an endpoint' def getAllDataspaceEndpoint = "$basePath/v1/admin/dataspaces" when: 'get all dataspace API is invoked' @@ -317,7 +323,7 @@ class AdminRestControllerSpec extends Specification { .params(requestParams as MultiValueMap)) .andReturn().response then: 'anchor is created successfully' - 1 * mockCpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorName) + 1 * mockCpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorName) assert response.status == HttpStatus.CREATED.value() assert response.getContentAsString() == expectedResponseBody where: 'following cases are tested' @@ -328,7 +334,7 @@ class AdminRestControllerSpec extends Specification { def 'Get existing anchor.'() { given: 'service method returns a list of anchors' - mockCpsAdminService.getAnchors(dataspaceName) >> [anchor] + mockCpsAnchorService.getAnchors(dataspaceName) >> [anchor] and: 'an endpoint' def anchorEndpoint = "$basePath/v1/dataspaces/$dataspaceName/anchors" when: 'get all anchors API is invoked' @@ -340,7 +346,7 @@ class AdminRestControllerSpec extends Specification { def 'Get existing anchor by dataspace and anchor name.'() { given: 'service method returns an anchor' - mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> + mockCpsAnchorService.getAnchor(dataspaceName, anchorName) >> new Anchor(name: anchorName, dataspaceName: dataspaceName, schemaSetName: schemaSetName) and: 'an endpoint' def anchorEndpoint = "$basePath/v1/dataspaces/$dataspaceName/anchors/$anchorName" @@ -360,7 +366,7 @@ class AdminRestControllerSpec extends Specification { when: 'delete method is invoked on anchor endpoint' def response = mvc.perform(delete(anchorEndpoint)).andReturn().response then: 'associated service method is invoked with expected parameters' - 1 * mockCpsAdminService.deleteAnchor(dataspaceName, anchorName) + 1 * mockCpsAnchorService.deleteAnchor(dataspaceName, anchorName) and: 'response code indicates success' response.status == HttpStatus.NO_CONTENT.value() } @@ -373,7 +379,7 @@ class AdminRestControllerSpec extends Specification { .param('dataspace-name', dataspaceName)) .andReturn().response then: 'associated service method is invoked with expected parameter' - 1 * mockCpsAdminService.deleteDataspace(dataspaceName) + 1 * mockCpsDataspaceService.deleteDataspace(dataspaceName) and: 'response code indicates success' response.status == HttpStatus.NO_CONTENT.value() } 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 535b83df7..ff2bed434 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 @@ -26,7 +26,8 @@ package org.onap.cps.rest.exceptions import com.fasterxml.jackson.databind.ObjectMapper import groovy.json.JsonSlurper -import org.onap.cps.api.CpsAdminService +import org.onap.cps.api.CpsDataspaceService +import org.onap.cps.api.CpsAnchorService import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService import org.onap.cps.api.CpsQueryService @@ -63,7 +64,10 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder class CpsRestExceptionHandlerSpec extends Specification { @SpringBean - CpsAdminService mockCpsAdminService = Stub() + CpsDataspaceService mockCpsAdminService = Stub() + + @SpringBean + CpsAnchorService mockCpsAnchorService = Stub() @SpringBean CpsModuleService mockCpsModuleService = Stub() @@ -198,7 +202,7 @@ class CpsRestExceptionHandlerSpec extends Specification { */ def setupTestException(exception) { - mockCpsAdminService.getAnchors(_) >> { throw exception } + mockCpsAnchorService.getAnchors(_) >> { throw exception } } def performTestRequest() { -- cgit 1.2.3-korg