aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cps-rest/docs/openapi/cpsAdmin.yml20
-rwxr-xr-xcps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java12
-rwxr-xr-xcps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy13
-rw-r--r--cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy4
-rwxr-xr-xcps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java17
-rwxr-xr-xcps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java2
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java5
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy29
-rw-r--r--cps-ri/src/test/resources/data/anchor.sql8
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/CpsAdminService.java7
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java5
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java7
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/exceptions/DataspaceInUseException.java40
-rwxr-xr-xcps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy8
-rwxr-xr-xcps-service/src/test/groovy/org/onap/cps/spi/exceptions/CpsExceptionsSpec.groovy8
15 files changed, 176 insertions, 9 deletions
diff --git a/cps-rest/docs/openapi/cpsAdmin.yml b/cps-rest/docs/openapi/cpsAdmin.yml
index a022ef1d94..869cb6e724 100644
--- a/cps-rest/docs/openapi/cpsAdmin.yml
+++ b/cps-rest/docs/openapi/cpsAdmin.yml
@@ -35,6 +35,26 @@ dataspaces:
'403':
$ref: 'components.yml#/components/responses/Forbidden'
+ delete:
+ description: Delete a dataspace
+ tags:
+ - cps-admin
+ summary: Delete a dataspace
+ operationId: deleteDataspace
+ parameters:
+ - $ref: 'components.yml#/components/parameters/dataspaceNameInQuery'
+ responses:
+ '204':
+ $ref: 'components.yml#/components/responses/NoContent'
+ '400':
+ $ref: 'components.yml#/components/responses/BadRequest'
+ '401':
+ $ref: 'components.yml#/components/responses/Unauthorized'
+ '403':
+ $ref: 'components.yml#/components/responses/Forbidden'
+ '409':
+ $ref: 'components.yml#/components/responses/Conflict'
+
schemaSet:
post:
description: Create a new schema set in the given dataspace
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 55fdbbe87a..52e64a95bd 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
@@ -71,6 +71,18 @@ public class AdminRestController implements CpsAdminApi {
}
/**
+ * Delete a dataspace.
+ *
+ * @param dataspaceName name of dataspace to be deleted
+ * @return a {@Link ResponseEntity} of {@link HttpStatus} NO_CONTENT
+ */
+ @Override
+ public ResponseEntity<Void> deleteDataspace(final String dataspaceName) {
+ cpsAdminService.deleteDataspace(dataspaceName);
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+
+ /**
* Create a {@link SchemaSet}.
*
* @param multipartFile multipart file
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 84da2db5d7..e8cfcfb6f6 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
@@ -311,6 +311,18 @@ class AdminRestControllerSpec extends Specification {
response.status == HttpStatus.NO_CONTENT.value()
}
+ def 'Delete dataspace.'() {
+ given: 'an endpoint'
+ def dataspaceEndpoint = "$basePath/v1/dataspaces"
+ when: 'delete dataspace endpoint is invoked'
+ def response = mvc.perform(delete(dataspaceEndpoint)
+ .param('dataspace-name', dataspaceName))
+ .andReturn().response
+ then: 'associated service method is invoked with expected parameter'
+ 1 * mockCpsAdminService.deleteDataspace(dataspaceName)
+ and: 'response code indicates success'
+ response.status == HttpStatus.NO_CONTENT.value()
+ }
def createMultipartFile(filename, content) {
return new MockMultipartFile("file", filename, "text/plain", content.getBytes())
@@ -333,4 +345,5 @@ class AdminRestControllerSpec extends Specification {
multipartFile.getInputStream() >> { throw new IOException() }
return multipartFile
}
+
}
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 079a59c667..f5968442d7 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
@@ -37,6 +37,7 @@ import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.spi.exceptions.ModelValidationException
import org.onap.cps.spi.exceptions.NotFoundInDataspaceException
import org.onap.cps.spi.exceptions.SchemaSetInUseException
+import org.onap.cps.spi.exceptions.DataspaceInUseException
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
@@ -145,7 +146,8 @@ class CpsRestExceptionHandlerSpec extends Specification {
assertTestResponse(response, CONFLICT, exceptionThrown.getMessage(), exceptionThrown.getDetails())
where: 'the following exceptions are thrown'
exceptionThrown << [new DataInUseException(dataspaceName, existingObjectName),
- new SchemaSetInUseException(dataspaceName, existingObjectName)]
+ new SchemaSetInUseException(dataspaceName, existingObjectName),
+ new DataspaceInUseException(dataspaceName, errorDetails)]
}
/*
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 b1bd03c255..9c69006ece 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
@@ -32,6 +32,7 @@ import org.onap.cps.spi.entities.AnchorEntity;
import org.onap.cps.spi.entities.DataspaceEntity;
import org.onap.cps.spi.entities.YangResourceModuleReference;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
+import org.onap.cps.spi.exceptions.DataspaceInUseException;
import org.onap.cps.spi.exceptions.ModuleNamesNotFoundException;
import org.onap.cps.spi.model.Anchor;
import org.onap.cps.spi.repository.AnchorRepository;
@@ -71,6 +72,22 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic
}
@Override
+ public void deleteDataspace(final String dataspaceName) {
+ final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
+ final int numberOfAssociatedAnchors = anchorRepository.countByDataspace(dataspaceEntity);
+ if (numberOfAssociatedAnchors != 0) {
+ throw new DataspaceInUseException(dataspaceName,
+ String.format("Dataspace contains %d anchor(s)", numberOfAssociatedAnchors));
+ }
+ final int numberOfAssociatedSchemaSets = schemaSetRepository.countByDataspace(dataspaceEntity);
+ if (numberOfAssociatedSchemaSets != 0) {
+ throw new DataspaceInUseException(dataspaceName,
+ String.format("Dataspace contains %d schemaset(s)", numberOfAssociatedSchemaSets));
+ }
+ dataspaceRepository.delete(dataspaceEntity);
+ }
+
+ @Override
public void createAnchor(final String dataspaceName, final String schemaSetName, final String anchorName) {
final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
final var schemaSetEntity =
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java
index 5870fd9e9b..471f1758cd 100755
--- a/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java
@@ -45,6 +45,8 @@ public interface AnchorRepository extends JpaRepository<AnchorEntity, Integer> {
Collection<AnchorEntity> findAllBySchemaSet(@NotNull SchemaSetEntity schemaSetEntity);
+ Integer countByDataspace(@NotNull DataspaceEntity dataspaceEntity);
+
@Query(value = "SELECT anchor.* FROM yang_resource\n"
+ "JOIN schema_set_yang_resources ON schema_set_yang_resources.yang_resource_id = yang_resource.id\n"
+ "JOIN schema_set ON schema_set.id = schema_set_yang_resources.schema_set_id\n"
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java
index 7b56f9323d..a15ce622c2 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java
@@ -19,7 +19,6 @@
package org.onap.cps.spi.repository;
-import java.util.List;
import java.util.Optional;
import javax.validation.constraints.NotNull;
import org.onap.cps.spi.entities.DataspaceEntity;
@@ -31,11 +30,11 @@ import org.springframework.stereotype.Repository;
@Repository
public interface SchemaSetRepository extends JpaRepository<SchemaSetEntity, Integer> {
- List<SchemaSetEntity> findAllByDataspace(@NotNull DataspaceEntity dataspaceEntity);
-
Optional<SchemaSetEntity> findByDataspaceAndName(@NotNull DataspaceEntity dataspaceEntity,
@NotNull String schemaSetName);
+ Integer countByDataspace(@NotNull DataspaceEntity dataspaceEntity);
+
/**
* Gets a schema set by dataspace and schema set name.
*
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
index a0df2b169d..4b5b116f48 100644
--- 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
@@ -24,6 +24,7 @@ package org.onap.cps.spi.impl
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.exceptions.ModuleNamesNotFoundException
@@ -36,10 +37,9 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase {
@Autowired
CpsAdminPersistenceService objectUnderTest
-
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 EMPTY_DATASPACE_NAME = 'DATASPACE-002'
+ static final String DATASPACE_WITH_NO_DATA = 'DATASPACE-002'
static final Integer DELETED_ANCHOR_ID = 3001
static final Long DELETED_FRAGMENT_ID = 4001
@@ -111,7 +111,7 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase {
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()]
- EMPTY_DATASPACE_NAME || []
+ DATASPACE_WITH_NO_DATA || []
}
@Sql(CLEAR_DATA)
@@ -173,4 +173,27 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase {
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 2 anchor(s)'
+ 'dataspace contains schemasets' | 'DATASPACE-003' || DataspaceInUseException | 'contains 1 schemaset(s)'
+ }
+
}
diff --git a/cps-ri/src/test/resources/data/anchor.sql b/cps-ri/src/test/resources/data/anchor.sql
index dbf1a6a47d..c9240f7fd2 100644
--- a/cps-ri/src/test/resources/data/anchor.sql
+++ b/cps-ri/src/test/resources/data/anchor.sql
@@ -21,10 +21,14 @@
*/
INSERT INTO DATASPACE (ID, NAME) VALUES
- (1001, 'DATASPACE-001'), (1002, 'DATASPACE-002');
+ (1001, 'DATASPACE-001'),
+ (1002, 'DATASPACE-002'),
+ (1003, 'DATASPACE-003');
INSERT INTO SCHEMA_SET (ID, NAME, DATASPACE_ID) VALUES
- (2001, 'SCHEMA-SET-001', 1001), (2002, 'SCHEMA-SET-002', 1001);
+ (2001, 'SCHEMA-SET-001', 1001),
+ (2002, 'SCHEMA-SET-002', 1001),
+ (2003, 'SCHEMA-SET-002', 1003);
INSERT INTO ANCHOR (ID, NAME, DATASPACE_ID, SCHEMA_SET_ID) VALUES
(3001, 'ANCHOR-001', 1001, 2001),
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java b/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java
index 1d08cde7ba..7ba95995a5 100755
--- a/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java
@@ -42,6 +42,13 @@ public interface CpsAdminService {
void createDataspace(@NonNull String dataspaceName);
/**
+ * Delete dataspace.
+ *
+ * @param dataspaceName the name of the dataspace to delete
+ */
+ void deleteDataspace(@NonNull String dataspaceName);
+
+ /**
* Create an Anchor.
*
* @param dataspaceName dataspace name
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java
index faff7b611b..d831793264 100755
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java
@@ -42,6 +42,11 @@ public class CpsAdminServiceImpl implements CpsAdminService {
}
@Override
+ public void deleteDataspace(final String dataspaceName) {
+ cpsAdminPersistenceService.deleteDataspace(dataspaceName);
+ }
+
+ @Override
public void createAnchor(final String dataspaceName, final String schemaSetName, final String anchorName) {
cpsAdminPersistenceService.createAnchor(dataspaceName, schemaSetName, anchorName);
}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
index 104ac4f3f6..95537006a7 100755
--- a/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
@@ -41,6 +41,13 @@ public interface CpsAdminPersistenceService {
void createDataspace(@NonNull String dataspaceName);
/**
+ * Delete dataspace.
+ *
+ * @param dataspaceName the name of the dataspace to delete
+ */
+ void deleteDataspace(@NonNull String dataspaceName);
+
+ /**
* Create an Anchor.
*
* @param dataspaceName dataspace name
diff --git a/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataspaceInUseException.java b/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataspaceInUseException.java
new file mode 100644
index 0000000000..7889301dd2
--- /dev/null
+++ b/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataspaceInUseException.java
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.spi.exceptions;
+
+/**
+ * Runtime exception.
+ * Thrown when given dataspace name is rejected to be deleted because it has anchor or schemasets associated.
+ */
+
+public class DataspaceInUseException extends DataInUseException {
+
+ private static final long serialVersionUID = 4531370947720760347L;
+
+ /**
+ * Constructor.
+ *
+ * @param dataspaceName dataspace name
+ * @param details error message details
+ */
+ public DataspaceInUseException(final String dataspaceName, final String details) {
+ super(String.format("Dataspace with name %s is being used.", dataspaceName), details);
+ }
+}
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy
index 95afeb4172..6d1f586295 100755
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy
@@ -78,4 +78,12 @@ class CpsAdminServiceImplSpec extends Specification {
objectUnderTest.queryAnchorNames('some-dataspace-name', ['some-module-name']) == ['some-anchor-identifier']
}
+
+ def 'Delete dataspace.'() {
+ when: 'delete dataspace is invoked'
+ objectUnderTest.deleteDataspace('someDataspace')
+ then: 'associated persistence service method is invoked with correct parameter'
+ 1 * mockCpsAdminPersistenceService.deleteDataspace('someDataspace')
+ }
+
}
diff --git a/cps-service/src/test/groovy/org/onap/cps/spi/exceptions/CpsExceptionsSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/spi/exceptions/CpsExceptionsSpec.groovy
index 4243c18c24..5bd3678346 100755
--- a/cps-service/src/test/groovy/org/onap/cps/spi/exceptions/CpsExceptionsSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/spi/exceptions/CpsExceptionsSpec.groovy
@@ -170,4 +170,12 @@ class CpsExceptionsSpec extends Specification {
expect: 'the exception has the provided details'
exception.details == providedDetails
}
+
+ def 'Creating an exception that the dataspace is being used and cannot be deleted.'() {
+ given: 'a dataspace in use exception is created'
+ def exception = new DataspaceInUseException(dataspaceName,providedDetails)
+ expect: 'the exception has the correct message with dataspace name and provided details'
+ exception.message == "Dataspace with name ${dataspaceName} is being used."
+ exception.details == providedDetails
+ }
}