diff options
10 files changed, 156 insertions, 75 deletions
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml index c38c13b7bf..ea1efcb3e9 100644 --- a/cps-ri/pom.xml +++ b/cps-ri/pom.xml @@ -33,7 +33,7 @@ <artifactId>cps-ri</artifactId>
<properties>
- <minimum-coverage>0.80</minimum-coverage>
+ <minimum-coverage>0.79</minimum-coverage>
</properties>
<dependencies>
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntityArranger.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntityArranger.java index 55d3c7e872..49e2dd2530 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntityArranger.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntityArranger.java @@ -47,6 +47,24 @@ public class FragmentEntityArranger { return reuniteChildrenWithTheirParents(fragmentEntityPerId); } + /** + * Convert a collection of (related) FragmentExtracts into FragmentEntities (trees) with descendants. + * + * @param anchorEntityPerId the anchor(entities) the fragments belong to + * @param fragmentExtracts FragmentExtracts to convert + * @return a collection of FragmentEntities (trees) with descendants. + */ + public static Collection<FragmentEntity> toFragmentEntityTreesAcrossAnchors( + final Map<Integer, AnchorEntity> anchorEntityPerId, final Collection<FragmentExtract> fragmentExtracts) { + final Map<Long, FragmentEntity> fragmentEntityPerId = new HashMap<>(); + for (final FragmentExtract fragmentExtract : fragmentExtracts) { + final AnchorEntity anchorEntity = anchorEntityPerId.get(fragmentExtract.getAnchorId()); + final FragmentEntity fragmentEntity = toFragmentEntity(anchorEntity, fragmentExtract); + fragmentEntityPerId.put(fragmentEntity.getId(), fragmentEntity); + } + return reuniteChildrenWithTheirParents(fragmentEntityPerId); + } + private static FragmentEntity toFragmentEntity(final AnchorEntity anchorEntity, final FragmentExtract fragmentExtract) { final FragmentEntity fragmentEntity = new FragmentEntity(); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentExtract.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentExtract.java index 52c1a603bb..3aa19e670b 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentExtract.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentExtract.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 2022-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ public interface FragmentExtract { Long getId(); - Long getAnchorId(); + Integer getAnchorId(); String getXpath(); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java index 3a1588a59a..be5c66db9a 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java @@ -36,6 +36,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -316,8 +317,9 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService description = "Time taken to query data nodes") public List<DataNode> queryDataNodes(final String dataspaceName, final String anchorName, final String cpsPath, final FetchDescendantsOption fetchDescendantsOption) { - final AnchorEntity anchorEntity = (Strings.isNullOrEmpty(anchorName)) ? ALL_ANCHORS - : getAnchorEntity(dataspaceName, anchorName); + final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); + final AnchorEntity anchorEntity = Strings.isNullOrEmpty(anchorName) ? ALL_ANCHORS + : anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); final CpsPathQuery cpsPathQuery; try { cpsPathQuery = CpsPathUtil.getCpsPathQuery(cpsPath); @@ -327,21 +329,30 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService Collection<FragmentEntity> fragmentEntities; if (canUseRegexQuickFind(fetchDescendantsOption, cpsPathQuery)) { - return getDataNodesUsingRegexQuickFind(fetchDescendantsOption, anchorEntity, cpsPathQuery); + return getDataNodesUsingRegexQuickFind(fetchDescendantsOption, dataspaceEntity, anchorEntity, cpsPathQuery); + } + + if (anchorEntity == ALL_ANCHORS) { + fragmentEntities = fragmentRepository.findByDataspaceAndCpsPath(dataspaceEntity, cpsPathQuery); + } else { + fragmentEntities = fragmentRepository.findByAnchorAndCpsPath(anchorEntity, cpsPathQuery); } - fragmentEntities = (anchorEntity == ALL_ANCHORS) ? fragmentRepository.findByCpsPath(cpsPathQuery) - : fragmentRepository.findByAnchorAndCpsPath(anchorEntity.getId(), cpsPathQuery); + if (cpsPathQuery.hasAncestorAxis()) { final Collection<String> ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery); - fragmentEntities = (anchorEntity == ALL_ANCHORS) ? getAncestorFragmentEntitiesAcrossAnchors(cpsPathQuery, - fragmentEntities) : getFragmentEntities(anchorEntity, ancestorXpaths, fetchDescendantsOption); + if (anchorEntity == ALL_ANCHORS) { + fragmentEntities = fragmentRepository.findByDataspaceAndXpathIn(dataspaceEntity, ancestorXpaths); + } else { + fragmentEntities = fragmentRepository.findByAnchorAndXpathIn(anchorEntity, ancestorXpaths); + } } + return createDataNodesFromProxiedFragmentEntities(fetchDescendantsOption, anchorEntity, fragmentEntities); } @Override public List<DataNode> queryDataNodesAcrossAnchors(final String dataspaceName, final String cpsPath, - final FetchDescendantsOption fetchDescendantsOption) { + final FetchDescendantsOption fetchDescendantsOption) { return queryDataNodes(dataspaceName, QUERY_ACROSS_ANCHORS, cpsPath, fetchDescendantsOption); } @@ -355,21 +366,29 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private List<DataNode> getDataNodesUsingRegexQuickFind(final FetchDescendantsOption fetchDescendantsOption, + final DataspaceEntity dataspaceEntity, final AnchorEntity anchorEntity, final CpsPathQuery cpsPathQuery) { final String xpathRegex = FragmentQueryBuilder.getXpathSqlRegexForQuickFindWithDescendants(cpsPathQuery); final List<FragmentExtract> fragmentExtracts = (anchorEntity == ALL_ANCHORS) - ? fragmentRepository.quickFindWithDescendantsAcrossAnchors(xpathRegex) + ? fragmentRepository.quickFindWithDescendantsAcrossAnchors(dataspaceEntity.getId(), xpathRegex) : fragmentRepository.quickFindWithDescendants(anchorEntity.getId(), xpathRegex); final Collection<FragmentEntity> fragmentEntities = - FragmentEntityArranger.toFragmentEntityTrees(anchorEntity, fragmentExtracts); + createFragmentEntitiesFromFragmentExtracts(anchorEntity, fragmentExtracts); return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities); } - private Collection<FragmentEntity> getAncestorFragmentEntitiesAcrossAnchors(final CpsPathQuery cpsPathQuery, - final Collection<FragmentEntity> fragmentEntities) { - final Collection<String> ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery); - return ancestorXpaths.isEmpty() ? Collections.emptyList() : fragmentRepository.findAllByXpathIn(ancestorXpaths); + private Collection<FragmentEntity> createFragmentEntitiesFromFragmentExtracts( + final AnchorEntity anchorEntity, final Collection<FragmentExtract> fragmentExtracts) { + if (anchorEntity == ALL_ANCHORS) { + final Collection<Integer> anchorIds = fragmentExtracts.stream() + .map(FragmentExtract::getAnchorId).collect(Collectors.toSet()); + final List<AnchorEntity> anchorEntities = anchorRepository.findAllById(anchorIds); + final Map<Integer, AnchorEntity> anchorEntityPerId = anchorEntities.stream() + .collect(Collectors.toMap(AnchorEntity::getId, Function.identity())); + return FragmentEntityArranger.toFragmentEntityTreesAcrossAnchors(anchorEntityPerId, fragmentExtracts); + } + return FragmentEntityArranger.toFragmentEntityTrees(anchorEntity, fragmentExtracts); } private List<DataNode> createDataNodesFromProxiedFragmentEntities( diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java index 0134873347..515bbd6165 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * Copyright (C) 2022-2023 Nordix Foundation * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -33,6 +33,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.cpspath.parser.CpsPathPrefixType; import org.onap.cps.cpspath.parser.CpsPathQuery; +import org.onap.cps.spi.entities.AnchorEntity; +import org.onap.cps.spi.entities.DataspaceEntity; import org.onap.cps.spi.entities.FragmentEntity; import org.onap.cps.utils.JsonObjectMapper; import org.springframework.stereotype.Component; @@ -45,6 +47,7 @@ public class FragmentQueryBuilder { private static final String REGEX_DESCENDANT_PATH_PREFIX = "^.*\\/"; private static final String REGEX_OPTIONAL_LIST_INDEX_POSTFIX = "(\\[@(?!.*\\[).*?])?$"; private static final String REGEX_FOR_QUICK_FIND_WITH_DESCENDANTS = "(\\[@.*?])?(\\/.*)?$"; + private static final AnchorEntity ACROSS_ALL_ANCHORS = null; @PersistenceContext private EntityManager entityManager; @@ -54,28 +57,24 @@ public class FragmentQueryBuilder { /** * Create a sql query to retrieve by anchor(id) and cps path. * - * @param anchorId the id of the anchor + * @param anchorEntity the anchor * @param cpsPathQuery the cps path query to be transformed into a sql query * @return a executable query object */ - public Query getQueryForAnchorAndCpsPath(final int anchorId, final CpsPathQuery cpsPathQuery) { - final StringBuilder sqlStringBuilder = new StringBuilder("SELECT * FROM FRAGMENT WHERE anchor_id = :anchorId"); - final Map<String, Object> queryParameters = new HashMap<>(); - queryParameters.put("anchorId", anchorId); - sqlStringBuilder.append(" AND xpath ~ :xpathRegex"); - return getQuery(cpsPathQuery, sqlStringBuilder, queryParameters); + public Query getQueryForAnchorAndCpsPath(final AnchorEntity anchorEntity, final CpsPathQuery cpsPathQuery) { + return getQueryForDataspaceOrAnchorAndCpsPath(anchorEntity.getDataspace(), anchorEntity, cpsPathQuery); } /** * Create a sql query to retrieve by cps path. * + * @param dataspaceEntity the dataspace * @param cpsPathQuery the cps path query to be transformed into a sql query * @return a executable query object */ - public Query getQueryForCpsPath(final CpsPathQuery cpsPathQuery) { - final StringBuilder sqlStringBuilder = new StringBuilder("SELECT * FROM FRAGMENT WHERE xpath ~ :xpathRegex"); - final Map<String, Object> queryParameters = new HashMap<>(); - return getQuery(cpsPathQuery, sqlStringBuilder, queryParameters); + public Query getQueryForDataspaceAndCpsPath(final DataspaceEntity dataspaceEntity, + final CpsPathQuery cpsPathQuery) { + return getQueryForDataspaceOrAnchorAndCpsPath(dataspaceEntity, ACROSS_ALL_ANCHORS, cpsPathQuery); } /** @@ -103,31 +102,45 @@ public class FragmentQueryBuilder { return xpathRegexBuilder.toString(); } - private Query getQuery(final CpsPathQuery cpsPathQuery, final StringBuilder sqlStringBuilder, - final Map<String, Object> queryParameters) { - final String xpathRegex = getXpathSqlRegex(cpsPathQuery); - queryParameters.put("xpathRegex", xpathRegex); - final List<String> queryBooleanOperatorsType = cpsPathQuery.getBooleanOperatorsType(); - if (cpsPathQuery.hasLeafConditions()) { - sqlStringBuilder.append(" AND ("); - final Queue<String> booleanOperatorsQueue = (queryBooleanOperatorsType == null) ? null : new LinkedList<>( - queryBooleanOperatorsType); - cpsPathQuery.getLeavesData().entrySet().forEach(entry -> { - sqlStringBuilder.append(" attributes @> "); - sqlStringBuilder.append("'" + jsonObjectMapper.asJsonString(entry) + "'"); - if (!(booleanOperatorsQueue == null || booleanOperatorsQueue.isEmpty())) { - sqlStringBuilder.append(" " + booleanOperatorsQueue.poll() + " "); - } - }); - sqlStringBuilder.append(")"); - } + private Query getQueryForDataspaceOrAnchorAndCpsPath(final DataspaceEntity dataspaceEntity, + final AnchorEntity anchorEntity, + final CpsPathQuery cpsPathQuery) { + final StringBuilder sqlStringBuilder = new StringBuilder(); + final Map<String, Object> queryParameters = new HashMap<>(); + + sqlStringBuilder.append("SELECT * FROM fragment WHERE "); + addDataspaceOrAnchor(sqlStringBuilder, queryParameters, dataspaceEntity, anchorEntity); + addXpathSearch(cpsPathQuery, sqlStringBuilder, queryParameters); + addLeafConditions(cpsPathQuery, sqlStringBuilder); addTextFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters); addContainsFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters); + final Query query = entityManager.createNativeQuery(sqlStringBuilder.toString(), FragmentEntity.class); setQueryParameters(query, queryParameters); return query; } + private static void addDataspaceOrAnchor(final StringBuilder sqlStringBuilder, + final Map<String, Object> queryParameters, + final DataspaceEntity dataspaceEntity, + final AnchorEntity anchorEntity) { + if (anchorEntity == ACROSS_ALL_ANCHORS) { + sqlStringBuilder.append("dataspace_id = :dataspaceId"); + queryParameters.put("dataspaceId", dataspaceEntity.getId()); + } else { + sqlStringBuilder.append("anchor_id = :anchorId"); + queryParameters.put("anchorId", anchorEntity.getId()); + } + } + + private static void addXpathSearch(final CpsPathQuery cpsPathQuery, + final StringBuilder sqlStringBuilder, + final Map<String, Object> queryParameters) { + sqlStringBuilder.append(" AND xpath ~ :xpathRegex"); + final String xpathRegex = getXpathSqlRegex(cpsPathQuery); + queryParameters.put("xpathRegex", xpathRegex); + } + private static StringBuilder getRegexStringBuilderWithPrefix(final CpsPathQuery cpsPathQuery) { final StringBuilder xpathRegexBuilder = new StringBuilder(); if (CpsPathPrefixType.ABSOLUTE.equals(cpsPathQuery.getCpsPathPrefixType())) { @@ -153,6 +166,27 @@ public class FragmentQueryBuilder { } } + private void addLeafConditions(final CpsPathQuery cpsPathQuery, final StringBuilder sqlStringBuilder) { + if (cpsPathQuery.hasLeafConditions()) { + sqlStringBuilder.append(" AND ("); + final List<String> queryBooleanOperatorsType = cpsPathQuery.getBooleanOperatorsType(); + final Queue<String> booleanOperatorsQueue = (queryBooleanOperatorsType == null) ? null : new LinkedList<>( + queryBooleanOperatorsType); + cpsPathQuery.getLeavesData().entrySet().forEach(entry -> { + sqlStringBuilder.append(" attributes @> "); + sqlStringBuilder.append("'"); + sqlStringBuilder.append(jsonObjectMapper.asJsonString(entry)); + sqlStringBuilder.append("'"); + if (!(booleanOperatorsQueue == null || booleanOperatorsQueue.isEmpty())) { + sqlStringBuilder.append(" "); + sqlStringBuilder.append(booleanOperatorsQueue.poll()); + sqlStringBuilder.append(" "); + } + }); + sqlStringBuilder.append(")"); + } + } + private static void addTextFunctionCondition(final CpsPathQuery cpsPathQuery, final StringBuilder sqlStringBuilder, final Map<String, Object> queryParameters) { 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 f389467a53..d20e4d35a4 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 @@ -27,6 +27,7 @@ import java.util.Collection; import java.util.List;
import java.util.Optional;
import org.onap.cps.spi.entities.AnchorEntity;
+import org.onap.cps.spi.entities.DataspaceEntity;
import org.onap.cps.spi.entities.FragmentEntity;
import org.onap.cps.spi.entities.FragmentExtract;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
@@ -46,18 +47,25 @@ public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, new DataNodeNotFoundException(anchorEntity.getDataspace().getName(), anchorEntity.getName(), xpath));
}
- boolean existsByAnchorId(int anchorId);
+ List<FragmentEntity> findByAnchorIdAndXpathIn(int anchorId, String[] xpaths);
- @Query("SELECT f FROM FragmentEntity f WHERE anchor = :anchor")
- List<FragmentExtract> findAllExtractsByAnchor(@Param("anchor") AnchorEntity anchorEntity);
+ default List<FragmentEntity> findByAnchorAndXpathIn(final AnchorEntity anchorEntity,
+ final Collection<String> xpaths) {
+ return findByAnchorIdAndXpathIn(anchorEntity.getId(), xpaths.toArray(new String[0]));
+ }
- @Query(value = "SELECT * FROM fragment WHERE xpath = ANY (:xpaths)", nativeQuery = true)
- List<FragmentEntity> findAllByXpathIn(@Param("xpaths") String[] xpath);
+ List<FragmentEntity> findByDataspaceIdAndXpathIn(int dataspaceId, String[] xpaths);
- default List<FragmentEntity> findAllByXpathIn(final Collection<String> xpaths) {
- return findAllByXpathIn(xpaths.toArray(new String[0]));
+ default List<FragmentEntity> findByDataspaceAndXpathIn(final DataspaceEntity dataspaceEntity,
+ final Collection<String> xpaths) {
+ return findByDataspaceIdAndXpathIn(dataspaceEntity.getId(), xpaths.toArray(new String[0]));
}
+ boolean existsByAnchorId(int anchorId);
+
+ @Query("SELECT f FROM FragmentEntity f WHERE anchor = :anchor")
+ List<FragmentExtract> findAllExtractsByAnchor(@Param("anchor") AnchorEntity anchorEntity);
+
@Modifying
@Query(value = "DELETE FROM fragment WHERE anchor_id = ANY (:anchorIds)", nativeQuery = true)
void deleteByAnchorIdIn(@Param("anchorIds") int[] anchorIds);
@@ -92,12 +100,18 @@ public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, @Query(value = "SELECT id, anchor_id AS anchorId, xpath, parent_id AS parentId,"
+ " CAST(attributes AS TEXT) AS attributes"
- + " FROM FRAGMENT WHERE anchor_id = :anchorId"
- + " AND xpath ~ :xpathRegex",
+ + " FROM FRAGMENT WHERE anchor_id = :anchorId AND xpath ~ :xpathRegex",
nativeQuery = true)
List<FragmentExtract> quickFindWithDescendants(@Param("anchorId") int anchorId,
@Param("xpathRegex") String xpathRegex);
+ @Query(value = "SELECT id, anchor_id AS anchorId, xpath, parent_id AS parentId,"
+ + " CAST(attributes AS TEXT) AS attributes"
+ + " FROM FRAGMENT WHERE dataspace_id = :dataspaceId AND xpath ~ :xpathRegex",
+ nativeQuery = true)
+ List<FragmentExtract> quickFindWithDescendantsAcrossAnchors(@Param("dataspaceId") int dataspaceId,
+ @Param("xpathRegex") String xpathRegex);
+
@Query(value = "SELECT xpath FROM fragment WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths)",
nativeQuery = true)
List<String> findAllXpathByAnchorIdAndXpathIn(@Param("anchorId") int anchorId,
@@ -136,9 +150,4 @@ public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, return findExtractsWithDescendants(anchorId, xpaths.toArray(new String[0]), maxDepth);
}
- @Query(value = "SELECT id, anchor_id AS anchorId, xpath, parent_id AS parentId,"
- + " CAST(attributes AS TEXT) AS attributes"
- + " FROM FRAGMENT WHERE xpath ~ :xpathRegex",
- nativeQuery = true)
- List<FragmentExtract> quickFindWithDescendantsAcrossAnchors(@Param("xpathRegex") String xpathRegex);
}
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQuery.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQuery.java index 32041e7d5e..de0c060148 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQuery.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQuery.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2023 Nordix Foundation. * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,10 +23,12 @@ package org.onap.cps.spi.repository; import java.util.List; import org.onap.cps.cpspath.parser.CpsPathQuery; +import org.onap.cps.spi.entities.AnchorEntity; +import org.onap.cps.spi.entities.DataspaceEntity; import org.onap.cps.spi.entities.FragmentEntity; public interface FragmentRepositoryCpsPathQuery { - List<FragmentEntity> findByAnchorAndCpsPath(int anchorId, CpsPathQuery cpsPathQuery); + List<FragmentEntity> findByAnchorAndCpsPath(AnchorEntity anchorEntity, CpsPathQuery cpsPathQuery); - List<FragmentEntity> findByCpsPath(CpsPathQuery cpsPathQuery); + List<FragmentEntity> findByDataspaceAndCpsPath(DataspaceEntity dataspaceEntity, CpsPathQuery cpsPathQuery); } diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java index b95491cd36..6cc6495b8d 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation. + * Copyright (C) 2021-2023 Nordix Foundation. * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,6 +29,8 @@ import javax.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.cpspath.parser.CpsPathQuery; +import org.onap.cps.spi.entities.AnchorEntity; +import org.onap.cps.spi.entities.DataspaceEntity; import org.onap.cps.spi.entities.FragmentEntity; @RequiredArgsConstructor @@ -42,8 +44,9 @@ public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCps @Override @Transactional - public List<FragmentEntity> findByAnchorAndCpsPath(final int anchorId, final CpsPathQuery cpsPathQuery) { - final Query query = fragmentQueryBuilder.getQueryForAnchorAndCpsPath(anchorId, cpsPathQuery); + public List<FragmentEntity> findByAnchorAndCpsPath(final AnchorEntity anchorEntity, + final CpsPathQuery cpsPathQuery) { + final Query query = fragmentQueryBuilder.getQueryForAnchorAndCpsPath(anchorEntity, cpsPathQuery); final List<FragmentEntity> fragmentEntities = query.getResultList(); log.debug("Fetched {} fragment entities by anchor and cps path.", fragmentEntities.size()); return fragmentEntities; @@ -51,8 +54,9 @@ public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCps @Override @Transactional - public List<FragmentEntity> findByCpsPath(final CpsPathQuery cpsPathQuery) { - final Query query = fragmentQueryBuilder.getQueryForCpsPath(cpsPathQuery); + public List<FragmentEntity> findByDataspaceAndCpsPath(final DataspaceEntity dataspaceEntity, + final CpsPathQuery cpsPathQuery) { + final Query query = fragmentQueryBuilder.getQueryForDataspaceAndCpsPath(dataspaceEntity, cpsPathQuery); final List<FragmentEntity> fragmentEntities = query.getResultList(); log.debug("Fetched {} fragment entities by cps path across all anchors.", fragmentEntities.size()); return fragmentEntities; diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy index 4e596da14d..d64617caf8 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy @@ -25,7 +25,6 @@ import org.onap.cps.api.CpsQueryService import org.onap.cps.integration.base.FunctionalSpecBase import org.onap.cps.spi.FetchDescendantsOption import org.onap.cps.spi.exceptions.CpsPathException -import spock.lang.Ignore import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS @@ -235,7 +234,6 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { thrown(CpsPathException) } - @Ignore def 'Cps Path query across anchors with #scenario.'() { when: 'a query is executed to get a data nodes across anchors by the given CpsPath' def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, cpsPath, OMIT_DESCENDANTS) @@ -261,7 +259,6 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { 'ancestor combined with text condition' | '//books/title[text()="Matilda"]/ancestor::bookstore' || ["/bookstore"] } - @Ignore def 'Cps Path query across anchors with #scenario descendants.'() { when: 'a query is executed to get a data node by the given cps path' def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '/bookstore', fetchDescendantsOption) @@ -276,7 +273,6 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { 'all' | INCLUDE_ALL_DESCENDANTS || 17 } - @Ignore def 'Cps Path query across anchors with ancestors and #scenario descendants.'() { when: 'a query is executed to get a data node by the given cps path' def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '//books/ancestor::bookstore', fetchDescendantsOption) diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy index 065365748c..0af01ac77b 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy @@ -63,8 +63,7 @@ class QueryPerfTest extends CpsPerfTestBase { recordAndAssertPerformance("Query across anchors ${scenario}", durationLimit, durationInMillis) where: 'the following parameters are used' scenario | cpspath || durationLimit | expectedNumberOfDataNodes - // FIXME Current implementation of queryDataNodesAcrossAnchors throws NullPointerException for next case. Uncomment after CPS-1582 is done. - // 'top element' | '/openroadm-devices' || 1 | 5 * (50 * 86 + 1) + 'top element' | '/openroadm-devices' || 1 | 5 * (50 * 86 + 1) 'leaf condition' | '//openroadm-device[@ne-state="inservice"]' || 2500 | 5 * (50 * 86) 'ancestors' | '//openroadm-device/ancestor::openroadm-devices' || 12000 | 5 * (50 * 86 + 1) 'leaf condition + ancestors' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 1000 | 5 * (50 * 86 + 1) |