summaryrefslogtreecommitdiffstats
path: root/cps-ri/src/main/java/org/onap/cps/spi/repository
diff options
context:
space:
mode:
Diffstat (limited to 'cps-ri/src/main/java/org/onap/cps/spi/repository')
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java94
-rwxr-xr-xcps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepository.java37
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQuery.java8
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java14
4 files changed, 101 insertions, 52 deletions
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 013487334..515bbd616 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 f389467a5..d20e4d35a 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 32041e7d5..de0c06014 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 b95491cd3..6cc6495b8 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;