diff options
Diffstat (limited to 'cps-ri')
5 files changed, 42 insertions, 55 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 c616c8face..c6e28aba91 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,6 +1,6 @@ /* * ============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. * ================================================================================ @@ -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; @@ -53,43 +50,29 @@ import org.onap.cps.spi.exceptions.AlreadyDefinedException; import org.onap.cps.spi.exceptions.ConcurrencyException; 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 Pattern REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE = Pattern.compile("\\[(\\@([^\\/]{0,9999}))\\]$"); @@ -152,7 +135,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<FragmentEntity> childFragmentsImmutableSetBuilder = ImmutableSet.builder(); @@ -177,13 +160,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(); } @@ -249,14 +232,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final List<DataNode> childDataNodes = getChildDataNodes(fragmentEntity, fetchDescendantsOption); Map<String, Object> 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()) @@ -278,7 +254,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService public void updateDataLeaves(final String dataspaceName, final String anchorName, final String xpath, final Map<String, Object> leaves) { final FragmentEntity fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, xpath); - fragmentEntity.setAttributes(GSON.toJson(leaves)); + fragmentEntity.setAttributes(jsonObjectMapper.asJsonString(leaves)); fragmentRepository.save(fragmentEntity); } @@ -296,10 +272,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<String, FragmentEntity> existingChildrenByXpath = existingFragmentEntity.getChildFragments() .stream().collect(Collectors.toMap(FragmentEntity::getXpath, childFragmentEntity -> childFragmentEntity)); @@ -412,7 +388,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService 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 +409,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()); } diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java index fddedcad27..37202498fb 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2022 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,19 @@ package org.onap.cps.spi.repository; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; +import lombok.RequiredArgsConstructor; import org.onap.cps.cpspath.parser.CpsPathPrefixType; import org.onap.cps.cpspath.parser.CpsPathQuery; import org.onap.cps.spi.entities.FragmentEntity; +import org.onap.cps.utils.JsonObjectMapper; +@RequiredArgsConstructor public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCpsPathQuery { public static final String SIMILAR_TO_ABSOLUTE_PATH_PREFIX = "%/"; @@ -39,8 +40,7 @@ public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCps @PersistenceContext private EntityManager entityManager; - - private static final Gson GSON = new GsonBuilder().create(); + private final JsonObjectMapper jsonObjectMapper; @Override public List<FragmentEntity> findByAnchorAndCpsPath(final int anchorId, final CpsPathQuery cpsPathQuery) { @@ -52,7 +52,8 @@ public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCps queryParameters.put("xpathRegex", xpathRegex); if (cpsPathQuery.hasLeafConditions()) { sqlStringBuilder.append(" AND attributes @> :leafDataAsJson\\:\\:jsonb"); - queryParameters.put("leafDataAsJson", GSON.toJson(cpsPathQuery.getLeavesData())); + queryParameters.put("leafDataAsJson", jsonObjectMapper.asJsonString( + cpsPathQuery.getLeavesData())); } addTextFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters); diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy index 85e1155cff..69e6aa81c4 100755 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation + * Copyright (C) 2021-2022 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2021 Bell Canada. * ================================================================================ @@ -21,9 +21,8 @@ */ package org.onap.cps.spi.impl +import com.fasterxml.jackson.databind.ObjectMapper import com.google.common.collect.ImmutableSet -import com.google.gson.Gson -import com.google.gson.GsonBuilder import org.onap.cps.spi.CpsDataPersistenceService import org.onap.cps.spi.entities.FragmentEntity import org.onap.cps.spi.exceptions.AlreadyDefinedException @@ -32,6 +31,7 @@ import org.onap.cps.spi.exceptions.DataNodeNotFoundException import org.onap.cps.spi.exceptions.DataspaceNotFoundException import org.onap.cps.spi.model.DataNode import org.onap.cps.spi.model.DataNodeBuilder +import org.onap.cps.utils.JsonObjectMapper import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.jdbc.Sql @@ -46,7 +46,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { @Autowired CpsDataPersistenceService objectUnderTest - static final Gson GSON = new GsonBuilder().create() + static final JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) static final String SET_DATA = '/data/fragment.sql' static final long ID_DATA_NODE_WITH_DESCENDANTS = 4001 @@ -549,7 +549,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { } static Map<String, Object> getLeavesMap(FragmentEntity fragmentEntity) { - return GSON.fromJson(fragmentEntity.getAttributes(), Map<String, Object>.class) + return jsonObjectMapper.convertJsonString(fragmentEntity.getAttributes(), Map<String, Object>.class) } def static assertLeavesMaps(actualLeavesMap, expectedLeavesMap) { diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy index 162a56682a..7166008ad3 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy @@ -18,6 +18,7 @@ package org.onap.cps.spi.impl +import com.fasterxml.jackson.databind.ObjectMapper import org.hibernate.StaleStateException import org.onap.cps.spi.FetchDescendantsOption import org.onap.cps.spi.entities.FragmentEntity @@ -27,6 +28,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.utils.JsonObjectMapper import spock.lang.Specification @@ -35,9 +37,10 @@ class CpsDataPersistenceServiceSpec extends Specification { def mockDataspaceRepository = Mock(DataspaceRepository) def mockAnchorRepository = Mock(AnchorRepository) def mockFragmentRepository = Mock(FragmentRepository) + def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) def objectUnderTest = new CpsDataPersistenceServiceImpl( - mockDataspaceRepository, mockAnchorRepository, mockFragmentRepository) + mockDataspaceRepository, mockAnchorRepository, mockFragmentRepository, jsonObjectMapper) def 'Handling of StaleStateException (caused by concurrent updates) during data node tree update.'() { diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsPersistenceSpecBase.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsPersistenceSpecBase.groovy index 8ec5c90e9c..8e13be2ae1 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsPersistenceSpecBase.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsPersistenceSpecBase.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation + * Copyright (C) 2021-2022 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2021 Bell Canada. * ================================================================================ @@ -22,11 +22,14 @@ package org.onap.cps.spi.impl +import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.DatabaseTestContainer 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.repository.YangResourceRepository +import org.onap.cps.utils.JsonObjectMapper +import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.testcontainers.spock.Testcontainers @@ -52,6 +55,9 @@ class CpsPersistenceSpecBase extends Specification { @Autowired FragmentRepository fragmentRepository + @SpringBean + JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) + static final String CLEAR_DATA = '/data/clear-all.sql' static final String DATASPACE_NAME = 'DATASPACE-001' |