From: Toine Siebelink Date: Fri, 5 Jan 2024 16:56:43 +0000 (+0000) Subject: Merge "Normalize JSON attributes during update" X-Git-Tag: 3.4.2~8 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=89871c11e9a32ad588fce392872a4be00badd0fe;hp=ed11dbc849abc69882051c47ed1e14d6e1abe8b3;p=cps.git Merge "Normalize JSON attributes during update" --- 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( diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 7fabfc3bb..b7f4c4fbe 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -1,6 +1,6 @@ .. This work is licensed under a Creative Commons Attribution 4.0 International License. .. http://creativecommons.org/licenses/by/4.0 -.. Copyright (C) 2021-2023 Nordix Foundation +.. Copyright (C) 2021-2024 Nordix Foundation .. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING .. _release_notes: @@ -43,6 +43,7 @@ Bug Fixes Features -------- + - `CPS-2018 `_ Improve performance of CPS update operations. Version: 3.4.1 diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy index 35f65551f..b3030b1c6 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation + * Copyright (C) 2023-2024 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the 'License'); * you may not use this file except in compliance with the License. @@ -80,8 +80,8 @@ class UpdatePerfTest extends CpsPerfTestBase { where: scenario | totalNodes | startId | changeLeaves || timeLimit | memoryLimit 'Replace 0 nodes with 100' | 100 | 1 | false || 7 | 250 - 'Replace 100 using same data' | 100 | 1 | false || 5 | 250 - 'Replace 100 with new leaf values' | 100 | 1 | true || 5 | 250 + 'Replace 100 using same data' | 100 | 1 | false || 3 | 250 + 'Replace 100 with new leaf values' | 100 | 1 | true || 3 | 250 'Replace 100 with 100 new nodes' | 100 | 101 | false || 12 | 300 'Replace 50 existing and 50 new' | 100 | 151 | true || 8 | 250 'Replace 100 nodes with 0' | 0 | 1 | false || 5 | 250 @@ -106,8 +106,8 @@ class UpdatePerfTest extends CpsPerfTestBase { where: scenario | totalNodes | startId | changeLeaves || timeLimit | memoryLimit 'Replace list of 0 with 100' | 100 | 1 | false || 7 | 250 - 'Replace list of 100 using same data' | 100 | 1 | false || 5 | 250 - 'Replace list of 100 with new leaf values' | 100 | 1 | true || 5 | 250 + 'Replace list of 100 using same data' | 100 | 1 | false || 3 | 250 + 'Replace list of 100 with new leaf values' | 100 | 1 | true || 3 | 250 'Replace list with 100 new nodes' | 100 | 101 | false || 12 | 300 'Replace list with 50 existing and 50 new' | 100 | 151 | true || 8 | 250 'Replace list of 100 nodes with 1' | 1 | 1 | false || 5 | 250