Delete anchor part 1: service and persistence layers 06/120206/3
authorRuslan Kashapov <ruslan.kashapov@pantheon.tech>
Mon, 5 Apr 2021 09:59:57 +0000 (12:59 +0300)
committerRishi Chail <rishi.chail@est.tech>
Wed, 7 Apr 2021 11:45:24 +0000 (11:45 +0000)
Issue-ID: CPS-312
Change-Id: I10ab5a2d115ffdf8179a99b6ec712f3eccfb5f13
Signed-off-by: Ruslan Kashapov <ruslan.kashapov@pantheon.tech>
cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java
cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy
cps-ri/src/test/resources/data/anchor.sql
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/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy

index 1b8f196..edc56e4 100755 (executable)
@@ -2,6 +2,7 @@
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2020 Nordix Foundation. All rights reserved.
  *  Modifications Copyright (C) 2020 Bell Canada. All rights reserved.
+ *  Modifications Copyright (C) 2021 Pantheon.tech
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.cps.spi.impl;
 
+import com.google.common.collect.ImmutableSet;
 import java.util.Collection;
 import java.util.stream.Collectors;
+import javax.transaction.Transactional;
 import org.onap.cps.spi.CpsAdminPersistenceService;
 import org.onap.cps.spi.entities.AnchorEntity;
 import org.onap.cps.spi.entities.DataspaceEntity;
@@ -31,6 +34,7 @@ import org.onap.cps.spi.exceptions.AlreadyDefinedException;
 import org.onap.cps.spi.model.Anchor;
 import org.onap.cps.spi.repository.AnchorRepository;
 import org.onap.cps.spi.repository.DataspaceRepository;
+import org.onap.cps.spi.repository.FragmentRepository;
 import org.onap.cps.spi.repository.SchemaSetRepository;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DataIntegrityViolationException;
@@ -48,6 +52,9 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic
     @Autowired
     private SchemaSetRepository schemaSetRepository;
 
