diff options
Diffstat (limited to 'cps-ri/src/main')
6 files changed, 146 insertions, 89 deletions
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java index 2ffbb4ae0e..82afc5a818 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java @@ -44,6 +44,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.ToString; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; @@ -89,6 +90,7 @@ public class FragmentEntity implements Serializable { @JoinColumn(name = "anchor_id") private AnchorEntity anchor; + @ToString.Exclude @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") private Set<FragmentEntity> childFragments; 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 2cebfc72c0..162b268d87 100755 --- 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,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2020-2022 Nordix Foundation. + * Copyright (C) 2020-2023 Nordix Foundation. * Modifications Copyright (C) 2020-2022 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2022 TechMahindra Ltd. @@ -131,6 +131,13 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic } @Override + public Collection<Anchor> getAnchors(final String dataspaceName, final Collection<String> schemaSetNames) { + final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); + return anchorRepository.findAllByDataspaceAndSchemaSetNameIn(dataspaceEntity, schemaSetNames) + .stream().map(CpsAdminPersistenceServiceImpl::toAnchor).collect(Collectors.toSet()); + } + + @Override public Collection<Anchor> queryAnchors(final String dataspaceName, final Collection<String> inputModuleNames) { try { validateDataspaceAndModuleNames(dataspaceName, inputModuleNames); @@ -157,6 +164,13 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic anchorRepository.delete(anchorEntity); } + @Transactional + @Override + public void deleteAnchors(final String dataspaceName, final Collection<String> anchorNames) { + final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName); + anchorRepository.deleteAllByDataspaceAndNameIn(dataspaceEntity, anchorNames); + } + private AnchorEntity getAnchorEntity(final String dataspaceName, final String anchorName) { final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName); return anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); 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 5b310efd5d..f634008dc6 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 @@ -3,7 +3,7 @@ * Copyright (C) 2021-2023 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2020-2022 Bell Canada. - * Modifications Copyright (C) 2022 TechMahindra Ltd. + * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,6 +57,7 @@ import org.onap.cps.spi.exceptions.ConcurrencyException; import org.onap.cps.spi.exceptions.CpsAdminException; import org.onap.cps.spi.exceptions.CpsPathException; import org.onap.cps.spi.exceptions.DataNodeNotFoundException; +import org.onap.cps.spi.exceptions.DataNodeNotFoundExceptionBatch; import org.onap.cps.spi.model.DataNode; import org.onap.cps.spi.model.DataNodeBuilder; import org.onap.cps.spi.repository.AnchorRepository; @@ -120,7 +121,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService private void addNewChildDataNode(final String dataspaceName, final String anchorName, final String parentNodeXpath, final DataNode newChild) { final FragmentEntity parentFragmentEntity = - getFragmentWithoutDescendantsByXpath(dataspaceName, anchorName, parentNodeXpath); + getFragmentEntity(dataspaceName, anchorName, parentNodeXpath); final FragmentEntity newChildAsFragmentEntity = convertToFragmentWithAllDescendants(parentFragmentEntity.getDataspace(), parentFragmentEntity.getAnchor(), newChild); @@ -136,7 +137,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService private void addChildrenDataNodes(final String dataspaceName, final String anchorName, final String parentNodeXpath, final Collection<DataNode> newChildren) { final FragmentEntity parentFragmentEntity = - getFragmentWithoutDescendantsByXpath(dataspaceName, anchorName, parentNodeXpath); + getFragmentEntity(dataspaceName, anchorName, parentNodeXpath); final List<FragmentEntity> fragmentEntities = new ArrayList<>(newChildren.size()); try { newChildren.forEach(newChildAsDataNode -> { @@ -249,17 +250,28 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } @Override - public DataNode getDataNode(final String dataspaceName, final String anchorName, final String xpath, - final FetchDescendantsOption fetchDescendantsOption) { - final FragmentEntity fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, xpath, - fetchDescendantsOption); - return toDataNode(fragmentEntity, fetchDescendantsOption); + public Collection<DataNode> getDataNodes(final String dataspaceName, final String anchorName, + final String xpath, + final FetchDescendantsOption fetchDescendantsOption) { + final String targetXpath = isRootXpath(xpath) ? xpath : CpsPathUtil.getNormalizedXpath(xpath); + final Collection<DataNode> dataNodes = getDataNodesForMultipleXpaths(dataspaceName, anchorName, + Collections.singletonList(targetXpath), fetchDescendantsOption); + if (dataNodes.isEmpty()) { + throw new DataNodeNotFoundException(dataspaceName, anchorName, xpath); + } + return dataNodes; } @Override - public Collection<DataNode> getDataNodes(final String dataspaceName, final String anchorName, - final Collection<String> xpaths, - final FetchDescendantsOption fetchDescendantsOption) { + public Collection<DataNode> getDataNodesForMultipleXpaths(final String dataspaceName, final String anchorName, + final Collection<String> xpaths, + final FetchDescendantsOption fetchDescendantsOption) { + final Collection<FragmentEntity> fragmentEntities = getFragmentEntities(dataspaceName, anchorName, xpaths); + return toDataNodes(fragmentEntities, fetchDescendantsOption); + } + + private Collection<FragmentEntity> getFragmentEntities(final String dataspaceName, final String anchorName, + final Collection<String> xpaths) { final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); @@ -271,7 +283,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService try { normalizedXpaths.add(CpsPathUtil.getNormalizedXpath(xpath)); } catch (final PathParsingException e) { - log.warn("Error parsing xpath \"{}\" in getDataNodes: {}", xpath, e.getMessage()); + log.warn("Error parsing xpath \"{}\": {}", xpath, e.getMessage()); } } final Collection<FragmentEntity> fragmentEntities = @@ -283,17 +295,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService fragmentEntities.addAll(FragmentEntityArranger.toFragmentEntityTrees(anchorEntity, fragmentExtracts)); } - return toDataNodes(fragmentEntities, fetchDescendantsOption); + return fragmentEntities; } - private FragmentEntity getFragmentWithoutDescendantsByXpath(final String dataspaceName, - final String anchorName, - final String xpath) { - return getFragmentByXpath(dataspaceName, anchorName, xpath, FetchDescendantsOption.OMIT_DESCENDANTS); - } - - private FragmentEntity getFragmentByXpath(final String dataspaceName, final String anchorName, - final String xpath, final FetchDescendantsOption fetchDescendantsOption) { + private FragmentEntity getFragmentEntity(final String dataspaceName, final String anchorName, final String xpath) { final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); final FragmentEntity fragmentEntity; @@ -304,13 +309,8 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService .stream().findFirst().orElse(null); } else { final String normalizedXpath = getNormalizedXpath(xpath); - if (FetchDescendantsOption.OMIT_DESCENDANTS.equals(fetchDescendantsOption)) { - fragmentEntity = - fragmentRepository.getByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, normalizedXpath); - } else { - fragmentEntity = buildFragmentEntitiesFromFragmentExtracts(anchorEntity, normalizedXpath) - .stream().findFirst().orElse(null); - } + fragmentEntity = + fragmentRepository.getByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, normalizedXpath); } if (fragmentEntity == null) { throw new DataNodeNotFoundException(dataspaceEntity.getName(), anchorEntity.getName(), xpath); @@ -486,7 +486,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService @Override public void updateDataLeaves(final String dataspaceName, final String anchorName, final String xpath, final Map<String, Serializable> updateLeaves) { - final FragmentEntity fragmentEntity = getFragmentWithoutDescendantsByXpath(dataspaceName, anchorName, xpath); + final FragmentEntity fragmentEntity = getFragmentEntity(dataspaceName, anchorName, xpath); final String currentLeavesAsString = fragmentEntity.getAttributes(); final String mergedLeaves = mergeLeaves(updateLeaves, currentLeavesAsString); fragmentEntity.setAttributes(mergedLeaves); @@ -496,8 +496,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService @Override public void updateDataNodeAndDescendants(final String dataspaceName, final String anchorName, final DataNode dataNode) { - final FragmentEntity fragmentEntity = - getFragmentWithoutDescendantsByXpath(dataspaceName, anchorName, dataNode.getXpath()); + final FragmentEntity fragmentEntity = getFragmentEntity(dataspaceName, anchorName, dataNode.getXpath()); updateFragmentEntityAndDescendantsWithDataNode(fragmentEntity, dataNode); try { fragmentRepository.save(fragmentEntity); @@ -509,21 +508,24 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } @Override - public void updateDataNodesAndDescendants(final String dataspaceName, - final String anchorName, - final List<DataNode> dataNodes) { - - final Map<DataNode, FragmentEntity> dataNodeFragmentEntityMap = dataNodes.stream() - .collect(Collectors.toMap( - dataNode -> dataNode, - dataNode -> - getFragmentWithoutDescendantsByXpath(dataspaceName, anchorName, dataNode.getXpath()))); - dataNodeFragmentEntityMap.forEach( - (dataNode, fragmentEntity) -> updateFragmentEntityAndDescendantsWithDataNode(fragmentEntity, dataNode)); + public void updateDataNodesAndDescendants(final String dataspaceName, final String anchorName, + final List<DataNode> updatedDataNodes) { + final Map<String, DataNode> xpathToUpdatedDataNode = updatedDataNodes.stream() + .collect(Collectors.toMap(DataNode::getXpath, dataNode -> dataNode)); + + final Collection<String> xpaths = xpathToUpdatedDataNode.keySet(); + final Collection<FragmentEntity> existingFragmentEntities = + getFragmentEntities(dataspaceName, anchorName, xpaths); + + for (final FragmentEntity existingFragmentEntity : existingFragmentEntities) { + final DataNode updatedDataNode = xpathToUpdatedDataNode.get(existingFragmentEntity.getXpath()); + updateFragmentEntityAndDescendantsWithDataNode(existingFragmentEntity, updatedDataNode); + } + try { - fragmentRepository.saveAll(dataNodeFragmentEntityMap.values()); + fragmentRepository.saveAll(existingFragmentEntities); } catch (final StaleStateException staleStateException) { - retryUpdateDataNodesIndividually(dataspaceName, anchorName, dataNodeFragmentEntityMap.values()); + retryUpdateDataNodesIndividually(dataspaceName, anchorName, existingFragmentEntities); } } @@ -577,8 +579,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService @Transactional public void replaceListContent(final String dataspaceName, final String anchorName, final String parentNodeXpath, final Collection<DataNode> newListElements) { - final FragmentEntity parentEntity = - getFragmentWithoutDescendantsByXpath(dataspaceName, anchorName, parentNodeXpath); + final FragmentEntity parentEntity = getFragmentEntity(dataspaceName, anchorName, parentNodeXpath); final String listElementXpathPrefix = getListElementXpathPrefix(newListElements); final Map<String, FragmentEntity> existingListElementFragmentEntitiesByXPath = extractListElementFragmentEntitiesByXPath(parentEntity.getChildFragments(), listElementXpathPrefix); @@ -607,22 +608,44 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService @Override @Transactional + public void deleteDataNodes(final String dataspaceName, final Collection<String> anchorNames) { + final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); + final Collection<AnchorEntity> anchorEntities = + anchorRepository.findAllByDataspaceAndNameIn(dataspaceEntity, anchorNames); + fragmentRepository.deleteByAnchorIn(anchorEntities); + } + + @Override + @Transactional public void deleteDataNodes(final String dataspaceName, final String anchorName, final Collection<String> xpathsToDelete) { final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); - final Collection<String> normalizedXpaths = new ArrayList<>(xpathsToDelete.size()); + final Collection<String> deleteChecklist = new HashSet<>(xpathsToDelete.size()); for (final String xpath : xpathsToDelete) { try { - normalizedXpaths.add(CpsPathUtil.getNormalizedXpath(xpath)); + deleteChecklist.add(CpsPathUtil.getNormalizedXpath(xpath)); } catch (final PathParsingException e) { - log.debug("Error parsing xpath \"{}\" in deleteDataNodes: {}", xpath, e.getMessage()); + log.debug("Error parsing xpath \"{}\": {}", xpath, e.getMessage()); } } - fragmentRepository.deleteByAnchorIdAndXpaths(anchorEntity.getId(), normalizedXpaths); - fragmentRepository.deleteListsByAnchorIdAndXpaths(anchorEntity.getId(), normalizedXpaths); + final Collection<String> xpathsToExistingContainers = + fragmentRepository.findAllXpathByAnchorAndXpathIn(anchorEntity, deleteChecklist); + deleteChecklist.removeAll(xpathsToExistingContainers); + + final Collection<String> xpathsToExistingLists = deleteChecklist.stream() + .filter(xpath -> fragmentRepository.existsByAnchorAndXpathStartsWith(anchorEntity, xpath + "[")) + .collect(Collectors.toList()); + deleteChecklist.removeAll(xpathsToExistingLists); + + if (!deleteChecklist.isEmpty()) { + throw new DataNodeNotFoundExceptionBatch(dataspaceName, anchorName, deleteChecklist); + } + + fragmentRepository.deleteByAnchorIdAndXpaths(anchorEntity.getId(), xpathsToExistingContainers); + fragmentRepository.deleteListsByAnchorIdAndXpaths(anchorEntity.getId(), xpathsToExistingLists); } @Override @@ -652,7 +675,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } else { parentNodeXpath = CpsPathUtil.getNormalizedParentXpath(targetXpath); } - parentFragmentEntity = getFragmentWithoutDescendantsByXpath(dataspaceName, anchorName, parentNodeXpath); + parentFragmentEntity = getFragmentEntity(dataspaceName, anchorName, parentNodeXpath); if (CpsPathUtil.isPathToListElement(targetXpath)) { targetDeleted = deleteDataNode(parentFragmentEntity, targetXpath); } else { diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java index 3dbd578c73..46b0fec1c2 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java @@ -47,6 +47,12 @@ public interface AnchorRepository extends JpaRepository<AnchorEntity, Integer> { Collection<AnchorEntity> findAllBySchemaSet(@NotNull SchemaSetEntity schemaSetEntity); + Collection<AnchorEntity> findAllByDataspaceAndNameIn(@NotNull DataspaceEntity dataspaceEntity, + @NotNull Collection<String> anchorNames); + + Collection<AnchorEntity> findAllByDataspaceAndSchemaSetNameIn(@NotNull DataspaceEntity dataspaceEntity, + @NotNull Collection<String> schemaSetNames); + Integer countByDataspace(@NotNull DataspaceEntity dataspaceEntity); @Query(value = "SELECT anchor.* FROM yang_resource\n" @@ -58,4 +64,7 @@ public interface AnchorRepository extends JpaRepository<AnchorEntity, Integer> { + "HAVING COUNT(DISTINCT module_name) = :sizeOfModuleNames", nativeQuery = true) Collection<AnchorEntity> getAnchorsByDataspaceIdAndModuleNames(@Param("dataspaceId") int dataspaceId, @Param("moduleNames") Collection<String> moduleNames, @Param("sizeOfModuleNames") int sizeOfModuleNames); -}
\ No newline at end of file + + void deleteAllByDataspaceAndNameIn(@NotNull DataspaceEntity dataspaceEntity, + @NotNull Collection<String> anchorNames); +} diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepositoryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepositoryImpl.java index 0e4d359da5..5c5458a039 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepositoryImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepositoryImpl.java @@ -21,8 +21,11 @@ package org.onap.cps.spi.repository; import java.util.Collection; +import java.util.Collections; +import java.util.stream.Collectors; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; +import javax.persistence.Query; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @@ -40,55 +43,55 @@ public class FragmentNativeRepositoryImpl implements FragmentNativeRepository { @PersistenceContext private final EntityManager entityManager; - private final TempTableCreator tempTableCreator; - @Override public void deleteFragmentEntity(final long fragmentEntityId) { entityManager.createNativeQuery( - DROP_FRAGMENT_CONSTRAINT - + ADD_FRAGMENT_CONSTRAINT_WITH_CASCADE - + "DELETE FROM fragment WHERE id = ?;" - + DROP_FRAGMENT_CONSTRAINT - + ADD_ORIGINAL_FRAGMENT_CONSTRAINT) + addFragmentConstraintWithDeleteCascade("DELETE FROM fragment WHERE id = ?")) .setParameter(1, fragmentEntityId) .executeUpdate(); } @Override - // Accept security hotspot as temporary table name in SQL query is created internally, not from user input. - @SuppressWarnings("squid:S2077") public void deleteByAnchorIdAndXpaths(final int anchorId, final Collection<String> xpaths) { - if (!xpaths.isEmpty()) { - final String tempTableName = tempTableCreator.createTemporaryTable("xpathsToDelete", xpaths, "xpath"); - entityManager.createNativeQuery( - DROP_FRAGMENT_CONSTRAINT - + ADD_FRAGMENT_CONSTRAINT_WITH_CASCADE - + "DELETE FROM fragment f USING " + tempTableName + " t" - + " WHERE f.anchor_id = :anchorId AND f.xpath = t.xpath;" - + DROP_FRAGMENT_CONSTRAINT - + ADD_ORIGINAL_FRAGMENT_CONSTRAINT) - .setParameter("anchorId", anchorId) - .executeUpdate(); - } + final String queryString = addFragmentConstraintWithDeleteCascade( + "DELETE FROM fragment f WHERE f.anchor_id = ? AND (f.xpath IN (:parameterPlaceholders))"); + executeUpdateWithAnchorIdAndCollection(queryString, anchorId, xpaths); } @Override - // Accept security hotspot as temporary table name in SQL query is created internally, not from user input. + public void deleteListsByAnchorIdAndXpaths(final int anchorId, final Collection<String> listXpaths) { + final Collection<String> listXpathPatterns = + listXpaths.stream().map(listXpath -> listXpath + "[%").collect(Collectors.toSet()); + final String queryString = addFragmentConstraintWithDeleteCascade( + "DELETE FROM fragment f WHERE f.anchor_id = ? AND (f.xpath LIKE ANY (array[:parameterPlaceholders]))"); + executeUpdateWithAnchorIdAndCollection(queryString, anchorId, listXpathPatterns); + } + + // Accept security hotspot as placeholders in SQL query are created internally, not from user input. @SuppressWarnings("squid:S2077") - public void deleteListsByAnchorIdAndXpaths(final int anchorId, final Collection<String> xpaths) { - if (!xpaths.isEmpty()) { - final String tempTableName = tempTableCreator.createTemporaryTable("xpathsToDelete", xpaths, "xpath"); - entityManager.createNativeQuery( - DROP_FRAGMENT_CONSTRAINT - + ADD_FRAGMENT_CONSTRAINT_WITH_CASCADE - + "DELETE FROM fragment f USING " + tempTableName + " t" - + " WHERE f.anchor_id = :anchorId AND f.xpath LIKE CONCAT(t.xpath, :xpathListPattern);" - + DROP_FRAGMENT_CONSTRAINT - + ADD_ORIGINAL_FRAGMENT_CONSTRAINT) - .setParameter("anchorId", anchorId) - .setParameter("xpathListPattern", "[%%") - .executeUpdate(); + private void executeUpdateWithAnchorIdAndCollection(final String sqlTemplate, final int anchorId, + final Collection<String> collection) { + if (!collection.isEmpty()) { + final String parameterPlaceholders = String.join(",", Collections.nCopies(collection.size(), "?")); + final String queryStringWithParameterPlaceholders = + sqlTemplate.replaceFirst(":parameterPlaceholders\\b", parameterPlaceholders); + + final Query query = entityManager.createNativeQuery(queryStringWithParameterPlaceholders); + query.setParameter(1, anchorId); + int parameterIndex = 2; + for (final String parameterValue : collection) { + query.setParameter(parameterIndex++, parameterValue); + } + query.executeUpdate(); } } + private static String addFragmentConstraintWithDeleteCascade(final String queryString) { + return DROP_FRAGMENT_CONSTRAINT + + ADD_FRAGMENT_CONSTRAINT_WITH_CASCADE + + queryString + ";" + + DROP_FRAGMENT_CONSTRAINT + + ADD_ORIGINAL_FRAGMENT_CONSTRAINT; + } + } 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 8bdb7d985b..51ebcb4127 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 @@ -100,4 +100,10 @@ public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, nativeQuery = true)
List<FragmentExtract> quickFindWithDescendants(@Param("anchorId") int anchorId,
@Param("xpathRegex") String xpathRegex);
+
+ @Query("SELECT f.xpath FROM FragmentEntity f WHERE f.anchor = :anchor AND f.xpath IN :xpaths")
+ List<String> findAllXpathByAnchorAndXpathIn(@Param("anchor") AnchorEntity anchorEntity,
+ @Param("xpaths") Collection<String> xpaths);
+
+ boolean existsByAnchorAndXpathStartsWith(AnchorEntity anchorEntity, String xpath);
}
|