Merge "Handle errors during cm handle search"
authorToine Siebelink <toine.siebelink@est.tech>
Thu, 9 Jun 2022 16:08:18 +0000 (16:08 +0000)
committerGerrit Code Review <gerrit@onap.org>
Thu, 9 Jun 2022 16:08:18 +0000 (16:08 +0000)
cps-ncmp-rest/docs/openapi/ncmp.yml
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
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-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java

index 7a894f5..3259032 100755 (executable)
@@ -248,7 +248,7 @@ fetchModuleReferencesByCmHandle:
 
 searchCmHandles:
   post:
-    description: Execute cm handle query search, to be included in the result a cm-handle must fulfill ALL the conditions listed here
+    description: Execute cm handle query search, to be included in the result a cm-handle must fulfill ALL the conditions listed here, if one of the given module names does not exists, return with an empty collection.
     tags:
       - network-cm-proxy
     summary: Execute cm handle search using the available conditions
@@ -321,7 +321,7 @@ getCmHandlePropertiesById:
 
 searchCmHandleIds:
   post:
-    description: Execute cm handle query search, to be included in the result a cm-handle must fulfill ALL the conditions listed here
+    description: Execute cm handle query search, to be included in the result a cm-handle must fulfill ALL the conditions listed here, if one of the given module names does not exists, return with an empty collection.
     tags:
       - network-cm-proxy
     summary: Execute cm handle query upon a given set of query parameters
index c70e7be..6ba2a2c 100644 (file)
@@ -244,21 +244,21 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
                 + '"additional-properties":[],"public-properties":[]}]}', null)
     }
 
-    def 'Execute cm handle id search'(){
+    def 'Execute cm handle id search'() {
         given: 'valid CmHandleQueryApiParameters input'
             def cmHandleQueryApiParameters = new CmHandleQueryApiParameters()
             def conditionApiProperties = new ConditionApiProperties()
             conditionApiProperties.conditionName = 'hasAllModules'
-            conditionApiProperties.conditionParameters = [[moduleName:'module-name-1']]
+            conditionApiProperties.conditionParameters = [[moduleName: 'module-name-1']]
             cmHandleQueryApiParameters.cmHandleQueryParameters = [conditionApiProperties]
         and: 'valid CmHandleQueryParameters input'
             def cmHandleQueryParameters = new CmHandleQueryParameters()
             def conditionProperties = new ConditionProperties()
             conditionProperties.conditionName = 'hasAllModules'
-            conditionProperties.conditionParameters = [[moduleName:'module-name-1']]
+            conditionProperties.conditionParameters = [[moduleName: 'module-name-1']]
             cmHandleQueryParameters.cmHandleQueryParameters = [conditionProperties]
         and: 'query cm handle method return with a data node list'
-            mockCpsCmHandlerQueryService.queryCmHandles(cmHandleQueryParameters) >> [ new DataNode(leaves: [id:'cm-handle-id-1'] )]
+            mockCpsCmHandlerQueryService.queryCmHandles(cmHandleQueryParameters) >> [new DataNode(leaves: [id: 'cm-handle-id-1'])]
         when: 'execute cm handle search is called'
             def result = objectUnderTest.executeCmHandleIdSearch(cmHandleQueryApiParameters)
         then: 'result is the same collection as returned by the CPS Data Service'
index 047ec99..20a39f9 100755 (executable)
 package org.onap.cps.spi.impl;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 import javax.transaction.Transactional;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.spi.CpsAdminPersistenceService;
 import org.onap.cps.spi.entities.AnchorEntity;
 import org.onap.cps.spi.entities.DataspaceEntity;
@@ -34,6 +36,7 @@ import org.onap.cps.spi.entities.SchemaSetEntity;
 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.DataspaceNotFoundException;
 import org.onap.cps.spi.exceptions.ModuleNamesNotFoundException;
 import org.onap.cps.spi.model.Anchor;
 import org.onap.cps.spi.repository.AnchorRepository;
@@ -43,6 +46,7 @@ import org.onap.cps.spi.repository.YangResourceRepository;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.stereotype.Component;
 
+@Slf4j
 @Component
 @RequiredArgsConstructor
 public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceService {
@@ -113,7 +117,13 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic
 
     @Override
     public Collection<Anchor> queryAnchors(final String dataspaceName, final Collection<String> inputModuleNames) {
-        validateDataspaceAndModuleNames(dataspaceName, inputModuleNames);
+        try {
+            validateDataspaceAndModuleNames(dataspaceName, inputModuleNames);
+        } catch (DataspaceNotFoundException | ModuleNamesNotFoundException  e) {
+            log.info("Module search encountered unknown dataspace or modulename, treating this as nothing found");
+            return Collections.emptySet();
+        }
+
         final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
         final Collection<AnchorEntity> anchorEntities = anchorRepository
             .getAnchorsByDataspaceIdAndModuleNames(dataspaceEntity.getId(), inputModuleNames, inputModuleNames.size());
index ee478b8..e037350 100644 (file)
@@ -174,28 +174,17 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase {
     @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('dataspace-1', inputModuleNames)
+            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                           | inputModuleNames                                    || expectedAnchors
-            'one module'                       | ['module-name-1']                                   || [buildAnchor('anchor-2', 'dataspace-1', 'schema-set-2'), buildAnchor('anchor-1', 'dataspace-1', 'schema-set-1')]
-            'two modules'                      | ['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' | ['module-name-1', 'module-name-2', 'module-name-3'] || []
-    }
-
-    @Sql([CLEAR_DATA, SAMPLE_DATA_FOR_ANCHORS_WITH_MODULES])
-    def 'Query all anchors for an #scenario.'() {
-        when: 'attempt to query anchors'
-            objectUnderTest.queryAnchors(dataspaceName, moduleNames)
-        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       | moduleNames                                || expectedException            | expectedMessageDetails  | messageDoesNotContain
-            'unknown dataspace'               | 'db-does-not-exist' | ['does-not-matter']                        || DataspaceNotFoundException   | 'db-does-not-exist'     | 'does-not-matter'
-            'unknown module and known module' | 'dataspace-1'       | ['module-name-1', 'module-does-not-exist'] || ModuleNamesNotFoundException | 'module-does-not-exist' | 'module-name-1'
+            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) {
index b0d28ea..db2d2b2 100755 (executable)
@@ -74,7 +74,7 @@ public interface CpsAdminPersistenceService {
 
     /**
      * Query anchor names for the given module names in the provided dataspace.
-     *
+     * If dataspace or one of the given module names does not exists, return with an empty collection.
      *
      * @param dataspaceName dataspace name
      * @param moduleNames a collection of module names