Part 2: Refactor CPS Delta code to utility class 90/141290/12
authorArpit Singh <AS00745003@techmahindra.com>
Fri, 27 Jun 2025 13:05:27 +0000 (18:35 +0530)
committerArpit Singh <AS00745003@techmahindra.com>
Thu, 17 Jul 2025 05:22:41 +0000 (10:52 +0530)
- Refactoring code for original delta report format to a utility class

Issue-ID:CPS-2838
Change-Id: I071c6e191c0ed5b718bd6a0e19117b2c76db44d2
Signed-off-by: Arpit Singh <AS00745003@techmahindra.com>
cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java
cps-service/src/main/java/org/onap/cps/utils/deltareport/DeltaReportGenerator.java [new file with mode: 0644]
cps-service/src/test/groovy/org/onap/cps/impl/CpsDeltaServiceImplSpec.groovy

index 1a5cdab..8ca49a3 100644 (file)
@@ -27,7 +27,6 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -45,6 +44,7 @@ import org.onap.cps.cpspath.parser.CpsPathUtil;
 import org.onap.cps.utils.DataMapUtils;
 import org.onap.cps.utils.DataMapper;
 import org.onap.cps.utils.JsonObjectMapper;
+import org.onap.cps.utils.deltareport.DeltaReportGenerator;
 import org.onap.cps.utils.deltareport.DeltaReportHelper;
 import org.springframework.stereotype.Service;
 
