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=7fed534b76e852d05109eb78717eaa77c6613e79;hb=c6a545daaaeac6136d91852cc4f8609eaf7ebe7f;hp=3a1588a59adfa6bc030c7d1c970a726b580d144c;hpb=c863070591268662eced18e04ba52b96897ce7bd;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 3a1588a59..7fed534b7 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 @@ -51,8 +51,6 @@ import org.onap.cps.spi.FetchDescendantsOption; 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; @@ -64,7 +62,6 @@ import org.onap.cps.spi.model.DataNode; import org.onap.cps.spi.model.DataNodeBuilder; import org.onap.cps.spi.repository.AnchorRepository; import org.onap.cps.spi.repository.DataspaceRepository; -import org.onap.cps.spi.repository.FragmentQueryBuilder; import org.onap.cps.spi.repository.FragmentRepository; import org.onap.cps.spi.utils.SessionManager; import org.onap.cps.utils.JsonObjectMapper; @@ -82,17 +79,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService private final JsonObjectMapper jsonObjectMapper; private final SessionManager sessionManager; - private static final String REG_EX_FOR_OPTIONAL_LIST_INDEX = "(\\[@[\\s\\S]+?])?)"; + 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 addChildDataNode(final String dataspaceName, final String anchorName, final String parentNodeXpath, - final DataNode newChildDataNode) { - final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName); - addNewChildDataNode(anchorEntity, parentNodeXpath, newChildDataNode); - } - @Override public void addChildDataNodes(final String dataspaceName, final String anchorName, final String parentNodeXpath, final Collection dataNodes) { @@ -170,11 +160,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } } - @Override - public void storeDataNode(final String dataspaceName, final String anchorName, final DataNode dataNode) { - storeDataNodes(dataspaceName, anchorName, Collections.singletonList(dataNode)); - } - @Override public void storeDataNodes(final String dataspaceName, final String anchorName, final Collection dataNodes) { @@ -230,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())) @@ -259,14 +243,14 @@ 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 xpaths) { final Collection nonRootXpaths = new HashSet<>(xpaths); final boolean haveRootXpath = nonRootXpaths.removeIf(CpsDataPersistenceServiceImpl::isRootXpath); @@ -282,19 +266,13 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService normalizedXpaths.addAll(fragmentRepository.findAllXpathByAnchorAndParentIdIsNull(anchorEntity)); } - final List fragmentExtracts = - fragmentRepository.findExtractsWithDescendants(anchorEntity.getId(), normalizedXpaths, - fetchDescendantsOption.getDepth()); - - return FragmentEntityArranger.toFragmentEntityTrees(anchorEntity, fragmentExtracts); + return fragmentRepository.findByAnchorAndXpathIn(anchorEntity, normalizedXpaths); } 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)); } @@ -304,20 +282,14 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return fragmentEntity; } - private Collection buildFragmentEntitiesFromFragmentExtracts(final AnchorEntity anchorEntity, - final String normalizedXpath) { - final List fragmentExtracts = - fragmentRepository.findByAnchorAndParentXpath(anchorEntity, normalizedXpath); - return FragmentEntityArranger.toFragmentEntityTrees(anchorEntity, fragmentExtracts); - } - @Override @Timed(value = "cps.data.persistence.service.datanode.query", description = "Time taken to query data nodes") public List 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); @@ -326,74 +298,30 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } Collection fragmentEntities; - if (canUseRegexQuickFind(fetchDescendantsOption, cpsPathQuery)) { - return getDataNodesUsingRegexQuickFind(fetchDescendantsOption, 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 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); + fragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption, + fragmentEntities); + return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities); } @Override public List queryDataNodesAcrossAnchors(final String dataspaceName, final String cpsPath, - final FetchDescendantsOption fetchDescendantsOption) { + final FetchDescendantsOption fetchDescendantsOption) { return queryDataNodes(dataspaceName, QUERY_ACROSS_ANCHORS, cpsPath, fetchDescendantsOption); } - private static boolean canUseRegexQuickFind(final FetchDescendantsOption fetchDescendantsOption, - final CpsPathQuery cpsPathQuery) { - return fetchDescendantsOption.equals(FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) - && !cpsPathQuery.hasAncestorAxis() - && !cpsPathQuery.hasLeafConditions() - && !cpsPathQuery.hasTextFunctionCondition() - && !cpsPathQuery.hasContainsFunctionCondition(); - } - - private List getDataNodesUsingRegexQuickFind(final FetchDescendantsOption fetchDescendantsOption, - final AnchorEntity anchorEntity, - final CpsPathQuery cpsPathQuery) { - final String xpathRegex = FragmentQueryBuilder.getXpathSqlRegexForQuickFindWithDescendants(cpsPathQuery); - final List fragmentExtracts = (anchorEntity == ALL_ANCHORS) - ? fragmentRepository.quickFindWithDescendantsAcrossAnchors(xpathRegex) - : fragmentRepository.quickFindWithDescendants(anchorEntity.getId(), xpathRegex); - final Collection fragmentEntities = - FragmentEntityArranger.toFragmentEntityTrees(anchorEntity, fragmentExtracts); - return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities); - } - - private Collection getAncestorFragmentEntitiesAcrossAnchors(final CpsPathQuery cpsPathQuery, - final Collection fragmentEntities) { - final Collection ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery); - return ancestorXpaths.isEmpty() ? Collections.emptyList() : fragmentRepository.findAllByXpathIn(ancestorXpaths); - } - - private List createDataNodesFromProxiedFragmentEntities( - final FetchDescendantsOption fetchDescendantsOption, - final AnchorEntity anchorEntity, - final Collection proxiedFragmentEntities) { - final List dataNodes = new ArrayList<>(proxiedFragmentEntities.size()); - for (final FragmentEntity proxiedFragmentEntity : proxiedFragmentEntities) { - if (FetchDescendantsOption.OMIT_DESCENDANTS.equals(fetchDescendantsOption)) { - dataNodes.add(toDataNode(proxiedFragmentEntity, fetchDescendantsOption)); - } else { - final String normalizedXpath = getNormalizedXpath(proxiedFragmentEntity.getXpath()); - final AnchorEntity anchorEntityForFragmentExtract = (anchorEntity == ALL_ANCHORS) - ? proxiedFragmentEntity.getAnchor() : anchorEntity; - final Collection unproxiedFragmentEntities = - buildFragmentEntitiesFromFragmentExtracts(anchorEntityForFragmentExtract, normalizedXpath); - for (final FragmentEntity unproxiedFragmentEntity : unproxiedFragmentEntities) { - dataNodes.add(toDataNode(unproxiedFragmentEntity, fetchDescendantsOption)); - } - } - } - return Collections.unmodifiableList(dataNodes); - } - private List createDataNodesFromFragmentEntities(final FetchDescendantsOption fetchDescendantsOption, final Collection fragmentEntities) { final List dataNodes = new ArrayList<>(fragmentEntities.size()); @@ -434,8 +362,8 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final CpsPathQuery cpsPathQuery) { final Set ancestorXpath = new HashSet<>(); final Pattern pattern = - Pattern.compile("([\\s\\S]*/" + Pattern.quote(cpsPathQuery.getAncestorSchemaNodeIdentifier()) - + REG_EX_FOR_OPTIONAL_LIST_INDEX + "/[\\s\\S]*"); + Pattern.compile("(.*/" + Pattern.quote(cpsPathQuery.getAncestorSchemaNodeIdentifier()) + + REG_EX_FOR_OPTIONAL_LIST_INDEX + "/.*"); for (final FragmentEntity fragmentEntity : fragmentEntities) { final Matcher matcher = pattern.matcher(fragmentEntity.getXpath()); if (matcher.matches()) { @@ -460,15 +388,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()) { @@ -480,14 +399,24 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } @Override - public void updateDataLeaves(final String dataspaceName, final String anchorName, final String xpath, - final Map updateLeaves) { + public void batchUpdateDataLeaves(final String dataspaceName, final String anchorName, + final Map> updatedLeavesPerXPath) { final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName); - final FragmentEntity fragmentEntity = getFragmentEntity(anchorEntity, xpath); - final String currentLeavesAsString = fragmentEntity.getAttributes(); - final String mergedLeaves = mergeLeaves(updateLeaves, currentLeavesAsString); - fragmentEntity.setAttributes(mergedLeaves); - fragmentRepository.save(fragmentEntity); + + final Collection xpathsOfUpdatedLeaves = updatedLeavesPerXPath.keySet(); + final Collection fragmentEntities = getFragmentEntities(anchorEntity, xpathsOfUpdatedLeaves); + + for (final FragmentEntity fragmentEntity : fragmentEntities) { + final Map updatedLeaves = updatedLeavesPerXPath.get(fragmentEntity.getXpath()); + final String mergedLeaves = mergeLeaves(updatedLeaves, fragmentEntity.getAttributes()); + fragmentEntity.setAttributes(mergedLeaves); + } + + try { + fragmentRepository.saveAll(fragmentEntities); + } catch (final StaleStateException staleStateException) { + retryUpdateDataNodesIndividually(anchorEntity, fragmentEntities); + } } @Override @@ -499,8 +428,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()); @@ -717,9 +647,12 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private String mergeLeaves(final Map updateLeaves, final String currentLeavesAsString) { - final Map currentLeavesAsMap = currentLeavesAsString.isEmpty() - ? new HashMap<>() : jsonObjectMapper.convertJsonString(currentLeavesAsString, Map.class); - currentLeavesAsMap.putAll(updateLeaves); + Map currentLeavesAsMap = new HashMap<>(); + if (currentLeavesAsString != null) { + currentLeavesAsMap = jsonObjectMapper.convertJsonString(currentLeavesAsString, Map.class); + currentLeavesAsMap.putAll(updateLeaves); + } + if (currentLeavesAsMap.isEmpty()) { return ""; }