Retrieve All anchors for a given Dataspace

Issue-ID: CPS-8
Signed-off-by: puthuparambil.aditya <aditya.puthuparambil@bell.ca>
Change-Id: Idb2e4f83d390f078345e556d89781e0bf4a9a41f
diff --git a/cps-rest/docs/api/swagger/openapi.yml b/cps-rest/docs/api/swagger/openapi.yml
index 56a012f..441d5e5 100755
--- a/cps-rest/docs/api/swagger/openapi.yml
+++ b/cps-rest/docs/api/swagger/openapi.yml
@@ -61,12 +61,17 @@
         401:
           description: Unauthorized
           content: {}
+        400:
+          description: Bad Request
+          content: {}
         403:
           description: Forbidden
-          content: {}
         404:
           description: Not Found
           content: {}
+        204:
+          description: No Content
+          content: {}
     post:
       tags:
         - cps-rest
diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java
index 30d3e24..32ea35c 100755
--- a/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java
+++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java
@@ -26,6 +26,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Collection;
 import javax.validation.Valid;
 import org.modelmapper.ModelMapper;
 import org.onap.cps.api.CpService;
@@ -107,8 +108,10 @@
     }
 
     @Override
+
     public ResponseEntity<Object> getAnchors(final String dataspaceName) {
-        return null;
+        final Collection<Anchor> anchorDetails = cpsAdminService.getAnchors(dataspaceName);
+        return new ResponseEntity<>(anchorDetails, HttpStatus.OK);
     }
 
     @Override
diff --git a/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java b/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java
index fc0164f..00e72a1 100644
--- a/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java
+++ b/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java
@@ -23,6 +23,7 @@
 import org.onap.cps.rest.controller.CpsRestController;
 import org.onap.cps.rest.model.ErrorMessage;
 import org.onap.cps.spi.exceptions.AnchorAlreadyDefinedException;
+import org.onap.cps.spi.exceptions.CpsAdminException;
 import org.onap.cps.spi.exceptions.CpsException;
 import org.onap.cps.spi.exceptions.DataValidationException;
 import org.onap.cps.spi.exceptions.ModelValidationException;
@@ -48,7 +49,7 @@
     }
 
     @ExceptionHandler({ModelValidationException.class, DataValidationException.class,
-        SchemaSetAlreadyDefinedException.class, AnchorAlreadyDefinedException.class})
+        SchemaSetAlreadyDefinedException.class, AnchorAlreadyDefinedException.class, CpsAdminException.class})
     public static ResponseEntity<Object> handleBadRequestExceptions(final CpsException exception) {
         return buildErrorResponse(HttpStatus.BAD_REQUEST, exception.getMessage(), extractDetails(exception));
     }
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml
index b5fe933..89b19d5 100644
--- a/cps-ri/pom.xml
+++ b/cps-ri/pom.xml
@@ -36,6 +36,10 @@
             <groupId>org.projectlombok</groupId>

             <artifactId>lombok</artifactId>

         </dependency>

+        <dependency>

+            <groupId>org.modelmapper</groupId>

+            <artifactId>modelmapper</artifactId>

+        </dependency>

         <!-- Test dependencies -->

         <dependency>

             <groupId>org.springframework.boot</groupId>

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 f119507..48e7303 100644
--- 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
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2020 Nordix Foundation. All rights reserved.
+ *  Modifications Copyright (C) 2020 Bell Canada. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +21,10 @@
 
 package org.onap.cps.spi.impl;
 
+import java.lang.reflect.Type;
+import java.util.Collection;
+import org.modelmapper.ModelMapper;
+import org.modelmapper.TypeToken;
 import org.onap.cps.spi.CpsAdminPersistenceService;
 import org.onap.cps.spi.entities.Dataspace;
 import org.onap.cps.spi.entities.Fragment;
@@ -61,4 +66,12 @@
             throw new AnchorAlreadyDefinedException(anchor.getDataspaceName(), anchorName, ex);
         }
     }
