diff options
4 files changed, 48 insertions, 269 deletions
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml index db274f7f01..25dc91c6fd 100644 --- a/cps-ri/pom.xml +++ b/cps-ri/pom.xml @@ -33,7 +33,7 @@ <artifactId>cps-ri</artifactId>
<properties>
- <minimum-coverage>0.64</minimum-coverage>
+ <minimum-coverage>0.54</minimum-coverage>
<!-- Additional coverage is provided by integration-test module -->
</properties>
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java index 162b268d87..6f9f5a482c 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java @@ -198,12 +198,10 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic verifyDataspaceName(dataspaceName); } if (inputModuleNames.size() > retrievedModuleReferences.size()) { - final List<String> moduleNamesNotFound = inputModuleNames.stream() + final List<String> unknownModules = inputModuleNames.stream() .filter(moduleName -> !retrievedModuleReferences.contains(moduleName)) .collect(Collectors.toList()); - if (!moduleNamesNotFound.isEmpty()) { - throw new ModuleNamesNotFoundException(dataspaceName, moduleNamesNotFound); - } + throw new ModuleNamesNotFoundException(dataspaceName, unknownModules); } } diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy deleted file mode 100644 index 28d3bcfa4c..0000000000 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy +++ /dev/null @@ -1,263 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation - * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2022 Bell Canada - * Modifications Copyright (C) 2022 TechMahindra Ltd. - * ================================================================================ - * 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.spi.impl - -import org.mockito.Mock -import org.onap.cps.spi.CpsAdminPersistenceService -import org.onap.cps.spi.exceptions.AlreadyDefinedException -import org.onap.cps.spi.exceptions.AnchorNotFoundException -import org.onap.cps.spi.exceptions.DataspaceInUseException -import org.onap.cps.spi.exceptions.DataspaceNotFoundException -import org.onap.cps.spi.exceptions.SchemaSetNotFoundException -import org.onap.cps.spi.model.Anchor -import org.onap.cps.spi.model.Dataspace -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.test.context.jdbc.Sql -import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper - -class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase { - - @Autowired - CpsAdminPersistenceService objectUnderTest - - @Mock - ObjectMapper objectMapper - - static final String SET_DATA = '/data/anchor.sql' - static final String SAMPLE_DATA_FOR_ANCHORS_WITH_MODULES = '/data/anchors-schemaset-modules.sql' - static final String DATASPACE_WITH_NO_DATA = 'DATASPACE-002-NO-DATA' - static final Integer DELETED_ANCHOR_ID = 3002 - - @Sql(CLEAR_DATA) - def 'Create and retrieve a new dataspace.'() { - when: 'a new dataspace is created' - def dataspaceName = 'some-new-dataspace' - objectUnderTest.createDataspace(dataspaceName) - then: 'that dataspace can be retrieved from the dataspace repository' - def dataspaceEntity = dataspaceRepository.findByName(dataspaceName).orElseThrow() - dataspaceEntity.id != null - dataspaceEntity.name == dataspaceName - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Attempt to create a duplicate dataspace.'() { - when: 'an attempt is made to create an already existing dataspace' - objectUnderTest.createDataspace(DATASPACE_NAME) - then: 'an exception that is is already defined is thrown with the correct details' - def thrown = thrown(AlreadyDefinedException) - thrown.details.contains(DATASPACE_NAME) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get a dataspace.'() { - when: 'dataspace is retrieved' - def dataspace = objectUnderTest.getDataspace(DATASPACE_NAME) - then: ' the response contains expected dataspace' - assert dataspace.getName().equals(DATASPACE_NAME); - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get all dataspaces.'() { - when: 'all dataspaces are retrieved' - def dataspaces = objectUnderTest.getAllDataspaces() - then: 'the response contains expected dataspaces' - def expectedDataspaces = Set.of(new Dataspace(name: 'DATASPACE-001'), new Dataspace(name: 'DATASPACE-002-NO-DATA'), - new Dataspace(name: 'DATASPACE-003')) - assert dataspaces == expectedDataspaces - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get non existing dataspace.'() { - when: 'attempting to retrieve a non-existing dataspace' - def dataspace = objectUnderTest.getDataspace('non_existing_dataspace') - then: 'an DataspaceNotFoundException is thrown' - thrown(DataspaceNotFoundException) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Create and retrieve a new anchor.'() { - when: 'a new anchor is created' - def newAnchorName = 'my-new-anchor' - objectUnderTest.createAnchor(DATASPACE_NAME, SCHEMA_SET_NAME1, newAnchorName) - then: 'that anchor can be retrieved' - def anchor = objectUnderTest.getAnchor(DATASPACE_NAME, newAnchorName) - anchor.name == newAnchorName - anchor.dataspaceName == DATASPACE_NAME - anchor.schemaSetName == SCHEMA_SET_NAME1 - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Create anchor error scenario: #scenario.'() { - when: 'attempt to create new anchor named #anchorName in dataspace #dataspaceName with #schemaSetName' - objectUnderTest.createAnchor(dataspaceName, schemaSetName, anchorName) - then: 'an #expectedException is thrown' - thrown(expectedException) - where: 'the following data is used' - scenario | dataspaceName | schemaSetName | anchorName || expectedException - 'dataspace does not exist' | 'unknown' | 'not-relevant' | 'not-relevant' || DataspaceNotFoundException - 'schema set does not exist' | DATASPACE_NAME | 'unknown' | 'not-relevant' || SchemaSetNotFoundException - 'anchor already exists' | DATASPACE_NAME | SCHEMA_SET_NAME1 | ANCHOR_NAME1 || AlreadyDefinedException - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get anchor error scenario: #scenario.'() { - when: 'attempt to get anchor named #anchorName in dataspace #dataspaceName' - objectUnderTest.getAnchor(dataspaceName, anchorName) - then: 'an #expectedException is thrown' - thrown(expectedException) - where: 'the following data is used' - scenario | dataspaceName | anchorName || expectedException - 'dataspace does not exist' | 'unknown' | 'not-relevant' || DataspaceNotFoundException - 'anchor does not exists' | DATASPACE_NAME | 'unknown' || AnchorNotFoundException - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get all anchors in dataspace #dataspaceName.'() { - when: 'all anchors are retrieved from #DATASPACE_NAME' - def result = objectUnderTest.getAnchors(dataspaceName) - then: 'the expected collection of anchors is returned' - result.size() == expectedAnchors.size() - result.containsAll(expectedAnchors) - where: 'the following data is used' - dataspaceName || expectedAnchors - DATASPACE_NAME || [Anchor.builder().name(ANCHOR_NAME1).schemaSetName(SCHEMA_SET_NAME1).dataspaceName(DATASPACE_NAME).build(), - Anchor.builder().name(ANCHOR_NAME2).schemaSetName(SCHEMA_SET_NAME2).dataspaceName(DATASPACE_NAME).build(), - Anchor.builder().name(ANCHOR_NAME3).schemaSetName(SCHEMA_SET_NAME2).dataspaceName(DATASPACE_NAME).build()] - DATASPACE_WITH_NO_DATA || [] - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get all anchors associated with schemaset in a dataspace.'() { - when: 'anchors are retrieved by dataspace and schema-set' - def anchors = objectUnderTest.getAnchors(dataspace, schemasetName) - then: ' the response contains expected anchors' - anchors == expectedAnchors - where: - scenario | dataspace | schemasetName || expectedAnchors - 'no-anchors' | 'DATASPACE-003' | 'SCHEMA-SET-002-NO-ANCHORS' || Collections.emptySet() - 'one-anchor' | 'DATASPACE-001' | 'SCHEMA-SET-001' || Set.of(new Anchor('ANCHOR-001', 'DATASPACE-001', 'SCHEMA-SET-001')) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Error Handling: Get all anchors associated with schemaset in a dataspace.'() { - when: 'anchors are retrieved by dataspace and schema-set' - def anchors = objectUnderTest.getAnchors(dataspace, schemasetName) - then: ' an expected expception is thrown' - thrown(expectedException) - where: - scenario | dataspace | schemasetName || expectedException - 'unknown-dataspace' | 'unknown' | 'SCHEMA-SET-002-NO-ANCHORS' || DataspaceNotFoundException - 'unknown-schemaset' | 'DATASPACE-001' | 'unknown-schema-set' || SchemaSetNotFoundException - } - - @Sql(CLEAR_DATA) - def 'Get all anchors in unknown dataspace.'() { - when: 'attempt to get all anchors in an unknown dataspace' - objectUnderTest.getAnchors('unknown-dataspace') - then: 'an DataspaceNotFoundException is thrown' - thrown(DataspaceNotFoundException) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get all anchors associated with multiple schemasets in a dataspace.'() { - when: 'anchors are retrieved by dataspace and schema-sets' - def anchors = objectUnderTest.getAnchors('DATASPACE-001', ['SCHEMA-SET-001', 'SCHEMA-SET-002']) - then: ' the response contains expected anchors' - anchors == Set.of( - new Anchor('ANCHOR-001', 'DATASPACE-001', 'SCHEMA-SET-001'), - new Anchor('ANCHOR-002', 'DATASPACE-001', 'SCHEMA-SET-002'), - new Anchor('ANCHOR-003', 'DATASPACE-001', 'SCHEMA-SET-002')) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Delete anchor'() { - when: 'delete anchor action is invoked' - objectUnderTest.deleteAnchor(DATASPACE_NAME, ANCHOR_NAME2) - then: 'anchor is deleted' - assert anchorRepository.findById(DELETED_ANCHOR_ID).isEmpty() - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'delete anchor error scenario: #scenario'() { - when: 'delete anchor attempt is performed' - objectUnderTest.deleteAnchor(dataspaceName, anchorName) - then: 'an #expectedException is thrown' - thrown(expectedException) - where: 'the following data is used' - scenario | dataspaceName | anchorName || expectedException - 'dataspace does not exist' | 'unknown' | 'not-relevant' || DataspaceNotFoundException - 'anchor does not exists' | DATASPACE_NAME | 'unknown' || AnchorNotFoundException - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Delete multiple anchors'() { - when: 'delete anchors action is invoked' - objectUnderTest.deleteAnchors(DATASPACE_NAME, ['ANCHOR-002', 'ANCHOR-003']) - then: 'anchors are deleted' - anchorRepository.findById(3002).isEmpty() - anchorRepository.findById(3003).isEmpty() - } - - @Sql([CLEAR_DATA, SAMPLE_DATA_FOR_ANCHORS_WITH_MODULES]) - def 'Query anchors that have #scenario.'() { - when: 'all anchor are retrieved for the given dataspace name and module names' - def anchors = objectUnderTest.queryAnchors(inputDataspaceName, inputModuleNames) - then: 'the expected anchors are returned' - anchors.size() == expectedAnchors.size() - anchors.containsAll(expectedAnchors) - where: 'the following data is used' - scenario | inputDataspaceName | inputModuleNames || expectedAnchors - 'one module' | 'dataspace-1' | ['module-name-1'] || [buildAnchor('anchor-2', 'dataspace-1', 'schema-set-2'), buildAnchor('anchor-1', 'dataspace-1', 'schema-set-1')] - 'two modules' | 'dataspace-1' | ['module-name-1', 'module-name-2'] || [buildAnchor('anchor-2', 'dataspace-1', 'schema-set-2'), buildAnchor('anchor-1', 'dataspace-1', 'schema-set-1')] - 'no anchors for all three modules' | 'dataspace-1' | ['module-name-1', 'module-name-2', 'module-name-3'] || [] - 'unknown dataspace' | 'db-does-not-exist' | ['does-not-matter'] || [] - 'unknown module and known module' | 'dataspace-1' | ['module-name-1', 'module-does-not-exist'] || [] - } - - def buildAnchor(def anchorName, def dataspaceName, def SchemaSetName) { - return Anchor.builder().name(anchorName).dataspaceName(dataspaceName).schemaSetName(SchemaSetName).build() - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Delete dataspace.'() { - when: 'delete dataspace action is invoked' - objectUnderTest.deleteDataspace(DATASPACE_WITH_NO_DATA) - then: 'dataspace is deleted' - assert dataspaceRepository.findByName(DATASPACE_WITH_NO_DATA).isEmpty(); - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Delete dataspace when #scenario.'() { - when: 'delete dataspace action is invoked' - objectUnderTest.deleteDataspace(dataspaceName) - then: 'the correct exception is thrown with the relevant details' - def thrownException = thrown(expectedException) - thrownException.details.contains(expectedMessageDetails) - where: 'the following data is used' - scenario | dataspaceName || expectedException | expectedMessageDetails - 'dataspace name does not exist' | 'unknown' || DataspaceNotFoundException | 'unknown does not exist' - 'dataspace contains an anchor' | 'DATASPACE-001' || DataspaceInUseException | 'contains 3 anchor(s)' - 'dataspace contains schemasets' | 'DATASPACE-003' || DataspaceInUseException | 'contains 1 schemaset(s)' - } -} diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy index 91a4c8ac0e..92fbdaaa25 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy @@ -24,6 +24,7 @@ import org.onap.cps.api.CpsAdminService import org.onap.cps.integration.base.CpsIntegrationSpecBase import org.onap.cps.spi.exceptions.AlreadyDefinedException import org.onap.cps.spi.exceptions.AnchorNotFoundException +import org.onap.cps.spi.exceptions.DataspaceInUseException import org.onap.cps.spi.exceptions.DataspaceNotFoundException class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { @@ -49,6 +50,27 @@ class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { assert thrown instanceof DataspaceNotFoundException } + def 'Delete dataspace with error; #scenario.'() { + setup: 'add some anchors if needed' + numberOfAnchors.times { + objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'anchor' + it) + } + when: 'attempt to delete dataspace' + objectUnderTest.deleteDataspace(dataspaceName) + then: 'the correct exception is thrown with the relevant details' + def thrownException = thrown(expectedException) + thrownException.details.contains(expectedMessageDetails) + cleanup: + numberOfAnchors.times { + objectUnderTest.deleteAnchor(GENERAL_TEST_DATASPACE, 'anchor' + it) + } + where: 'the following data is used' + scenario | dataspaceName | numberOfAnchors || expectedException | expectedMessageDetails + 'dataspace name does not exist' | 'unknown' | 0 || DataspaceNotFoundException | 'unknown does not exist' + 'dataspace contains schemasets' | GENERAL_TEST_DATASPACE | 0 || DataspaceInUseException | 'contains 1 schemaset(s)' + 'dataspace contains anchors' | GENERAL_TEST_DATASPACE | 2 || DataspaceInUseException | 'contains 2 anchor(s)' + } + def 'Retrieve all dataspaces (depends on total test suite).'() { given: 'two addtional dataspaces are created' objectUnderTest.createDataspace('dataspace1') @@ -68,7 +90,7 @@ class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { } def 'Anchor CRUD operations.'() { - when: 'a anchor is created' + when: 'an anchor is created' objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'newAnchor') then: 'the anchor be read' assert objectUnderTest.getAnchor(GENERAL_TEST_DATASPACE, 'newAnchor').name == 'newAnchor' @@ -107,4 +129,26 @@ class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { assert objectUnderTest.queryAnchorNames(GENERAL_TEST_DATASPACE, ['stores', 'unused-model']).size() == 0 } + def 'Duplicate anchors.'() { + given: 'an anchor is created' + objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'newAnchor') + when: 'attempt to create another anchor with the same name' + objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'newAnchor') + then: 'an exception is thrown that the anchor already is defined' + thrown(AlreadyDefinedException) + cleanup: + objectUnderTest.deleteAnchor(GENERAL_TEST_DATASPACE, 'newAnchor') + } + + def 'Query anchors without any known modules and #scenario'() { + when: 'querying for anchors with #scenario' + def result = objectUnderTest.queryAnchorNames(dataspaceName, ['unknownModule']) + then: 'an empty result is returned (no error)' + assert result == [] + where: + scenario | dataspaceName + 'non existing database' | 'nonExistingDataspace' + 'just unknown module(s)' | GENERAL_TEST_DATASPACE + } + } |