X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cps-ri%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fcps%2Fspi%2Fimpl%2FCpsDataPersistenceServiceImpl.java;h=c3b8adb5dd4dd9770be8a5bbd5ecd9105a49506c;hb=ad9b701a00c237ae8e462de76b500c8612866da6;hp=d0154e116374fd77bb05843bb90f68b310f5cd60;hpb=e626c9661fd88a585b50dafab5f5542784690143;p=cps.git 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 d0154e116..c3b8adb5d 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 @@ -23,7 +23,8 @@ package org.onap.cps.spi.impl; -import com.google.common.base.Strings; +import static org.onap.cps.spi.PaginationOption.NO_PAGINATION; + import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; import io.micrometer.core.annotation.Timed; @@ -36,7 +37,6 @@ 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; @@ -49,13 +49,11 @@ import org.onap.cps.cpspath.parser.CpsPathUtil; import org.onap.cps.cpspath.parser.PathParsingException; import org.onap.cps.spi.CpsDataPersistenceService; import org.onap.cps.spi.FetchDescendantsOption; +import org.onap.cps.spi.PaginationOption; 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.FragmentEntityArranger; -import org.onap.cps.spi.entities.FragmentExtract; import org.onap.cps.spi.exceptions.AlreadyDefinedException; -import org.onap.cps.spi.exceptions.AlreadyDefinedExceptionBatch; import org.onap.cps.spi.exceptions.ConcurrencyException; import org.onap.cps.spi.exceptions.CpsAdminException; import org.onap.cps.spi.exceptions.CpsPathException; @@ -83,8 +81,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService private final SessionManager sessionManager; private static final String REG_EX_FOR_OPTIONAL_LIST_INDEX = "(\\[@.+?])?)"; - private static final String QUERY_ACROSS_ANCHORS = null; - private static final AnchorEntity ALL_ANCHORS = null; @Override public void addChildDataNodes(final String dataspaceName, final String anchorName, @@ -108,12 +104,12 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService for (final Collection newList : newLists) { try { addChildrenDataNodes(anchorEntity, parentNodeXpath, newList); - } catch (final AlreadyDefinedExceptionBatch e) { - failedXpaths.addAll(e.getAlreadyDefinedXpaths()); + } catch (final AlreadyDefinedException alreadyDefinedException) { + failedXpaths.addAll(alreadyDefinedException.getAlreadyDefinedObjectNames()); } } if (!failedXpaths.isEmpty()) { - throw new AlreadyDefinedExceptionBatch(failedXpaths); + throw AlreadyDefinedException.forDataNodes(failedXpaths, anchorEntity.getName()); } } @@ -124,8 +120,9 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService newChildAsFragmentEntity.setParentId(parentFragmentEntity.getId()); try { fragmentRepository.save(newChildAsFragmentEntity); - } catch (final DataIntegrityViolationException e) { - throw AlreadyDefinedException.forDataNode(newChild.getXpath(), anchorEntity.getName(), e); + } catch (final DataIntegrityViolationException dataIntegrityViolationException) { + throw AlreadyDefinedException.forDataNodes(Collections.singletonList(newChild.getXpath()), + anchorEntity.getName()); } } @@ -141,9 +138,9 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService fragmentEntities.add(newChildAsFragmentEntity); } fragmentRepository.saveAll(fragmentEntities); - } catch (final DataIntegrityViolationException e) { + } catch (final DataIntegrityViolationException dataIntegrityViolationException) { log.warn("Exception occurred : {} , While saving : {} children, retrying using individual save operations", - e, fragmentEntities.size()); + dataIntegrityViolationException, fragmentEntities.size()); retrySavingEachChildIndividually(anchorEntity, parentNodeXpath, newChildren); } } @@ -154,12 +151,12 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService for (final DataNode newChild : newChildren) { try { addNewChildDataNode(anchorEntity, parentNodeXpath, newChild); - } catch (final AlreadyDefinedException e) { + } catch (final AlreadyDefinedException alreadyDefinedException) { failedXpaths.add(newChild.getXpath()); } } if (!failedXpaths.isEmpty()) { - throw new AlreadyDefinedExceptionBatch(failedXpaths); + throw AlreadyDefinedException.forDataNodes(failedXpaths, anchorEntity.getName()); } } @@ -187,12 +184,12 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService try { final FragmentEntity fragmentEntity = convertToFragmentWithAllDescendants(anchorEntity, dataNode); fragmentRepository.save(fragmentEntity); - } catch (final DataIntegrityViolationException e) { + } catch (final DataIntegrityViolationException dataIntegrityViolationException) { failedXpaths.add(dataNode.getXpath()); } } if (!failedXpaths.isEmpty()) { - throw new AlreadyDefinedExceptionBatch(failedXpaths); + throw AlreadyDefinedException.forDataNodes(failedXpaths, anchorEntity.getName()); } } @@ -218,7 +215,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService private FragmentEntity toFragmentEntity(final AnchorEntity anchorEntity, final DataNode dataNode) { return FragmentEntity.builder() - .dataspace(anchorEntity.getDataspace()) .anchor(anchorEntity) .xpath(dataNode.getXpath()) .attributes(jsonObjectMapper.asJsonString(dataNode.getLeaves())) @@ -247,42 +243,42 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final Collection xpaths, final FetchDescendantsOption fetchDescendantsOption) { final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName); - final Collection fragmentEntities = - getFragmentEntities(anchorEntity, xpaths, fetchDescendantsOption); - return toDataNodes(fragmentEntities, fetchDescendantsOption); + Collection fragmentEntities = getFragmentEntities(anchorEntity, xpaths); + fragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption, + fragmentEntities); + return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities); } private Collection getFragmentEntities(final AnchorEntity anchorEntity, - final Collection xpaths, - final FetchDescendantsOption fetchDescendantsOption) { - final Collection nonRootXpaths = new HashSet<>(xpaths); - final boolean haveRootXpath = nonRootXpaths.removeIf(CpsDataPersistenceServiceImpl::isRootXpath); + final Collection xpaths) { + final Collection normalizedXpaths = getNormalizedXpaths(xpaths); - final Collection normalizedXpaths = new HashSet<>(nonRootXpaths.size()); - for (final String xpath : nonRootXpaths) { - try { - normalizedXpaths.add(CpsPathUtil.getNormalizedXpath(xpath)); - } catch (final PathParsingException e) { - log.warn("Error parsing xpath \"{}\": {}", xpath, e.getMessage()); + final boolean haveRootXpath = normalizedXpaths.removeIf(CpsDataPersistenceServiceImpl::isRootXpath); + + final List fragmentEntities = fragmentRepository.findByAnchorAndXpathIn(anchorEntity, + normalizedXpaths); + + for (final FragmentEntity fragmentEntity : fragmentEntities) { + normalizedXpaths.remove(fragmentEntity.getXpath()); + } + + for (final String xpath : normalizedXpaths) { + if (!CpsPathUtil.isPathToListElement(xpath)) { + fragmentEntities.addAll(fragmentRepository.findListByAnchorAndXpath(anchorEntity, xpath)); } } + if (haveRootXpath) { - normalizedXpaths.addAll(fragmentRepository.findAllXpathByAnchorAndParentIdIsNull(anchorEntity)); + fragmentEntities.addAll(fragmentRepository.findRootsByAnchorId(anchorEntity.getId())); } - final List fragmentExtracts = - fragmentRepository.findExtractsWithDescendants(anchorEntity.getId(), normalizedXpaths, - fetchDescendantsOption.getDepth()); - - return FragmentEntityArranger.toFragmentEntityTrees(anchorEntity, fragmentExtracts); + return fragmentEntities; } private FragmentEntity getFragmentEntity(final AnchorEntity anchorEntity, final String xpath) { final FragmentEntity fragmentEntity; if (isRootXpath(xpath)) { - final List fragmentExtracts = fragmentRepository.findAllExtractsByAnchor(anchorEntity); - fragmentEntity = FragmentEntityArranger.toFragmentEntityTrees(anchorEntity, fragmentExtracts) - .stream().findFirst().orElse(null); + fragmentEntity = fragmentRepository.findOneByAnchorId(anchorEntity.getId()).orElse(null); } else { fragmentEntity = fragmentRepository.getByAnchorAndXpath(anchorEntity, getNormalizedXpath(xpath)); } @@ -298,63 +294,69 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService public List queryDataNodes(final String dataspaceName, final String anchorName, final String cpsPath, final FetchDescendantsOption fetchDescendantsOption) { final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); - final AnchorEntity anchorEntity = Strings.isNullOrEmpty(anchorName) ? ALL_ANCHORS - : anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); + final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); final CpsPathQuery cpsPathQuery; try { cpsPathQuery = CpsPathUtil.getCpsPathQuery(cpsPath); - } catch (final PathParsingException e) { - throw new CpsPathException(e.getMessage()); + } catch (final PathParsingException pathParsingException) { + throw new CpsPathException(pathParsingException.getMessage()); } Collection fragmentEntities; - if (anchorEntity == ALL_ANCHORS) { - fragmentEntities = fragmentRepository.findByDataspaceAndCpsPath(dataspaceEntity, cpsPathQuery); - } else { - fragmentEntities = fragmentRepository.findByAnchorAndCpsPath(anchorEntity, cpsPathQuery); - } + fragmentEntities = fragmentRepository.findByAnchorAndCpsPath(anchorEntity, cpsPathQuery); if (cpsPathQuery.hasAncestorAxis()) { final Collection ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery); - if (anchorEntity == ALL_ANCHORS) { - fragmentEntities = fragmentRepository.findByDataspaceAndXpathIn(dataspaceEntity, ancestorXpaths); - } else { - fragmentEntities = fragmentRepository.findByAnchorAndXpathIn(anchorEntity, ancestorXpaths); - } + fragmentEntities = fragmentRepository.findByAnchorAndXpathIn(anchorEntity, ancestorXpaths); } - fragmentEntities = prefetchDescendantsForFragmentEntities(fetchDescendantsOption, anchorEntity, - fragmentEntities); + fragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption, + fragmentEntities); return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities); } @Override + @Timed(value = "cps.data.persistence.service.datanode.query.anchors", + description = "Time taken to query data nodes across all anchors or list of anchors") public List queryDataNodesAcrossAnchors(final String dataspaceName, final String cpsPath, - final FetchDescendantsOption fetchDescendantsOption) { - return queryDataNodes(dataspaceName, QUERY_ACROSS_ANCHORS, cpsPath, fetchDescendantsOption); - } - - private Collection prefetchDescendantsForFragmentEntities( - final FetchDescendantsOption fetchDescendantsOption, - final AnchorEntity anchorEntity, - final Collection proxiedFragmentEntities) { - if (FetchDescendantsOption.OMIT_DESCENDANTS.equals(fetchDescendantsOption)) { - return proxiedFragmentEntities; + final FetchDescendantsOption fetchDescendantsOption, + final PaginationOption paginationOption) { + final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); + final CpsPathQuery cpsPathQuery; + try { + cpsPathQuery = CpsPathUtil.getCpsPathQuery(cpsPath); + } catch (final PathParsingException e) { + throw new CpsPathException(e.getMessage()); } - final List fragmentEntityIds = proxiedFragmentEntities.stream() - .map(FragmentEntity::getId).collect(Collectors.toList()); + final List anchorIds; + if (paginationOption == NO_PAGINATION) { + anchorIds = Collections.emptyList(); + } else { + anchorIds = getAnchorIdsForPagination(dataspaceEntity, cpsPathQuery, paginationOption); + if (anchorIds.isEmpty()) { + return Collections.emptyList(); + } + } + Collection fragmentEntities = + fragmentRepository.findByDataspaceAndCpsPath(dataspaceEntity, cpsPathQuery, anchorIds); - final List fragmentExtracts = - fragmentRepository.findExtractsWithDescendantsByIds(fragmentEntityIds, fetchDescendantsOption.getDepth()); + if (cpsPathQuery.hasAncestorAxis()) { + final Collection ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery); + if (anchorIds.isEmpty()) { + fragmentEntities = fragmentRepository.findByDataspaceAndXpathIn(dataspaceEntity, ancestorXpaths); + } else { + fragmentEntities = fragmentRepository.findByAnchorIdsAndXpathIn( + anchorIds.toArray(new Long[0]), ancestorXpaths.toArray(new String[0])); + } - if (anchorEntity == ALL_ANCHORS) { - final Collection anchorIds = fragmentExtracts.stream() - .map(FragmentExtract::getAnchorId).collect(Collectors.toSet()); - final List anchorEntities = anchorRepository.findAllById(anchorIds); - final Map anchorEntityPerId = anchorEntities.stream() - .collect(Collectors.toMap(AnchorEntity::getId, Function.identity())); - return FragmentEntityArranger.toFragmentEntityTreesAcrossAnchors(anchorEntityPerId, fragmentExtracts); } - return FragmentEntityArranger.toFragmentEntityTrees(anchorEntity, fragmentExtracts); + fragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption, + fragmentEntities); + return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities); + } + + private List getAnchorIdsForPagination(final DataspaceEntity dataspaceEntity, final CpsPathQuery cpsPathQuery, + final PaginationOption paginationOption) { + return fragmentRepository.findAnchorIdsForPagination(dataspaceEntity, cpsPathQuery, paginationOption); } private List createDataNodesFromFragmentEntities(final FetchDescendantsOption fetchDescendantsOption, @@ -372,9 +374,21 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } try { return CpsPathUtil.getNormalizedXpath(xpathSource); - } catch (final PathParsingException e) { - throw new CpsPathException(e.getMessage()); + } catch (final PathParsingException pathParsingException) { + throw new CpsPathException(pathParsingException.getMessage()); + } + } + + private static Collection getNormalizedXpaths(final Collection xpaths) { + final Collection normalizedXpaths = new HashSet<>(xpaths.size()); + for (final String xpath : xpaths) { + try { + normalizedXpaths.add(getNormalizedXpath(xpath)); + } catch (final CpsPathException cpsPathException) { + log.warn("Error parsing xpath \"{}\": {}", xpath, cpsPathException.getMessage()); + } } + return normalizedXpaths; } @Override @@ -393,6 +407,19 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService sessionManager.lockAnchor(sessionId, dataspaceName, anchorName, timeoutInMilliseconds); } + @Override + public Integer countAnchorsForDataspaceAndCpsPath(final String dataspaceName, final String cpsPath) { + final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); + final CpsPathQuery cpsPathQuery; + try { + cpsPathQuery = CpsPathUtil.getCpsPathQuery(cpsPath); + } catch (final PathParsingException e) { + throw new CpsPathException(e.getMessage()); + } + final List anchorIdList = getAnchorIdsForPagination(dataspaceEntity, cpsPathQuery, NO_PAGINATION); + return anchorIdList.size(); + } + private static Set processAncestorXpath(final Collection fragmentEntities, final CpsPathQuery cpsPathQuery) { final Set ancestorXpath = new HashSet<>(); @@ -423,15 +450,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService .withChildDataNodes(childDataNodes).build(); } - private Collection toDataNodes(final Collection fragmentEntities, - final FetchDescendantsOption fetchDescendantsOption) { - final Collection dataNodes = new ArrayList<>(fragmentEntities.size()); - for (final FragmentEntity fragmentEntity : fragmentEntities) { - dataNodes.add(toDataNode(fragmentEntity, fetchDescendantsOption)); - } - return dataNodes; - } - private List getChildDataNodes(final FragmentEntity fragmentEntity, final FetchDescendantsOption fetchDescendantsOption) { if (fetchDescendantsOption.hasNext()) { @@ -448,8 +466,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName); final Collection xpathsOfUpdatedLeaves = updatedLeavesPerXPath.keySet(); - final Collection fragmentEntities = getFragmentEntities(anchorEntity, xpathsOfUpdatedLeaves, - FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); + final Collection fragmentEntities = getFragmentEntities(anchorEntity, xpathsOfUpdatedLeaves); for (final FragmentEntity fragmentEntity : fragmentEntities) { final Map updatedLeaves = updatedLeavesPerXPath.get(fragmentEntity.getXpath()); @@ -473,8 +490,9 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService .collect(Collectors.toMap(DataNode::getXpath, dataNode -> dataNode)); final Collection xpaths = xpathToUpdatedDataNode.keySet(); - final Collection existingFragmentEntities = - getFragmentEntities(anchorEntity, xpaths, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); + Collection existingFragmentEntities = getFragmentEntities(anchorEntity, xpaths); + existingFragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities( + FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS, existingFragmentEntities); for (final FragmentEntity existingFragmentEntity : existingFragmentEntities) { final DataNode updatedDataNode = xpathToUpdatedDataNode.get(existingFragmentEntity.getXpath()); @@ -494,7 +512,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService for (final FragmentEntity dataNodeFragment : fragmentEntities) { try { fragmentRepository.save(dataNodeFragment); - } catch (final StaleStateException e) { + } catch (final StaleStateException staleStateException) { failedXpaths.add(dataNodeFragment.getXpath()); } } @@ -586,15 +604,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName); - final Collection deleteChecklist = new HashSet<>(xpathsToDelete.size()); - for (final String xpath : xpathsToDelete) { - try { - deleteChecklist.add(CpsPathUtil.getNormalizedXpath(xpath)); - } catch (final PathParsingException e) { - log.warn("Error parsing xpath \"{}\": {}", xpath, e.getMessage()); - } - } - + final Collection deleteChecklist = getNormalizedXpaths(xpathsToDelete); final Collection xpathsToExistingContainers = fragmentRepository.findAllXpathByAnchorAndXpathIn(anchorEntity, deleteChecklist); if (onlySupportListDeletion) { @@ -693,8 +703,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService private String mergeLeaves(final Map updateLeaves, final String currentLeavesAsString) { Map currentLeavesAsMap = new HashMap<>(); if (currentLeavesAsString != null) { - currentLeavesAsMap = currentLeavesAsString.isEmpty() - ? new HashMap<>() : jsonObjectMapper.convertJsonString(currentLeavesAsString, Map.class); + currentLeavesAsMap = jsonObjectMapper.convertJsonString(currentLeavesAsString, Map.class); currentLeavesAsMap.putAll(updateLeaves); }