+
+    @Override
+    public Collection<Anchor> getAnchors(final String dataspaceName) {
+        final Dataspace dataspace = dataspaceRepository.getByName(dataspaceName);
+        final Collection<Fragment> fragments = fragmentRepository.findFragmentsThatAreAnchorsByDataspace(dataspace);
+        final Type anchorListType = new TypeToken<Collection<Anchor>>() {}.getType();
+        return new ModelMapper().map(fragments, anchorListType);
+    }
 }
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepository.java
index ba83f15..7ae7c13 100755
--- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepository.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepository.java
@@ -1,6 +1,7 @@
 /*-

  * ============LICENSE_START=======================================================

  *  Copyright (C) 2020 Nordix Foundation. All rights reserved.

+ *  Modifications Copyright (C) 2020 Bell Canada. All rights reserved.

  * ================================================================================

  * Licensed under the Apache License, Version 2.0 (the "License");

  * you may not use this file except in compliance with the License.

@@ -20,10 +21,20 @@
 

 package org.onap.cps.spi.repository;

 

+import java.util.Collection;

+import org.onap.cps.spi.entities.Dataspace;

 import org.onap.cps.spi.entities.Fragment;

 import org.springframework.data.jpa.repository.JpaRepository;

+import org.springframework.data.jpa.repository.Query;

+import org.springframework.data.repository.query.Param;

 import org.springframework.stereotype.Repository;

 

 @Repository

 public interface FragmentRepository extends JpaRepository<Fragment, Integer> {

+

+    default Collection<Fragment> findFragmentsThatAreAnchorsByDataspace(Dataspace dataspace) {

+        return findFragmentsByDataspaceAndParentFragmentIsNull(dataspace);

+    }

+

+    Collection<Fragment> findFragmentsByDataspaceAndParentFragmentIsNull(Dataspace dataspace);

 }
\ No newline at end of file
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 98ea8eb..a2c05bf 100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java
@@ -20,6 +20,7 @@
 
 package org.onap.cps.api;
 
+import java.util.Collection;
 import org.onap.cps.spi.exceptions.CpsException;
 import org.onap.cps.spi.model.Anchor;
 
@@ -36,4 +37,12 @@
      * @throws CpsException if input data is invalid.
      */
     String createAnchor(Anchor anchor);
+
+    /**
+     * Read all anchors in the given a dataspace.
+     *
+     * @param dataspaceName dataspace name
+     * @return a collection of anchors
+     */
+    Collection<Anchor> getAnchors(String dataspaceName);
 }
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 b4deef6..5d9bc01 100644
--- 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
@@ -20,6 +20,7 @@
 
 package org.onap.cps.api.impl;
 
+import java.util.Collection;
 import org.onap.cps.api.CpsAdminService;
 import org.onap.cps.spi.CpsAdminPersistenceService;
 import org.onap.cps.spi.model.Anchor;
@@ -36,4 +37,9 @@
     public String createAnchor(final Anchor anchor) {
         return cpsAdminPersistenceService.createAnchor(anchor);
     }
+
+    @Override
+    public Collection<Anchor> getAnchors(final String dataspaceName) {
+        return cpsAdminPersistenceService.getAnchors(dataspaceName);
+    }
 }
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 6709c1f..4e88d49 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2020 Nordix Foundation. All rights reserved.
+ *  Modifications Copyright (C) 2020 Bell Canada. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +21,7 @@
 
 package org.onap.cps.spi;
 
+import java.util.Collection;
 import org.onap.cps.spi.model.Anchor;
 
 /*
@@ -34,4 +36,12 @@
      * @return the anchor name.
      */
     String createAnchor(Anchor anchor);
+
+    /**
+     * Read all anchors in the given a dataspace.
+     *
+     * @param dataspaceName dataspace name
+     * @return a collection of anchors
+     */
+    Collection<Anchor> getAnchors(String dataspaceName);
 }
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 65a8e71..d31a2f7 100644
--- 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
@@ -20,8 +20,8 @@
 
 package org.onap.cps.api.impl
 
-
 import org.onap.cps.spi.CpsAdminPersistenceService
+import org.onap.cps.spi.exceptions.DataspaceNotFoundException
 import org.onap.cps.spi.model.Anchor
 import spock.lang.Specification
 
@@ -52,4 +52,24 @@
             def exceptionThrownInServiceLayer = thrown(Exception)
             exceptionThrownInServiceLayer == exceptionThrownInPersistenceLayer
     }
+
+    def 'Retrieve all anchors for an existing dataspace'() {
+        given: 'that the dataspace exist and an anchor is associated with the dataspace'
+            Collection<Anchor> anchorCollection = Arrays.asList(anchor)
+            mockCpsAdminPersistenceService.getAnchors('dummyDataspace') >> { anchorCollection }
+        expect: 'we try to retrieve an anchor, a collection of anchor is returned by the service'
+            objectUnderTest.getAnchors('dummyDataspace') == anchorCollection
+    }
+
+    def 'Retrieve all anchors for a non existing dataspace'() {
+        given: 'that the dataspace does not exist, service throws an exception'
+            def exceptionThrownInPersistenceLayer = new DataspaceNotFoundException(_ as String)
+            mockCpsAdminPersistenceService.getAnchors('dummyDataspace') >>
+                    { throw exceptionThrownInPersistenceLayer }
+        when: 'we try to retrieve a anchor with a non-existant dataspace'
+            objectUnderTest.getAnchors('dummyDataspace')
+        then: 'the same exception is thrown by CPS'
+            def exceptionThrownInServiceLayer = thrown(Exception)
+            exceptionThrownInServiceLayer == exceptionThrownInPersistenceLayer
+    }
 }