@@ -59,6 +59,7 @@ public class CpsDeltaServiceImpl implements CpsDeltaService {
     private final DataMapper dataMapper;
     private final JsonObjectMapper jsonObjectMapper;
     private final DeltaReportHelper deltaReportHelper;
+    private final DeltaReportGenerator deltaReportGenerator;
 
     @Override
     @Timed(value = "cps.delta.service.get.delta",
@@ -106,70 +107,11 @@ public class CpsDeltaServiceImpl implements CpsDeltaService {
         if (groupDataNodes) {
             deltaReport.addAll(getCondensedDeltaReports(sourceDataNodes, targetDataNodes));
         } else {
-            final Map<String, DataNode> xpathToSourceDataNodes = convertToXPathToDataNodesMap(sourceDataNodes);
-            final Map<String, DataNode> xpathToTargetDataNodes = convertToXPathToDataNodesMap(targetDataNodes);
-            deltaReport.addAll(getRemovedAndUpdatedDeltaReports(xpathToSourceDataNodes, xpathToTargetDataNodes));
-            deltaReport.addAll(getAddedDeltaReports(xpathToSourceDataNodes, xpathToTargetDataNodes));
+            deltaReport.addAll(deltaReportGenerator.createDeltaReports(sourceDataNodes, targetDataNodes));
         }
         return Collections.unmodifiableList(deltaReport);
     }
 
-    private static Map<String, DataNode> convertToXPathToDataNodesMap(final Collection<DataNode> dataNodes) {
-        final Map<String, DataNode> xpathToDataNode = new LinkedHashMap<>();
-        for (final DataNode dataNode : dataNodes) {
-            xpathToDataNode.put(dataNode.getXpath(), dataNode);
-            final Collection<DataNode> childDataNodes = dataNode.getChildDataNodes();
-            if (!childDataNodes.isEmpty()) {
-                xpathToDataNode.putAll(convertToXPathToDataNodesMap(childDataNodes));
-            }
-        }
-        return xpathToDataNode;
-    }
-
-    private List<DeltaReport> getRemovedAndUpdatedDeltaReports(
-                                                                final Map<String, DataNode> xpathToSourceDataNodes,
-                                                                final Map<String, DataNode> xpathToTargetDataNodes) {
-        final List<DeltaReport> removedAndUpdatedDeltaReportEntries = new ArrayList<>();
-        for (final Map.Entry<String, DataNode> entry: xpathToSourceDataNodes.entrySet()) {
-            final String xpath = entry.getKey();
-            final DataNode sourceDataNode = entry.getValue();
-            final DataNode targetDataNode = xpathToTargetDataNodes.get(xpath);
-            final List<DeltaReport> deltaReports;
-            if (targetDataNode == null) {
-                deltaReports = getDeltaReportsForRemove(xpath, sourceDataNode);
-            } else {
-                deltaReports = deltaReportHelper.createDeltaReportsForUpdates(xpath, sourceDataNode, targetDataNode);
-            }
-            removedAndUpdatedDeltaReportEntries.addAll(deltaReports);
-        }
-        return removedAndUpdatedDeltaReportEntries;
-    }
-
-    private static List<DeltaReport> getDeltaReportsForRemove(final String xpath, final DataNode sourceDataNode) {
-        final List<DeltaReport> deltaReportEntriesForRemove = new ArrayList<>();
-        final Map<String, Serializable> sourceDataNodeLeaves = sourceDataNode.getLeaves();
-        final DeltaReport removedDeltaReportEntry = new DeltaReportBuilder().actionRemove().withXpath(xpath)
-                .withSourceData(sourceDataNodeLeaves).build();
-        deltaReportEntriesForRemove.add(removedDeltaReportEntry);
-        return deltaReportEntriesForRemove;
-    }
-
-    private static List<DeltaReport> getAddedDeltaReports(final Map<String, DataNode> xpathToSourceDataNodes,
-                                                          final Map<String, DataNode> xpathToTargetDataNodes) {
-
-        final List<DeltaReport> addedDeltaReportEntries = new ArrayList<>();
-        final Map<String, DataNode> xpathToAddedNodes = new LinkedHashMap<>(xpathToTargetDataNodes);
-        xpathToAddedNodes.keySet().removeAll(xpathToSourceDataNodes.keySet());
-        for (final Map.Entry<String, DataNode> entry: xpathToAddedNodes.entrySet()) {
-            final String xpath = entry.getKey();
-            final DataNode dataNode = entry.getValue();
-            final DeltaReport addedDataForDeltaReport = new DeltaReportBuilder().actionCreate().withXpath(xpath)
-                                .withTargetData(dataNode.getLeaves()).build();
-            addedDeltaReportEntries.add(addedDataForDeltaReport);
-        }
-        return addedDeltaReportEntries;
-    }
-
     private Collection<DataNode> rebuildSourceDataNodes(final String xpath,
                                                         final Anchor sourceAnchor,
                                                         final Collection<DataNode> sourceDataNodes) {
diff --git a/cps-service/src/main/java/org/onap/cps/utils/deltareport/DeltaReportGenerator.java b/cps-service/src/main/java/org/onap/cps/utils/deltareport/DeltaReportGenerator.java
new file mode 100644 (file)
index 0000000..44b7ba6
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2025 TechMahindra Ltd.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.utils.deltareport;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.api.model.DataNode;
+import org.onap.cps.api.model.DeltaReport;
+import org.onap.cps.impl.DeltaReportBuilder;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class DeltaReportGenerator {
+    private final DeltaReportHelper deltaReportHelper;
+
+    /**`
+     * Generate delta reports between the given source and target data nodes.
+     *
+     * @param sourceDataNodes the source data nodes
+     * @param targetDataNodes the target data nodes
+     * @return                a list of delta reports
+     */
+    public List<DeltaReport> createDeltaReports(final Collection<DataNode> sourceDataNodes,
+                                                final Collection<DataNode> targetDataNodes) {
+        final List<DeltaReport> deltaReport = new ArrayList<>();
+        final Map<String, DataNode> xpathToSourceDataNodes = convertToXPathToDataNodesMap(sourceDataNodes);
+        final Map<String, DataNode> xpathToTargetDataNodes = convertToXPathToDataNodesMap(targetDataNodes);
+        deltaReport.addAll(getRemovedAndUpdatedDeltaReports(xpathToSourceDataNodes, xpathToTargetDataNodes));
+        deltaReport.addAll(getAddedDeltaReports(xpathToSourceDataNodes, xpathToTargetDataNodes));
+        return deltaReport;
+    }
+
+    private static Map<String, DataNode> convertToXPathToDataNodesMap(final Collection<DataNode> dataNodes) {
+        final Map<String, DataNode> xpathToDataNode = new LinkedHashMap<>();
+        for (final DataNode dataNode : dataNodes) {
+            xpathToDataNode.put(dataNode.getXpath(), dataNode);
+            final Collection<DataNode> childDataNodes = dataNode.getChildDataNodes();
+            if (!childDataNodes.isEmpty()) {
+                xpathToDataNode.putAll(convertToXPathToDataNodesMap(childDataNodes));
+            }
+        }
+        return xpathToDataNode;
+    }
+
+    private List<DeltaReport> getRemovedAndUpdatedDeltaReports(final Map<String, DataNode> xpathToSourceDataNodes,
+                                                               final Map<String, DataNode> xpathToTargetDataNodes) {
+        final List<DeltaReport> removedAndUpdatedDeltaReportEntries = new ArrayList<>();
+        for (final Map.Entry<String, DataNode> entry: xpathToSourceDataNodes.entrySet()) {
+            final String xpath = entry.getKey();
+            final DataNode sourceDataNode = entry.getValue();
+            final DataNode targetDataNode = xpathToTargetDataNodes.get(xpath);
+            final List<DeltaReport> deltaReports;
+            if (targetDataNode == null) {
+                deltaReports = getDeltaReportsForRemove(xpath, sourceDataNode);
+            } else {
+                deltaReports = deltaReportHelper.createDeltaReportsForUpdates(xpath, sourceDataNode, targetDataNode);
+            }
+            removedAndUpdatedDeltaReportEntries.addAll(deltaReports);
+        }
+        return removedAndUpdatedDeltaReportEntries;
+    }
+
+    private static List<DeltaReport> getDeltaReportsForRemove(final String xpath, final DataNode sourceDataNode) {
+        final List<DeltaReport> deltaReportEntriesForRemove = new ArrayList<>();
+        final Map<String, Serializable> sourceDataNodeLeaves = sourceDataNode.getLeaves();
+        final DeltaReport removedDeltaReportEntry = new DeltaReportBuilder().actionRemove().withXpath(xpath)
+            .withSourceData(sourceDataNodeLeaves).build();
+        deltaReportEntriesForRemove.add(removedDeltaReportEntry);
+        return deltaReportEntriesForRemove;
+    }
+
+    private static List<DeltaReport> getAddedDeltaReports(final Map<String, DataNode> xpathToSourceDataNodes,
+                                                          final Map<String, DataNode> xpathToTargetDataNodes) {
+
+        final List<DeltaReport> addedDeltaReportEntries = new ArrayList<>();
+        final Map<String, DataNode> xpathToAddedNodes = new LinkedHashMap<>(xpathToTargetDataNodes);
+        xpathToAddedNodes.keySet().removeAll(xpathToSourceDataNodes.keySet());
+        for (final Map.Entry<String, DataNode> entry: xpathToAddedNodes.entrySet()) {
+            final String xpath = entry.getKey();
+            final DataNode dataNode = entry.getValue();
+            final DeltaReport addedDataForDeltaReport = new DeltaReportBuilder().actionCreate().withXpath(xpath)
+                .withTargetData(dataNode.getLeaves()).build();
+            addedDeltaReportEntries.add(addedDataForDeltaReport);
+        }
+        return addedDeltaReportEntries;
+    }
+
+
+}
index 97618de..dc48ec9 100644 (file)
@@ -36,6 +36,7 @@ import org.onap.cps.utils.JsonObjectMapper
 import org.onap.cps.utils.PrefixResolver
 import org.onap.cps.utils.YangParser
 import org.onap.cps.utils.YangParserHelper
+import org.onap.cps.utils.deltareport.DeltaReportGenerator
 import org.onap.cps.utils.deltareport.DeltaReportHelper
 import org.onap.cps.yang.TimedYangTextSchemaSourceSetBuilder
 import org.onap.cps.yang.YangTextSchemaSourceSet
@@ -60,7 +61,8 @@ class CpsDeltaServiceImplSpec extends Specification {
     def dataMapper = new DataMapper(mockCpsAnchorService, mockPrefixResolver)
     def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
     def deltaReportHelper = new DeltaReportHelper()
-    def objectUnderTest = new CpsDeltaServiceImpl(mockCpsAnchorService, mockCpsDataService, dataNodeFactory, dataMapper, jsonObjectMapper, deltaReportHelper)
+    def deltaReportGenerator = new DeltaReportGenerator(deltaReportHelper)
+    def objectUnderTest = new CpsDeltaServiceImpl(mockCpsAnchorService, mockCpsDataService, dataNodeFactory, dataMapper, jsonObjectMapper, deltaReportHelper, deltaReportGenerator)
 
     static def bookstoreDataNodeWithParentXpath = [new DataNode(xpath: '/bookstore', leaves: ['bookstore-name': 'Easons'])]
     static def bookstoreDataNodeWithChildXpath = [new DataNode(xpath: '/bookstore/categories[@code=\'02\']', leaves: ['code': '02', 'name': 'Kids'])]