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=ed414fc30c002345a749d2aadedf04a77b8f0624;hb=e1537e7c389950dd8ad845e46a9e7b647f427eba;hp=8dc6c2f69cbcb506755b4419fa5f65e7b52c5908;hpb=a79c9f1bdf335843c29a425da53c15b5e353e5a3;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 8dc6c2f69..ed414fc30 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 @@ -1,8 +1,8 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation + * 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. @@ -24,12 +24,8 @@ package org.onap.cps.spi.impl; import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -41,6 +37,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.transaction.Transactional; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.hibernate.StaleStateException; import org.onap.cps.cpspath.parser.CpsPathQuery; @@ -51,47 +48,35 @@ import org.onap.cps.spi.entities.DataspaceEntity; import org.onap.cps.spi.entities.FragmentEntity; import org.onap.cps.spi.exceptions.AlreadyDefinedException; 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.DataValidationException; 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.FragmentRepository; +import org.onap.cps.utils.JsonObjectMapper; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; @Service @Slf4j +@RequiredArgsConstructor public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService { - private DataspaceRepository dataspaceRepository; + private final DataspaceRepository dataspaceRepository; - private AnchorRepository anchorRepository; + private final AnchorRepository anchorRepository; - private FragmentRepository fragmentRepository; + private final FragmentRepository fragmentRepository; - private final ObjectMapper objectMapper; + private final JsonObjectMapper jsonObjectMapper; - /** - * Constructor. - * - * @param dataspaceRepository dataspaceRepository - * @param anchorRepository anchorRepository - * @param fragmentRepository fragmentRepository - */ - public CpsDataPersistenceServiceImpl(final DataspaceRepository dataspaceRepository, - final AnchorRepository anchorRepository, final FragmentRepository fragmentRepository) { - this.dataspaceRepository = dataspaceRepository; - this.anchorRepository = anchorRepository; - this.fragmentRepository = fragmentRepository; - objectMapper = new ObjectMapper(); - } - private static final Gson GSON = new GsonBuilder().create(); private static final String REG_EX_FOR_OPTIONAL_LIST_INDEX = "(\\[@[\\s\\S]+?]){0,1})"; - private static final String REG_EX_FOR_LIST_ELEMENT_KEY_PREDICATE = "\\[(\\@([^/]*?)){0,99}( and)*\\]$"; + 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, @@ -151,7 +136,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService * @param dataNodeToBeConverted dataNode * @return a Fragment built from current DataNode */ - private static FragmentEntity convertToFragmentWithAllDescendants(final DataspaceEntity dataspaceEntity, + private FragmentEntity convertToFragmentWithAllDescendants(final DataspaceEntity dataspaceEntity, final AnchorEntity anchorEntity, final DataNode dataNodeToBeConverted) { final FragmentEntity parentFragment = toFragmentEntity(dataspaceEntity, anchorEntity, dataNodeToBeConverted); final Builder childFragmentsImmutableSetBuilder = ImmutableSet.builder(); @@ -176,13 +161,13 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } } - private static FragmentEntity toFragmentEntity(final DataspaceEntity dataspaceEntity, + private FragmentEntity toFragmentEntity(final DataspaceEntity dataspaceEntity, final AnchorEntity anchorEntity, final DataNode dataNode) { return FragmentEntity.builder() .dataspace(dataspaceEntity) .anchor(anchorEntity) .xpath(dataNode.getXpath()) - .attributes(GSON.toJson(dataNode.getLeaves())) + .attributes(jsonObjectMapper.asJsonString(dataNode.getLeaves())) .build(); } @@ -248,14 +233,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final List childDataNodes = getChildDataNodes(fragmentEntity, fetchDescendantsOption); Map leaves = new HashMap<>(); if (fragmentEntity.getAttributes() != null) { - try { - leaves = objectMapper.readValue(fragmentEntity.getAttributes(), Map.class); - } catch (final JsonProcessingException jsonProcessingException) { - final String message = "Parsing error occurred while processing fragmentEntity attributes."; - log.error(message); - throw new DataValidationException(message, - jsonProcessingException.getMessage(), jsonProcessingException); - } + leaves = jsonObjectMapper.convertJsonString(fragmentEntity.getAttributes(), Map.class); } return new DataNodeBuilder() .withXpath(fragmentEntity.getXpath()) @@ -277,7 +255,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService public void updateDataLeaves(final String dataspaceName, final String anchorName, final String xpath, final Map leaves) { final FragmentEntity fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, xpath); - fragmentEntity.setAttributes(GSON.toJson(leaves)); + fragmentEntity.setAttributes(jsonObjectMapper.asJsonString(leaves)); fragmentRepository.save(fragmentEntity); } @@ -295,10 +273,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } } - private static void replaceDataNodeTree(final FragmentEntity existingFragmentEntity, + private void replaceDataNodeTree(final FragmentEntity existingFragmentEntity, final DataNode newDataNode) { - existingFragmentEntity.setAttributes(GSON.toJson(newDataNode.getLeaves())); + existingFragmentEntity.setAttributes(jsonObjectMapper.asJsonString(newDataNode.getLeaves())); final Map existingChildrenByXpath = existingFragmentEntity.getChildFragments() .stream().collect(Collectors.toMap(FragmentEntity::getXpath, childFragmentEntity -> childFragmentEntity)); @@ -342,6 +320,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 @@ -361,8 +347,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService 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 = Pattern.compile(REG_EX_FOR_LIST_ELEMENT_KEY_PREDICATE) - .matcher(lastXpathElement).find(); + final boolean isListElement = REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE.matcher(lastXpathElement).find(); boolean targetExist; if (isListElement) { targetExist = deleteDataNode(parentFragmentEntity, targetXpath); @@ -408,11 +393,15 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private static String getListElementXpathPrefix(final Collection newListElements) { + if (newListElements.isEmpty()) { + throw new CpsAdminException("Invalid list replacement", + "Cannot replace list elements with empty collection"); + } final String firstChildNodeXpath = newListElements.iterator().next().getXpath(); return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf("[") + 1); } - private static FragmentEntity getFragmentForReplacement(final FragmentEntity parentEntity, + private FragmentEntity getFragmentForReplacement(final FragmentEntity parentEntity, final DataNode newListElement, final FragmentEntity existingListElementEntity) { if (existingListElementEntity == null) { @@ -433,10 +422,11 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return !existingListElementsByXpath.containsKey(replacementDataNode.getXpath()); } - private static void copyAttributesFromNewListElement(final FragmentEntity existingListElementEntity, + private void copyAttributesFromNewListElement(final FragmentEntity existingListElementEntity, final DataNode newListElement) { final FragmentEntity replacementFragmentEntity = - FragmentEntity.builder().attributes(GSON.toJson(newListElement.getLeaves())).build(); + FragmentEntity.builder().attributes(jsonObjectMapper.asJsonString( + newListElement.getLeaves())).build(); existingListElementEntity.setAttributes(replacementFragmentEntity.getAttributes()); }