summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToine Siebelink <toine.siebelink@est.tech>2024-01-05 16:56:43 +0000
committerGerrit Code Review <gerrit@onap.org>2024-01-05 16:56:43 +0000
commit89871c11e9a32ad588fce392872a4be00badd0fe (patch)
treed39a68d21b09562a17229a0b704a195b1cf3d754
parented11dbc849abc69882051c47ed1e14d6e1abe8b3 (diff)
parent9e871800f7bb6de76a2baf10d0395933fd0bb5ab (diff)
Merge "Normalize JSON attributes during update"
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java35
-rw-r--r--docs/release-notes.rst3
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy10
3 files changed, 33 insertions, 15 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 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<String, FragmentEntity> 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<String, Serializable> currentLeaves) {
+ final Map<String, Serializable> sortedLeaves = new TreeMap<>(String::compareTo);
+ sortedLeaves.putAll(currentLeaves);
+ return jsonObjectMapper.asJsonString(sortedLeaves);
+ }
+
+ private String getOrderedLeavesAsJson(final String currentLeavesAsString) {
+ if (currentLeavesAsString == null) {
+ return "{}";
+ }
+ final Map<String, Serializable> sortedLeaves = jsonObjectMapper.convertJsonString(currentLeavesAsString,
+ TreeMap.class);
+ return jsonObjectMapper.asJsonString(sortedLeaves);
}
private static Map<String, FragmentEntity> 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 <https://jira.onap.org/browse/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