From 9e871800f7bb6de76a2baf10d0395933fd0bb5ab Mon Sep 17 00:00:00 2001 From: danielhanrahan Date: Thu, 17 Aug 2023 14:58:30 +0100 Subject: Normalize JSON attributes during update This change fixes a few issues related to JSON encoding of FragmentEntity attributes (data leaves). This significantly improves update performance in cases of partial updates. - Normalize JSON and order leaves by name when comparing data leaves during update operations. - Update performance test timings. Issue-ID: CPS-2018 Signed-off-by: danielhanrahan Change-Id: Ia764a353bf96c05758827845e1358745247ee237 --- .../spi/impl/CpsDataPersistenceServiceImpl.java | 35 ++++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'cps-ri') 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 50e671d24..19547bbcc 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-2023 Nordix Foundation + * Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2020-2022 Bell Canada. * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. @@ -38,6 +38,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -526,7 +527,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService private void updateFragmentEntityAndDescendantsWithDataNode(final FragmentEntity existingFragmentEntity, final DataNode newDataNode) { - existingFragmentEntity.setAttributes(jsonObjectMapper.asJsonString(newDataNode.getLeaves())); + copyAttributesFromNewDataNode(existingFragmentEntity, newDataNode); final Map existingChildrenByXpath = existingFragmentEntity.getChildFragments().stream() .collect(Collectors.toMap(FragmentEntity::getXpath, childFragmentEntity -> childFragmentEntity)); @@ -668,7 +669,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return convertToFragmentWithAllDescendants(parentEntity.getAnchor(), newListElement); } if (newListElement.getChildDataNodes().isEmpty()) { - copyAttributesFromNewListElement(existingListElementEntity, newListElement); + copyAttributesFromNewDataNode(existingListElementEntity, newListElement); existingListElementEntity.getChildFragments().clear(); } else { updateFragmentEntityAndDescendantsWithDataNode(existingListElementEntity, newListElement); @@ -681,12 +682,28 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return !existingListElementsByXpath.containsKey(replacementDataNode.getXpath()); } - private void copyAttributesFromNewListElement(final FragmentEntity existingListElementEntity, - final DataNode newListElement) { - final FragmentEntity replacementFragmentEntity = - FragmentEntity.builder().attributes(jsonObjectMapper.asJsonString( - newListElement.getLeaves())).build(); - existingListElementEntity.setAttributes(replacementFragmentEntity.getAttributes()); + private void copyAttributesFromNewDataNode(final FragmentEntity existingFragmentEntity, + final DataNode newDataNode) { + final String oldOrderedLeavesAsJson = getOrderedLeavesAsJson(existingFragmentEntity.getAttributes()); + final String newOrderedLeavesAsJson = getOrderedLeavesAsJson(newDataNode.getLeaves()); + if (!oldOrderedLeavesAsJson.equals(newOrderedLeavesAsJson)) { + existingFragmentEntity.setAttributes(jsonObjectMapper.asJsonString(newDataNode.getLeaves())); + } + } + + private String getOrderedLeavesAsJson(final Map currentLeaves) { + final Map sortedLeaves = new TreeMap<>(String::compareTo); + sortedLeaves.putAll(currentLeaves); + return jsonObjectMapper.asJsonString(sortedLeaves); + } + + private String getOrderedLeavesAsJson(final String currentLeavesAsString) { + if (currentLeavesAsString == null) { + return "{}"; + } + final Map sortedLeaves = jsonObjectMapper.convertJsonString(currentLeavesAsString, + TreeMap.class); + return jsonObjectMapper.asJsonString(sortedLeaves); } private static Map extractListElementFragmentEntitiesByXPath( -- cgit 1.2.3-korg