[BUG] Remove slow validation check during module search (CPS-2190 #2) 68/137768/2
authordanielhanrahan <daniel.hanrahan@est.tech>
Thu, 25 Apr 2024 13:33:05 +0000 (14:33 +0100)
committerdanielhanrahan <daniel.hanrahan@est.tech>
Thu, 25 Apr 2024 15:04:38 +0000 (16:04 +0100)
The check for existing modules is extremely slow, being dependent on
the file sizes of the Yang modules being queries.
The validation check is also completely unnecessary, since it simply
ignores any exceptions and returns an empty set, which the main logic
does implicitly. (The Dataspace check is also not needed, as the NCMP
dataspace is guaranteed to exist.)

Issue-ID: CPS-2190
Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech>
Change-Id: I329c1f8aac3f50bda0333e6c9c686f47af2e009f

cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java
cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAnchorServiceIntegrationSpec.groovy
integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/ModuleQueryPerfTest.groovy

index 2fb08d2..d697fd5 100755 (executable)
@@ -1,6 +1,6 @@
 /*
  * ============LICENSE_START=======================================================
- * Copyright (C) 2020-2023 Nordix Foundation.
+ * Copyright (C) 2020-2024 Nordix Foundation.
  * Modifications Copyright (C) 2020-2022 Bell Canada.
  * Modifications Copyright (C) 2021 Pantheon.tech
  * Modifications Copyright (C) 2022 TechMahindra Ltd.
@@ -25,8 +25,6 @@ package org.onap.cps.spi.impl;
 
 import jakarta.transaction.Transactional;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -34,17 +32,13 @@ import org.onap.cps.spi.CpsAdminPersistenceService;
 import org.onap.cps.spi.entities.AnchorEntity;
 import org.onap.cps.spi.entities.DataspaceEntity;
 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.model.Dataspace;
 import org.onap.cps.spi.repository.AnchorRepository;
 import org.onap.cps.spi.repository.DataspaceRepository;
 import org.onap.cps.spi.repository.SchemaSetRepository;
-import org.onap.cps.spi.repository.YangResourceRepository;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.stereotype.Component;
 
@@ -56,7 +50,6 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic
     private final DataspaceRepository dataspaceRepository;
     private final AnchorRepository anchorRepository;
     private final SchemaSetRepository schemaSetRepository;
-    private final YangResourceRepository yangResourceRepository;
 
     @Override
     public void createDataspace(final String dataspaceName) {
@@ -139,13 +132,6 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic
 
     @Override
     public Collection<Anchor> queryAnchors(final String dataspaceName, final Collection<String> 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());
@@ -199,25 +185,4 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic
     private static Dataspace toDataspace(final DataspaceEntity dataspaceEntity) {
         return Dataspace.builder().name(dataspaceEntity.getName()).build();
     }
-
-    private void validateDataspaceAndModuleNames(final String dataspaceName,
-        final Collection<String> inputModuleNames) {
-        final Collection<String> retrievedModuleReferences =
-            yangResourceRepository.findAllModuleReferencesByDataspaceAndModuleNames(dataspaceName, inputModuleNames)
-                .stream().map(YangResourceModuleReference::getModuleName)
-                .collect(Collectors.toList());
-        if (retrievedModuleReferences.isEmpty()) {
-            verifyDataspaceName(dataspaceName);
-        }
-        if (inputModuleNames.size() > retrievedModuleReferences.size()) {
-            final List<String> unknownModules = inputModuleNames.stream()
-                .filter(moduleName -> !retrievedModuleReferences.contains(moduleName))
-                .collect(Collectors.toList());
-            throw new ModuleNamesNotFoundException(dataspaceName, unknownModules);
-        }
-    }
-
-    private void verifyDataspaceName(final String dataspaceName) {
-        dataspaceRepository.getByName(dataspaceName);
-    }
 }
index b37f635..8be0d9a 100644 (file)
@@ -91,26 +91,6 @@ public interface YangResourceRepository extends JpaRepository<YangResourceEntity
             @Param("dataspaceName") String dataspaceName, @Param("anchorName") String anchorName,
             @Param("moduleName") String moduleName, @Param("revision") String revision);
 
-    @Query(value = """
-            SELECT DISTINCT
-                yang_resource.*
-            FROM
-                     dataspace
-                JOIN schema_set ON schema_set.dataspace_id = dataspace.id
-                JOIN schema_set_yang_resources ON schema_set_yang_resources.schema_set_id = schema_set.id
-                JOIN yang_resource ON yang_resource.id = schema_set_yang_resources.yang_resource_id
-            WHERE
-                    dataspace.name = :dataspaceName
-                AND yang_resource.module_name = ANY ( :moduleNames )
-            """, nativeQuery = true)
-    Set<YangResourceModuleReference> findAllModuleReferencesByDataspaceAndModuleNames(
-            @Param("dataspaceName") String dataspaceName, @Param("moduleNames") String[] moduleNames);
-
-    default Set<YangResourceModuleReference> findAllModuleReferencesByDataspaceAndModuleNames(
-        final String dataspaceName, final Collection<String> moduleNames) {
-        return findAllModuleReferencesByDataspaceAndModuleNames(dataspaceName, moduleNames.toArray(new String[0]));
-    }
-
     @Modifying
     @Query(value = "DELETE FROM schema_set_yang_resources WHERE schema_set_id = :schemaSetId", nativeQuery = true)
     void deleteSchemaSetYangResourceForSchemaSetId(@Param("schemaSetId") int schemaSetId);
index 04c5dfc..4bba8a5 100644 (file)
@@ -84,15 +84,11 @@ class CpsAnchorServiceIntegrationSpec extends CpsIntegrationSpecBase {
             objectUnderTest.deleteAnchor(GENERAL_TEST_DATASPACE, 'newAnchor')
     }
 
-    def 'Query anchors without any known modules and #scenario'() {
+    def 'Query anchors without any known modules'() {
         when: 'querying for anchors with #scenario'
-            def result = objectUnderTest.queryAnchorNames(dataspaceName, ['unknownModule'])
+            def result = objectUnderTest.queryAnchorNames(GENERAL_TEST_DATASPACE, ['unknownModule'])
         then: 'an empty result is returned (no error)'
             assert result == []
-        where:
-            scenario                 | dataspaceName
-            'non existing database'  | 'nonExistingDataspace'
-            'just unknown module(s)' | GENERAL_TEST_DATASPACE
     }
 
     def 'Update anchor schema set.'() {
index 8609dd5..6efebd4 100644 (file)
@@ -76,7 +76,7 @@ class ModuleQueryPerfTest extends CpsPerfTestBase {
             )
     }
 
-    def 'Bug CPS-2190: Querying anchors by module name IS dependant on the file size of the module.'() {
+    def 'Querying anchors by module name is NOT dependant on the file size of the module.'() {
         when: 'we search for anchors with given Yang module name'
             resourceMeter.start()
             def result = cpsAnchorService.queryAnchorNames(CPS_PERFORMANCE_TEST_DATASPACE, [yangModuleName])
@@ -86,11 +86,11 @@ class ModuleQueryPerfTest extends CpsPerfTestBase {
         and: 'operation completes with expected resource usage'
             recordAndAssertResourceUsage("Query for anchors with ${scenario}",
                     expectedTimeInSeconds, resourceMeter.totalTimeInSeconds,
-                    300, resourceMeter.totalMemoryUsageInMB)
+                    150, resourceMeter.totalMemoryUsageInMB)
         where: 'the following parameters are used'
             scenario         | yangModuleName || expectedTimeInSeconds
             '1 KB module'    | 'module0'      || 3
-            '1000 KB module' | 'module1'      || 12
+            '1000 KB module' | 'module1'      || 3
     }
 
     def 'Module query - Clean up test data.'() {