+    @Autowired
+    private FragmentRepository fragmentRepository;
+
     @Override
     public void createDataspace(final String dataspaceName) {
         try {
@@ -83,10 +90,20 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic
 
     @Override
     public Anchor getAnchor(final String dataspaceName, final String anchorName) {
+        return toAnchor(getAnchorEntity(dataspaceName, anchorName));
+    }
+
+    @Transactional
+    @Override
+    public void deleteAnchor(final String dataspaceName, final String anchorName) {
+        final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName);
+        fragmentRepository.deleteByAnchorIn(ImmutableSet.of(anchorEntity));
+        anchorRepository.delete(anchorEntity);
+    }
+
+    private AnchorEntity getAnchorEntity(final String dataspaceName, final String anchorName) {
         final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
-        final AnchorEntity anchorEntity =
-            anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName);
-        return toAnchor(anchorEntity);
+        return anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName);
     }
 
     private static Anchor toAnchor(final AnchorEntity anchorEntity) {
index 7ab099d..0d75d3f 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2021 Nordix Foundation
+ *  Modifications Copyright (C) 2021 Pantheon.tech
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -36,6 +37,8 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase {
 
     static final String SET_DATA = '/data/anchor.sql'
     static final String EMPTY_DATASPACE_NAME = 'DATASPACE-002'
+    static final Integer DELETED_ANCHOR_ID = 3001
+    static final Long DELETED_FRAGMENT_ID = 4001
 
     @Sql(CLEAR_DATA)
     def 'Create and retrieve a new dataspace.'() {
@@ -77,10 +80,10 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase {
         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
+            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
     }
 
     @Unroll
@@ -91,9 +94,9 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase {
         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
+            scenario                   | dataspaceName  | anchorName     || expectedException
+            'dataspace does not exist' | 'unknown'      | 'not-relevant' || DataspaceNotFoundException
+            'anchor does not exists'   | DATASPACE_NAME | 'unknown'      || AnchorNotFoundException
     }
 
     @Unroll
@@ -118,4 +121,26 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase {
         then: 'an DataspaceNotFoundException is thrown'
             thrown(DataspaceNotFoundException)
     }
+
+    @Sql([CLEAR_DATA, SET_DATA])
+    def 'Delete anchor'() {
+        when: 'delete anchor action is invoked'
+            objectUnderTest.deleteAnchor(DATASPACE_NAME, ANCHOR_NAME1)
+        then: 'anchor and associated data fragment are deleted'
+            assert anchorRepository.findById(DELETED_ANCHOR_ID).isEmpty()
+            assert fragmentRepository.findById(DELETED_FRAGMENT_ID).isEmpty()
+    }
+
+    @Unroll
+    @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
+    }
 }
index 1d9b4b1..a7d3e67 100644 (file)
@@ -6,4 +6,7 @@ INSERT INTO SCHEMA_SET (ID, NAME, DATASPACE_ID) VALUES
 
 INSERT INTO ANCHOR (ID, NAME, DATASPACE_ID, SCHEMA_SET_ID) VALUES
     (3001, 'ANCHOR-001', 1001, 2001),
-    (3002, 'ANCHOR-002', 1001, 2002);
\ No newline at end of file
+    (3002, 'ANCHOR-002', 1001, 2002);
+
+INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES
+    (4001, 1001, 3001, null, '/xpath', '{}');
\ No newline at end of file
index 0379ac2..1e4c9c7 100755 (executable)
@@ -2,6 +2,7 @@
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2020 Nordix Foundation
  *  Modifications Copyright (C) 2020 Bell Canada. All rights reserved.
+ *  Modifications Copyright (C) 2021 Pantheon.tech
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -62,9 +63,17 @@ public interface CpsAdminService {
      * Get an anchor in the given dataspace using the anchor name.
      *
      * @param dataspaceName dataspace name
-     * @param anchorName anchor name
+     * @param anchorName    anchor name
      * @return an anchor
      */
     @NonNull
     Anchor getAnchor(@NonNull String dataspaceName, @NonNull String anchorName);
+
+    /**
+     * Delete anchor by name in given dataspace.
+     *
+     * @param dataspaceName dataspace name
+     * @param anchorName    anchor name
+     */
+    void deleteAnchor(@NonNull String dataspaceName, @NonNull String anchorName);
 }
index 09550f1..2518573 100755 (executable)
@@ -2,6 +2,7 @@
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2020 Nordix Foundation
  *  Modifications Copyright (C) 2020 Bell Canada. All rights reserved.
+ *  Modifications Copyright (C) 2021 Pantheon.tech
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -52,4 +53,9 @@ public class CpsAdminServiceImpl implements CpsAdminService {
     public Anchor getAnchor(final String dataspaceName, final String anchorName) {
         return cpsAdminPersistenceService.getAnchor(dataspaceName, anchorName);
     }
+
+    @Override
+    public void deleteAnchor(final String dataspaceName, final String anchorName) {
+        cpsAdminPersistenceService.deleteAnchor(dataspaceName, anchorName);
+    }
 }
\ No newline at end of file
index f47af5f..35e07f8 100755 (executable)
@@ -2,6 +2,7 @@
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2020 Nordix Foundation. All rights reserved.
  *  Modifications Copyright (C) 2020 Bell Canada. All rights reserved.
+ *  Modifications Copyright (C) 2021 Pantheon.tech
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -67,4 +68,12 @@ public interface CpsAdminPersistenceService {
      */
     @NonNull
     Anchor getAnchor(@NonNull String dataspaceName, @NonNull String anchorName);
+
+    /**
+     * Delete anchor by name in given dataspace.
+     *
+     * @param dataspaceName dataspace name
+     * @param anchorName anchor name
+     */
+    void deleteAnchor(@NonNull String dataspaceName, @NonNull String anchorName);
 }
\ No newline at end of file
index 6631a20..b1fc4dc 100755 (executable)
@@ -2,6 +2,7 @@
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2020 Nordix Foundation
  *  Modifications Copyright (C) 2020 Bell Canada. All rights reserved.
+ *  Modifications Copyright (C) 2021 Pantheon.tech
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -61,4 +62,11 @@ class CpsAdminServiceImplSpec extends Specification {
         expect: 'the anchor provided by persistence service is returned as result'
             objectUnderTest.getAnchor('someDataspace','someAnchor') == anchor
     }
+
+    def 'Delete anchor.'() {
+        when: 'delete anchor is invoked'
+            objectUnderTest.deleteAnchor('someDataspace','someAnchor')
+        then: 'associated persistence service method is invoked with same parameters'
+             1 * mockCpsAdminPersistenceService.deleteAnchor('someDataspace','someAnchor')
+    }
 }