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=bb3c2d07d430b4b356f8a944b9069a35336692f1;hb=c9275522f95f6cd94f28286f5e86f86dd451a19b;hp=2d67d7c953accb0aa2ea0cdf768b916b0f328fb8;hpb=d924ab57a11af19f92037d150e5e5e8ea52f04a8;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 2d67d7c95..bb3c2d07d 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 @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2021-2022 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2020-2021 Bell Canada. + * Modifications Copyright (C) 2020-2022 Bell Canada. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,6 +56,7 @@ 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.FragmentRepository; +import org.onap.cps.spi.utils.SessionManager; import org.onap.cps.utils.JsonObjectMapper; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; @@ -73,41 +74,40 @@ 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]+?]){0,1})"; private static final Pattern REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE = Pattern.compile("\\[(\\@([^\\/]{0,9999}))\\]$"); @Override - public void addChildDataNode(final String dataspaceName, final String anchorName, final String parentXpath, - final DataNode dataNode) { - final FragmentEntity parentFragment = getFragmentByXpath(dataspaceName, anchorName, parentXpath); - final FragmentEntity fragmentEntity = - toFragmentEntity(parentFragment.getDataspace(), parentFragment.getAnchor(), dataNode); - parentFragment.getChildFragments().add(fragmentEntity); - try { - fragmentRepository.save(parentFragment); - } catch (final DataIntegrityViolationException exception) { - throw AlreadyDefinedException.forDataNode(dataNode.getXpath(), anchorName, exception); - } + @Transactional + public void addChildDataNode(final String dataspaceName, final String anchorName, final String parentNodeXpath, + final DataNode newChildDataNode) { + addChildDataNodes(dataspaceName, anchorName, parentNodeXpath, Collections.singleton(newChildDataNode)); } @Override + @Transactional public void addListElements(final String dataspaceName, final String anchorName, final String parentNodeXpath, - final Collection dataNodes) { - final FragmentEntity parentFragment = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath); - final List newFragmentEntities = - dataNodes.stream().map( - dataNode -> toFragmentEntity(parentFragment.getDataspace(), parentFragment.getAnchor(), dataNode) - ).collect(Collectors.toUnmodifiableList()); - parentFragment.getChildFragments().addAll(newFragmentEntities); + final Collection newListElements) { + addChildDataNodes(dataspaceName, anchorName, parentNodeXpath, newListElements); + } + + private void addChildDataNodes(final String dataspaceName, final String anchorName, final String parentNodeXpath, + final Collection newChildren) { + final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath); try { - fragmentRepository.save(parentFragment); - dataNodes.forEach( - dataNode -> getChildFragments(dataspaceName, anchorName, dataNode) - ); + for (final DataNode newChildAsDataNode : newChildren) { + final FragmentEntity newChildAsFragmentEntity = convertToFragmentWithAllDescendants( + parentFragmentEntity.getDataspace(), + parentFragmentEntity.getAnchor(), + newChildAsDataNode); + newChildAsFragmentEntity.setParentId(parentFragmentEntity.getId()); + fragmentRepository.save(newChildAsFragmentEntity); + } } catch (final DataIntegrityViolationException exception) { - final List conflictXpaths = dataNodes.stream() + final List conflictXpaths = newChildren.stream() .map(DataNode::getXpath) .collect(Collectors.toList()); throw AlreadyDefinedException.forDataNodes(conflictXpaths, anchorName, exception); @@ -150,17 +150,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return parentFragment; } - private void getChildFragments(final String dataspaceName, final String anchorName, final DataNode dataNode) { - for (final DataNode childDataNode: dataNode.getChildDataNodes()) { - final FragmentEntity getChildsParentFragmentByXPath = - getFragmentByXpath(dataspaceName, anchorName, dataNode.getXpath()); - final FragmentEntity childFragmentEntity = toFragmentEntity(getChildsParentFragmentByXPath.getDataspace(), - getChildsParentFragmentByXPath.getAnchor(), childDataNode); - getChildsParentFragmentByXPath.getChildFragments().add(childFragmentEntity); - fragmentRepository.save(getChildsParentFragmentByXPath); - } - } - private FragmentEntity toFragmentEntity(final DataspaceEntity dataspaceEntity, final AnchorEntity anchorEntity, final DataNode dataNode) { return FragmentEntity.builder() @@ -213,6 +202,16 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService .collect(Collectors.toUnmodifiableList()); } + @Override + public String startSession() { + return sessionManager.startSession(); + } + + @Override + public void closeSession(final String sessionId) { + sessionManager.closeSession(sessionId); + } + private static Set processAncestorXpath(final List fragmentEntities, final CpsPathQuery cpsPathQuery) { final Set ancestorXpath = new HashSet<>(); @@ -320,6 +319,14 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService fragmentRepository.save(parentEntity); } + @Override + @Transactional + public void deleteDataNodes(final String dataspaceName, final String anchorName) { + final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); + anchorRepository.findByDataspaceAndName(dataspaceEntity, anchorName) + .ifPresent( + anchorEntity -> fragmentRepository.deleteByAnchorIn(Set.of(anchorEntity))); + } @Override @Transactional @@ -335,22 +342,34 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private void deleteDataNode(final String dataspaceName, final String anchorName, final String targetXpath, - final boolean onlySupportListNodeDeletion) { - final String parentNodeXpath = targetXpath.substring(0, targetXpath.lastIndexOf('/')); - final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath); - final String lastXpathElement = targetXpath.substring(targetXpath.lastIndexOf('/')); - final boolean isListElement = REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE.matcher(lastXpathElement).find(); - boolean targetExist; - if (isListElement) { - targetExist = deleteDataNode(parentFragmentEntity, targetXpath); + final boolean onlySupportListNodeDeletion) { + final String parentNodeXpath; + FragmentEntity parentFragmentEntity = null; + boolean targetDeleted = false; + if (isRootXpath(targetXpath)) { + deleteDataNodes(dataspaceName, anchorName); + targetDeleted = true; } else { - targetExist = deleteAllListElements(parentFragmentEntity, targetXpath); - final boolean tryToDeleteDataNode = !targetExist && !onlySupportListNodeDeletion; - if (tryToDeleteDataNode) { - targetExist = deleteDataNode(parentFragmentEntity, targetXpath); + if (isRootContainerNodeXpath(targetXpath)) { + parentNodeXpath = targetXpath; + } else { + parentNodeXpath = targetXpath.substring(0, targetXpath.lastIndexOf('/')); + } + parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath); + final String lastXpathElement = targetXpath.substring(targetXpath.lastIndexOf('/')); + final boolean isListElement = REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE + .matcher(lastXpathElement).find(); + if (isListElement) { + targetDeleted = deleteDataNode(parentFragmentEntity, targetXpath); + } else { + targetDeleted = deleteAllListElements(parentFragmentEntity, targetXpath); + final boolean tryToDeleteDataNode = !targetDeleted && !onlySupportListNodeDeletion; + if (tryToDeleteDataNode) { + targetDeleted = deleteDataNode(parentFragmentEntity, targetXpath); + } } } - if (!targetExist) { + if (!targetDeleted) { final String additionalInformation = onlySupportListNodeDeletion ? "The target is probably not a List." : ""; throw new DataNodeNotFoundException(parentFragmentEntity.getDataspace().getName(), @@ -359,6 +378,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private boolean deleteDataNode(final FragmentEntity parentFragmentEntity, final String targetXpath) { + if (parentFragmentEntity.getXpath().equals(targetXpath)) { + fragmentRepository.delete(parentFragmentEntity); + return true; + } if (parentFragmentEntity.getChildFragments() .removeIf(fragment -> fragment.getXpath().equals(targetXpath))) { fragmentRepository.save(parentFragmentEntity); @@ -367,7 +390,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return false; } - private boolean deleteAllListElements(final FragmentEntity parentFragmentEntity, final String listXpath) { final String deleteTargetXpathPrefix = listXpath + "["; if (parentFragmentEntity.getChildFragments() @@ -390,7 +412,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService "Cannot replace list elements with empty collection"); } final String firstChildNodeXpath = newListElements.iterator().next().getXpath(); - return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf("[") + 1); + return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf('[') + 1); } private FragmentEntity getFragmentForReplacement(final FragmentEntity parentEntity, @@ -414,6 +436,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return !existingListElementsByXpath.containsKey(replacementDataNode.getXpath()); } + private static boolean isRootContainerNodeXpath(final String xpath) { + return 0 == xpath.lastIndexOf('/'); + } + private void copyAttributesFromNewListElement(final FragmentEntity existingListElementEntity, final DataNode newListElement) { final FragmentEntity replacementFragmentEntity =