Create dataspace 80/116480/7
authorRuslan Kashapov <ruslan.kashapov@pantheon.tech>
Thu, 10 Dec 2020 08:49:59 +0000 (10:49 +0200)
committerRuslan Kashapov <ruslan.kashapov@pantheon.tech>
Wed, 6 Jan 2021 13:03:59 +0000 (15:03 +0200)
Issue-ID: CPS-134
Change-Id: Ie7f00f9c322a12a6c2a71c1407f6970a7dd24d2d
Signed-off-by: Ruslan Kashapov <ruslan.kashapov@pantheon.tech>
cps-rest/docs/api/swagger/openapi.yml
cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java
cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy
cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java
cps-ri/src/test/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceTest.java
cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java
cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java
cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
cps-service/src/main/java/org/onap/cps/spi/exceptions/DataspaceAlreadyDefinedException.java [new file with mode: 0644]
cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy

index d76ec5e..d2c720e 100755 (executable)
@@ -9,6 +9,35 @@ tags:
   - name: cps-rest
     description: cps Resource
 paths:
+  /v1/dataspaces:
+    post:
+      tags:
+        - cps-admin
+      summary: Create a new dataspace
+      operationId: createDataspace
+      parameters:
+        - name: dataspace-name
+          in: query
+          description: dataspace-name
+          required: true
+          schema:
+            type: string
+      responses:
+        201:
+          description: Created
+          content:
+            application/json:
+              schema:
+                type: string
+        400:
+          description: Bad Request
+          content: { }
+        401:
+          description: Unauthorized
+          content: { }
+        403:
+          description: Forbidden
+          content: { }
   /v1/dataspaces/{dataspace-name}/:
     delete:
       tags:
