diff options
Diffstat (limited to 'cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java')
-rw-r--r-- | cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java | 149 |
1 files changed, 82 insertions, 67 deletions
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 ded234bb48..117cb43b4f 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 @@ -48,6 +48,8 @@ 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.SchemaSetEntity; +import org.onap.cps.spi.entities.YangResourceEntity; import org.onap.cps.spi.exceptions.AlreadyDefinedException; import org.onap.cps.spi.exceptions.ConcurrencyException; import org.onap.cps.spi.exceptions.CpsAdminException; @@ -60,6 +62,8 @@ 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.onap.cps.yang.YangTextSchemaSourceSetBuilder; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; @@ -85,33 +89,33 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService @Override @Transactional public void addChildDataNode(final String dataspaceName, final String anchorName, final String parentNodeXpath, - final DataNode newChildDataNode) { - addChildDataNodes(dataspaceName, anchorName, parentNodeXpath, Collections.singleton(newChildDataNode)); + 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<DataNode> newListElements) { + final Collection<DataNode> newListElements) { addChildDataNodes(dataspaceName, anchorName, parentNodeXpath, newListElements); } private void addChildDataNodes(final String dataspaceName, final String anchorName, final String parentNodeXpath, - final Collection<DataNode> newChildren) { + final Collection<DataNode> newChildren) { final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath); try { for (final DataNode newChildAsDataNode : newChildren) { final FragmentEntity newChildAsFragmentEntity = convertToFragmentWithAllDescendants( - parentFragmentEntity.getDataspace(), - parentFragmentEntity.getAnchor(), - newChildAsDataNode); + parentFragmentEntity.getDataspace(), + parentFragmentEntity.getAnchor(), + newChildAsDataNode); newChildAsFragmentEntity.setParentId(parentFragmentEntity.getId()); fragmentRepository.save(newChildAsFragmentEntity); } } catch (final DataIntegrityViolationException exception) { final List<String> conflictXpaths = newChildren.stream() - .map(DataNode::getXpath) - .collect(Collectors.toList()); + .map(DataNode::getXpath) + .collect(Collectors.toList()); throw AlreadyDefinedException.forDataNodes(conflictXpaths, anchorName, exception); } } @@ -121,7 +125,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); final FragmentEntity fragmentEntity = convertToFragmentWithAllDescendants(dataspaceEntity, anchorEntity, - dataNode); + dataNode); try { fragmentRepository.save(fragmentEntity); } catch (final DataIntegrityViolationException exception) { @@ -139,13 +143,13 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService * @return a Fragment built from current DataNode */ private FragmentEntity convertToFragmentWithAllDescendants(final DataspaceEntity dataspaceEntity, - final AnchorEntity anchorEntity, final DataNode dataNodeToBeConverted) { + final AnchorEntity anchorEntity, final DataNode dataNodeToBeConverted) { final FragmentEntity parentFragment = toFragmentEntity(dataspaceEntity, anchorEntity, dataNodeToBeConverted); final Builder<FragmentEntity> childFragmentsImmutableSetBuilder = ImmutableSet.builder(); for (final DataNode childDataNode : dataNodeToBeConverted.getChildDataNodes()) { final FragmentEntity childFragment = - convertToFragmentWithAllDescendants(parentFragment.getDataspace(), parentFragment.getAnchor(), - childDataNode); + convertToFragmentWithAllDescendants(parentFragment.getDataspace(), parentFragment.getAnchor(), + childDataNode); childFragmentsImmutableSetBuilder.add(childFragment); } parentFragment.setChildFragments(childFragmentsImmutableSetBuilder.build()); @@ -153,24 +157,24 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private FragmentEntity toFragmentEntity(final DataspaceEntity dataspaceEntity, - final AnchorEntity anchorEntity, final DataNode dataNode) { + final AnchorEntity anchorEntity, final DataNode dataNode) { return FragmentEntity.builder() - .dataspace(dataspaceEntity) - .anchor(anchorEntity) - .xpath(dataNode.getXpath()) - .attributes(jsonObjectMapper.asJsonString(dataNode.getLeaves())) - .build(); + .dataspace(dataspaceEntity) + .anchor(anchorEntity) + .xpath(dataNode.getXpath()) + .attributes(jsonObjectMapper.asJsonString(dataNode.getLeaves())) + .build(); } @Override public DataNode getDataNode(final String dataspaceName, final String anchorName, final String xpath, - final FetchDescendantsOption fetchDescendantsOption) { + final FetchDescendantsOption fetchDescendantsOption) { final FragmentEntity fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, xpath); return toDataNode(fragmentEntity, fetchDescendantsOption); } private FragmentEntity getFragmentByXpath(final String dataspaceName, final String anchorName, - final String xpath) { + final String xpath) { final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); if (isRootXpath(xpath)) { @@ -189,7 +193,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService @Override public List<DataNode> queryDataNodes(final String dataspaceName, final String anchorName, final String cpsPath, - final FetchDescendantsOption fetchDescendantsOption) { + final FetchDescendantsOption fetchDescendantsOption) { final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); final CpsPathQuery cpsPathQuery; @@ -199,15 +203,15 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService throw new CpsPathException(e.getMessage()); } List<FragmentEntity> fragmentEntities = - fragmentRepository.findByAnchorAndCpsPath(anchorEntity.getId(), cpsPathQuery); + fragmentRepository.findByAnchorAndCpsPath(anchorEntity.getId(), cpsPathQuery); if (cpsPathQuery.hasAncestorAxis()) { final Set<String> ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery); - fragmentEntities = ancestorXpaths.isEmpty() - ? Collections.emptyList() : fragmentRepository.findAllByAnchorAndXpathIn(anchorEntity, ancestorXpaths); + fragmentEntities = ancestorXpaths.isEmpty() ? Collections.emptyList() + : fragmentRepository.findAllByAnchorAndXpathIn(anchorEntity, ancestorXpaths); } return fragmentEntities.stream() - .map(fragmentEntity -> toDataNode(fragmentEntity, fetchDescendantsOption)) - .collect(Collectors.toUnmodifiableList()); + .map(fragmentEntity -> toDataNode(fragmentEntity, fetchDescendantsOption)) + .collect(Collectors.toUnmodifiableList()); } @Override @@ -222,16 +226,16 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService @Override public void lockAnchor(final String sessionId, final String dataspaceName, - final String anchorName, final Long timeoutInMilliseconds) { + final String anchorName, final Long timeoutInMilliseconds) { sessionManager.lockAnchor(sessionId, dataspaceName, anchorName, timeoutInMilliseconds); } private static Set<String> processAncestorXpath(final List<FragmentEntity> fragmentEntities, - final CpsPathQuery cpsPathQuery) { + final CpsPathQuery cpsPathQuery) { final Set<String> ancestorXpath = new HashSet<>(); final Pattern pattern = - Pattern.compile("([\\s\\S]*\\/" + Pattern.quote(cpsPathQuery.getAncestorSchemaNodeIdentifier()) - + REG_EX_FOR_OPTIONAL_LIST_INDEX + "\\/[\\s\\S]*"); + Pattern.compile("([\\s\\S]*\\/" + Pattern.quote(cpsPathQuery.getAncestorSchemaNodeIdentifier()) + + REG_EX_FOR_OPTIONAL_LIST_INDEX + "\\/[\\s\\S]*"); for (final FragmentEntity fragmentEntity : fragmentEntities) { final Matcher matcher = pattern.matcher(fragmentEntity.getXpath()); if (matcher.matches()) { @@ -242,31 +246,42 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private DataNode toDataNode(final FragmentEntity fragmentEntity, - final FetchDescendantsOption fetchDescendantsOption) { + final FetchDescendantsOption fetchDescendantsOption) { final List<DataNode> childDataNodes = getChildDataNodes(fragmentEntity, fetchDescendantsOption); Map<String, Object> leaves = new HashMap<>(); if (fragmentEntity.getAttributes() != null) { leaves = jsonObjectMapper.convertJsonString(fragmentEntity.getAttributes(), Map.class); } return new DataNodeBuilder() - .withXpath(fragmentEntity.getXpath()) - .withLeaves(leaves) - .withChildDataNodes(childDataNodes).build(); + .withModuleNamePrefix(getFirstModuleName(fragmentEntity)) + .withXpath(fragmentEntity.getXpath()) + .withLeaves(leaves) + .withChildDataNodes(childDataNodes).build(); + } + + private String getFirstModuleName(final FragmentEntity fragmentEntity) { + final SchemaSetEntity schemaSetEntity = fragmentEntity.getAnchor().getSchemaSet(); + final Map<String, String> yangResourceNameToContent = + schemaSetEntity.getYangResources().stream().collect( + Collectors.toMap(YangResourceEntity::getName, YangResourceEntity::getContent)); + final SchemaContext schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent) + .getSchemaContext(); + return schemaContext.getModules().iterator().next().getName(); } private List<DataNode> getChildDataNodes(final FragmentEntity fragmentEntity, - final FetchDescendantsOption fetchDescendantsOption) { + final FetchDescendantsOption fetchDescendantsOption) { if (fetchDescendantsOption == INCLUDE_ALL_DESCENDANTS) { return fragmentEntity.getChildFragments().stream() - .map(childFragmentEntity -> toDataNode(childFragmentEntity, fetchDescendantsOption)) - .collect(Collectors.toUnmodifiableList()); + .map(childFragmentEntity -> toDataNode(childFragmentEntity, fetchDescendantsOption)) + .collect(Collectors.toUnmodifiableList()); } return Collections.emptyList(); } @Override public void updateDataLeaves(final String dataspaceName, final String anchorName, final String xpath, - final Map<String, Object> leaves) { + final Map<String, Object> leaves) { final FragmentEntity fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, xpath); fragmentEntity.setAttributes(jsonObjectMapper.asJsonString(leaves)); fragmentRepository.save(fragmentEntity); @@ -280,19 +295,19 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService fragmentRepository.save(fragmentEntity); } catch (final StaleStateException staleStateException) { throw new ConcurrencyException("Concurrent Transactions", - String.format("dataspace :'%s', Anchor : '%s' and xpath: '%s' is updated by another transaction.", - dataspaceName, anchorName, dataNode.getXpath()), - staleStateException); + String.format("dataspace :'%s', Anchor : '%s' and xpath: '%s' is updated by another transaction.", + dataspaceName, anchorName, dataNode.getXpath()), + staleStateException); } } private void replaceDataNodeTree(final FragmentEntity existingFragmentEntity, - final DataNode newDataNode) { + final DataNode newDataNode) { existingFragmentEntity.setAttributes(jsonObjectMapper.asJsonString(newDataNode.getLeaves())); - final Map<String, FragmentEntity> existingChildrenByXpath = existingFragmentEntity.getChildFragments() - .stream().collect(Collectors.toMap(FragmentEntity::getXpath, childFragmentEntity -> childFragmentEntity)); + final Map<String, FragmentEntity> existingChildrenByXpath = existingFragmentEntity.getChildFragments().stream() + .collect(Collectors.toMap(FragmentEntity::getXpath, childFragmentEntity -> childFragmentEntity)); final Collection<FragmentEntity> updatedChildFragments = new HashSet<>(); @@ -300,7 +315,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final FragmentEntity childFragment; if (isNewDataNode(newDataNodeChild, existingChildrenByXpath)) { childFragment = convertToFragmentWithAllDescendants( - existingFragmentEntity.getDataspace(), existingFragmentEntity.getAnchor(), newDataNodeChild); + existingFragmentEntity.getDataspace(), existingFragmentEntity.getAnchor(), newDataNodeChild); } else { childFragment = existingChildrenByXpath.get(newDataNodeChild.getXpath()); replaceDataNodeTree(childFragment, newDataNodeChild); @@ -318,14 +333,14 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final FragmentEntity parentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath); final String listElementXpathPrefix = getListElementXpathPrefix(newListElements); final Map<String, FragmentEntity> existingListElementFragmentEntitiesByXPath = - extractListElementFragmentEntitiesByXPath(parentEntity.getChildFragments(), listElementXpathPrefix); + extractListElementFragmentEntitiesByXPath(parentEntity.getChildFragments(), listElementXpathPrefix); deleteListElements(parentEntity.getChildFragments(), existingListElementFragmentEntitiesByXPath); final Set<FragmentEntity> updatedChildFragmentEntities = new HashSet<>(); for (final DataNode newListElement : newListElements) { final FragmentEntity existingListElementEntity = - existingListElementFragmentEntitiesByXPath.get(newListElement.getXpath()); + existingListElementFragmentEntitiesByXPath.get(newListElement.getXpath()); final FragmentEntity entityToBeAdded = getFragmentForReplacement(parentEntity, newListElement, - existingListElementEntity); + existingListElementEntity); updatedChildFragmentEntities.add(entityToBeAdded); } @@ -338,8 +353,8 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService 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))); + .ifPresent( + anchorEntity -> fragmentRepository.deleteByAnchorIn(Set.of(anchorEntity))); } @Override @@ -356,7 +371,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private void deleteDataNode(final String dataspaceName, final String anchorName, final String targetXpath, - final boolean onlySupportListNodeDeletion) { + final boolean onlySupportListNodeDeletion) { final String parentNodeXpath; FragmentEntity parentFragmentEntity = null; boolean targetDeleted = false; @@ -372,7 +387,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService 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(); + .matcher(lastXpathElement).find(); if (isListElement) { targetDeleted = deleteDataNode(parentFragmentEntity, targetXpath); } else { @@ -385,9 +400,9 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } if (!targetDeleted) { final String additionalInformation = onlySupportListNodeDeletion - ? "The target is probably not a List." : ""; + ? "The target is probably not a List." : ""; throw new DataNodeNotFoundException(parentFragmentEntity.getDataspace().getName(), - parentFragmentEntity.getAnchor().getName(), targetXpath, additionalInformation); + parentFragmentEntity.getAnchor().getName(), targetXpath, additionalInformation); } } @@ -398,7 +413,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return true; } if (parentFragmentEntity.getChildFragments() - .removeIf(fragment -> fragment.getXpath().equals(normalizedTargetXpath))) { + .removeIf(fragment -> fragment.getXpath().equals(normalizedTargetXpath))) { fragmentRepository.save(parentFragmentEntity); return true; } @@ -409,7 +424,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final String normalizedListXpath = CpsPathUtil.getNormalizedXpath(listXpath); final String deleteTargetXpathPrefix = normalizedListXpath + "["; if (parentFragmentEntity.getChildFragments() - .removeIf(fragment -> fragment.getXpath().startsWith(deleteTargetXpathPrefix))) { + .removeIf(fragment -> fragment.getXpath().startsWith(deleteTargetXpathPrefix))) { fragmentRepository.save(parentFragmentEntity); return true; } @@ -417,26 +432,26 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private static void deleteListElements( - final Collection<FragmentEntity> fragmentEntities, - final Map<String, FragmentEntity> existingListElementFragmentEntitiesByXPath) { + final Collection<FragmentEntity> fragmentEntities, + final Map<String, FragmentEntity> existingListElementFragmentEntitiesByXPath) { fragmentEntities.removeAll(existingListElementFragmentEntitiesByXPath.values()); } private static String getListElementXpathPrefix(final Collection<DataNode> newListElements) { if (newListElements.isEmpty()) { throw new CpsAdminException("Invalid list replacement", - "Cannot replace list elements with empty collection"); + "Cannot replace list elements with empty collection"); } final String firstChildNodeXpath = newListElements.iterator().next().getXpath(); return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf('[') + 1); } private FragmentEntity getFragmentForReplacement(final FragmentEntity parentEntity, - final DataNode newListElement, - final FragmentEntity existingListElementEntity) { + final DataNode newListElement, + final FragmentEntity existingListElementEntity) { if (existingListElementEntity == null) { return convertToFragmentWithAllDescendants( - parentEntity.getDataspace(), parentEntity.getAnchor(), newListElement); + parentEntity.getDataspace(), parentEntity.getAnchor(), newListElement); } if (newListElement.getChildDataNodes().isEmpty()) { copyAttributesFromNewListElement(existingListElementEntity, newListElement); @@ -457,7 +472,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private void copyAttributesFromNewListElement(final FragmentEntity existingListElementEntity, - final DataNode newListElement) { + final DataNode newListElement) { final FragmentEntity replacementFragmentEntity = FragmentEntity.builder().attributes(jsonObjectMapper.asJsonString( newListElement.getLeaves())).build(); @@ -465,10 +480,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private static Map<String, FragmentEntity> extractListElementFragmentEntitiesByXPath( - final Set<FragmentEntity> childEntities, final String listElementXpathPrefix) { + final Set<FragmentEntity> childEntities, final String listElementXpathPrefix) { return childEntities.stream() - .filter(fragmentEntity -> fragmentEntity.getXpath().startsWith(listElementXpathPrefix)) - .collect(Collectors.toMap(FragmentEntity::getXpath, fragmentEntity -> fragmentEntity)); + .filter(fragmentEntity -> fragmentEntity.getXpath().startsWith(listElementXpathPrefix)) + .collect(Collectors.toMap(FragmentEntity::getXpath, fragmentEntity -> fragmentEntity)); } private static boolean isRootXpath(final String xpath) { |