index 6dc2cee..9549580 100644 (file)
@@ -46,6 +46,12 @@ public class AdminRestController implements CpsAdminApi {
     @Autowired
     private ModelMapper modelMapper;
 
+    @Override
+    public ResponseEntity<String> createDataspace(final String dataspaceName) {
+        cpsAdminService.createDataspace(dataspaceName);
+        return new ResponseEntity<>(dataspaceName, HttpStatus.CREATED);
+    }
+
     @Override
     public ResponseEntity<String> createSchemaSet(final String schemaSetName, final MultipartFile multipartFile,
         final String dataspaceName) {
index ed87e3c..9919649 100644 (file)
@@ -24,6 +24,7 @@ import org.modelmapper.ModelMapper
 import org.onap.cps.api.CpsAdminService
 import org.onap.cps.api.CpsModuleService
 import org.onap.cps.spi.model.Anchor
+import org.onap.cps.spi.exceptions.DataspaceAlreadyDefinedException
 import org.spockframework.spring.SpringBean
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
@@ -60,6 +61,25 @@ class AdminRestControllerSpec extends Specification {
     def anchor = new Anchor(name: 'my_anchor')
     def anchorList = [anchor]
 
+    def 'Create new dataspace'() {
+        when:
+            def response = performCreateDataspaceRequest("new-dataspace")
+        then: 'Service method is invoked with expected parameters'
+            1 * mockCpsAdminService.createDataspace("new-dataspace")
+        and:
+            response.status == HttpStatus.CREATED.value()
+    }
+
+    def 'Create dataspace over existing with same name'() {
+        given:
+            def thrownException = new DataspaceAlreadyDefinedException("", new RuntimeException())
+            mockCpsAdminService.createDataspace("existing-dataspace") >> { throw thrownException }
+        when:
+            def response = performCreateDataspaceRequest("existing-dataspace")
+        then:
+            response.status == HttpStatus.BAD_REQUEST.value()
+    }
+
     def 'Create schema set from yang file'() {
         def yangResourceMapCapture
         given:
@@ -83,6 +103,14 @@ class AdminRestControllerSpec extends Specification {
             response.status == HttpStatus.BAD_REQUEST.value()
     }
 
+    def performCreateDataspaceRequest(String dataspaceName) {
+        return mvc.perform(
+                MockMvcRequestBuilders
+                        .post('/v1/dataspaces')
+                        .param('dataspace-name', dataspaceName)
+        ).andReturn().response
+    }
+
     def createMultipartFile(filename, content) {
         return new MockMultipartFile("file", filename, "text/plain", content.getBytes())
     }
index 5093ba5..d6579bd 100644 (file)
@@ -28,6 +28,7 @@ import org.onap.cps.spi.entities.Dataspace;
 import org.onap.cps.spi.entities.Fragment;
 import org.onap.cps.spi.entities.SchemaSet;
 import org.onap.cps.spi.exceptions.AnchorAlreadyDefinedException;
+import org.onap.cps.spi.exceptions.DataspaceAlreadyDefinedException;
 import org.onap.cps.spi.model.Anchor;
 import org.onap.cps.spi.repository.DataspaceRepository;
 import org.onap.cps.spi.repository.FragmentRepository;
@@ -48,6 +49,15 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic
     @Autowired
     private SchemaSetRepository schemaSetRepository;
 
+    @Override
+    public void createDataspace(final String dataspaceName) {
+        try {
+            dataspaceRepository.save(new Dataspace(dataspaceName));
+        } catch (final DataIntegrityViolationException e) {
+            throw new DataspaceAlreadyDefinedException(dataspaceName, e);
+        }
+    }
+
     @Override
     public void createAnchor(final String dataspaceName, final String schemaSetName, final String anchorName) {
         final Dataspace dataspace = dataspaceRepository.getByName(dataspaceName);
index 455369d..7497526 100644 (file)
@@ -32,6 +32,7 @@ import org.onap.cps.spi.CpsAdminPersistenceService;
 import org.onap.cps.spi.entities.Dataspace;
 import org.onap.cps.spi.entities.Fragment;
 import org.onap.cps.spi.exceptions.AnchorAlreadyDefinedException;
+import org.onap.cps.spi.exceptions.DataspaceAlreadyDefinedException;
 import org.onap.cps.spi.exceptions.DataspaceNotFoundException;
 import org.onap.cps.spi.exceptions.SchemaSetNotFoundException;
 import org.onap.cps.spi.model.Anchor;
@@ -76,6 +77,24 @@ public class CpsAdminPersistenceServiceTest {
     @Autowired
     private SchemaSetRepository schemaSetRepository;
 
+    @Test
+    @SqlGroup({@Sql(CLEAR_DATA), @Sql(SET_DATA)})
+    public void testCreateDataspace() {
+        final String dataspaceName = "DATASPACE-NEW";
+        cpsAdminPersistenceService.createDataspace(dataspaceName);
+
+        final Dataspace dataspace = dataspaceRepository.findByName(dataspaceName).orElseThrow();
+        assertNotNull(dataspace);
+        assertNotNull(dataspace.getId());
+        assertEquals(dataspaceName, dataspace.getName());
+    }
+
+    @Test(expected = DataspaceAlreadyDefinedException.class)
+    @SqlGroup({@Sql(CLEAR_DATA), @Sql(SET_DATA)})
+    public void testCreateDataspaceWithNameAlreadyDefined() {
+        cpsAdminPersistenceService.createDataspace(DATASPACE_NAME);
+    }
+
     @Test
     @SqlGroup({@Sql(CLEAR_DATA), @Sql(SET_DATA)})
     public void testCreateAnchor() {
index 5090e3a..581550f 100644 (file)
@@ -23,6 +23,7 @@ package org.onap.cps.api;
 import java.util.Collection;
 import org.checkerframework.checker.nullness.qual.NonNull;
 import org.onap.cps.spi.exceptions.CpsException;
+import org.onap.cps.spi.exceptions.DataspaceAlreadyDefinedException;
 import org.onap.cps.spi.model.Anchor;
 
 /**
@@ -30,6 +31,14 @@ import org.onap.cps.spi.model.Anchor;
  */
 public interface CpsAdminService {
 
+    /**
+     * Create dataspace.
+     *
+     * @param dataspaceName dataspace name
+     * @throws DataspaceAlreadyDefinedException if dataspace with same name already exists
+     */
+    void createDataspace(@NonNull String dataspaceName);
+
     /**
      * Create an Anchor.
      *
index f93a827..0cb85fd 100644 (file)
@@ -33,6 +33,11 @@ public class CpsAdminServiceImpl implements CpsAdminService {
     @Autowired
     private CpsAdminPersistenceService cpsAdminPersistenceService;
 
+    @Override
+    public void createDataspace(final String dataspaceName) {
+        cpsAdminPersistenceService.createDataspace(dataspaceName);
+    }
+
     @Override
     public void createAnchor(final String dataspaceName, final String schemaSetName, final String anchorName) {
         cpsAdminPersistenceService.createAnchor(dataspaceName, schemaSetName, anchorName);
index 1b7ddb7..ba53003 100644 (file)
@@ -23,6 +23,7 @@ package org.onap.cps.spi;
 
 import java.util.Collection;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.onap.cps.spi.exceptions.DataspaceAlreadyDefinedException;
 import org.onap.cps.spi.model.Anchor;
 
 /*
@@ -30,6 +31,14 @@ import org.onap.cps.spi.model.Anchor;
  */
 public interface CpsAdminPersistenceService {
 
+    /**
+     * Create dataspace.
+     *
+     * @param dataspaceName dataspace name
+     * @throws DataspaceAlreadyDefinedException if dataspace with same name already exists
+     */
+    void createDataspace(@NonNull String dataspaceName);
+
     /**
      * Create an Anchor.
      *
diff --git a/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataspaceAlreadyDefinedException.java b/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataspaceAlreadyDefinedException.java
new file mode 100644 (file)
index 0000000..d6d933c
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Pantheon.tech
+ *  ================================================================================
+ *  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;
+
+/**
+ * Dataspace already defined exception. Indicates the dataspace with same name already exists.
+ */
+public class DataspaceAlreadyDefinedException extends CpsAdminException {
+
+    private static final long serialVersionUID = -5813793951842079228L;
+
+    /**
+     * Constructor.
+     *
+     * @param dataspaceName dataspace name
+     * @param cause         the cause of this exception
+     */
+    public DataspaceAlreadyDefinedException(final String dataspaceName, final Throwable cause) {
+        super("Duplicate Dataspace.",
+            String.format("Dataspace with name %s already exists.", dataspaceName),
+            cause);
+    }
+}
index 9e13c77..0222824 100644 (file)
@@ -32,6 +32,13 @@ class CpsAdminServiceImplSpec extends Specification {
         objectUnderTest.cpsAdminPersistenceService = mockCpsAdminPersistenceService
     }
 
+    def 'Create dataspace method invokes persistence service'() {
+        when: 'Create dataspace method is invoked'
+            objectUnderTest.createDataspace('someDataspace')
+        then: 'The persistence service method is invoked with same parameters'
+            1 * mockCpsAdminPersistenceService.createDataspace('someDataspace')
+    }
+
     def 'Create anchor method invokes persistence service'() {
         when: 'Create anchor method is invoked'
             objectUnderTest.createAnchor('dummyDataspace', 'dummySchemaSet', 'dummyAnchorName')