From 1c0b139de87c8073151d0ee99dd28a2a3fb66b62 Mon Sep 17 00:00:00 2001 From: Arpit Singh Date: Fri, 27 Jun 2025 18:35:27 +0530 Subject: [PATCH] Part 2: Refactor CPS Delta code to utility class - Refactoring code for original delta report format to a utility class Issue-ID:CPS-2838 Change-Id: I071c6e191c0ed5b718bd6a0e19117b2c76db44d2 Signed-off-by: Arpit Singh --- .../org/onap/cps/impl/CpsDeltaServiceImpl.java | 64 +----------- .../utils/deltareport/DeltaReportGenerator.java | 115 +++++++++++++++++++++ .../onap/cps/impl/CpsDeltaServiceImplSpec.groovy | 4 +- 3 files changed, 121 insertions(+), 62 deletions(-) create mode 100644 cps-service/src/main/java/org/onap/cps/utils/deltareport/DeltaReportGenerator.java diff --git a/cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java b/cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java index 1a5cdab290..8ca49a3e65 100644 --- a/cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java @@ -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 xpathToSourceDataNodes = convertToXPathToDataNodesMap(sourceDataNodes); - final Map 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 convertToXPathToDataNodesMap(final Collection dataNodes) { - final Map xpathToDataNode = new LinkedHashMap<>(); - for (final DataNode dataNode : dataNodes) { - xpathToDataNode.put(dataNode.getXpath(), dataNode); - final Collection childDataNodes = dataNode.getChildDataNodes(); - if (!childDataNodes.isEmpty()) { - xpathToDataNode.putAll(convertToXPathToDataNodesMap(childDataNodes)); - } - } - return xpathToDataNode; - } - - private List getRemovedAndUpdatedDeltaReports( - final Map xpathToSourceDataNodes, - final Map xpathToTargetDataNodes) { - final List removedAndUpdatedDeltaReportEntries = new ArrayList<>(); - for (final Map.Entry entry: xpathToSourceDataNodes.entrySet()) { - final String xpath = entry.getKey(); - final DataNode sourceDataNode = entry.getValue(); - final DataNode targetDataNode = xpathToTargetDataNodes.get(xpath); - final List deltaReports; - if (targetDataNode == null) { - deltaReports = getDeltaReportsForRemove(xpath, sourceDataNode); - } else { - deltaReports = deltaReportHelper.createDeltaReportsForUpdates(xpath, sourceDataNode, targetDataNode); - } - removedAndUpdatedDeltaReportEntries.addAll(deltaReports); - } - return removedAndUpdatedDeltaReportEntries; - } - - private static List getDeltaReportsForRemove(final String xpath, final DataNode sourceDataNode) { - final List deltaReportEntriesForRemove = new ArrayList<>(); - final Map sourceDataNodeLeaves = sourceDataNode.getLeaves(); - final DeltaReport removedDeltaReportEntry = new DeltaReportBuilder().actionRemove().withXpath(xpath) - .withSourceData(sourceDataNodeLeaves).build(); - deltaReportEntriesForRemove.add(removedDeltaReportEntry); - return deltaReportEntriesForRemove; - } - - private static List getAddedDeltaReports(final Map xpathToSourceDataNodes, - final Map xpathToTargetDataNodes) { - - final List addedDeltaReportEntries = new ArrayList<>(); - final Map xpathToAddedNodes = new LinkedHashMap<>(xpathToTargetDataNodes); - xpathToAddedNodes.keySet().removeAll(xpathToSourceDataNodes.keySet()); - for (final Map.Entry 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 rebuildSourceDataNodes(final String xpath, final Anchor sourceAnchor, final Collection 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 index 0000000000..44b7ba63ae --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/utils/deltareport/DeltaReportGenerator.java @@ -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 createDeltaReports(final Collection sourceDataNodes, + final Collection targetDataNodes) { + final List deltaReport = new ArrayList<>(); + final Map xpathToSourceDataNodes = convertToXPathToDataNodesMap(sourceDataNodes); + final Map xpathToTargetDataNodes = convertToXPathToDataNodesMap(targetDataNodes); + deltaReport.addAll(getRemovedAndUpdatedDeltaReports(xpathToSourceDataNodes, xpathToTargetDataNodes)); + deltaReport.addAll(getAddedDeltaReports(xpathToSourceDataNodes, xpathToTargetDataNodes)); + return deltaReport; + } + + private static Map convertToXPathToDataNodesMap(final Collection dataNodes) { + final Map xpathToDataNode = new LinkedHashMap<>(); + for (final DataNode dataNode : dataNodes) { + xpathToDataNode.put(dataNode.getXpath(), dataNode); + final Collection childDataNodes = dataNode.getChildDataNodes(); + if (!childDataNodes.isEmpty()) { + xpathToDataNode.putAll(convertToXPathToDataNodesMap(childDataNodes)); + } + } + return xpathToDataNode; + } + + private List getRemovedAndUpdatedDeltaReports(final Map xpathToSourceDataNodes, + final Map xpathToTargetDataNodes) { + final List removedAndUpdatedDeltaReportEntries = new ArrayList<>(); + for (final Map.Entry entry: xpathToSourceDataNodes.entrySet()) { + final String xpath = entry.getKey(); + final DataNode sourceDataNode = entry.getValue(); + final DataNode targetDataNode = xpathToTargetDataNodes.get(xpath); + final List deltaReports; + if (targetDataNode == null) { + deltaReports = getDeltaReportsForRemove(xpath, sourceDataNode); + } else { + deltaReports = deltaReportHelper.createDeltaReportsForUpdates(xpath, sourceDataNode, targetDataNode); + } + removedAndUpdatedDeltaReportEntries.addAll(deltaReports); + } + return removedAndUpdatedDeltaReportEntries; + } + + private static List getDeltaReportsForRemove(final String xpath, final DataNode sourceDataNode) { + final List deltaReportEntriesForRemove = new ArrayList<>(); + final Map sourceDataNodeLeaves = sourceDataNode.getLeaves(); + final DeltaReport removedDeltaReportEntry = new DeltaReportBuilder().actionRemove().withXpath(xpath) + .withSourceData(sourceDataNodeLeaves).build(); + deltaReportEntriesForRemove.add(removedDeltaReportEntry); + return deltaReportEntriesForRemove; + } + + private static List getAddedDeltaReports(final Map xpathToSourceDataNodes, + final Map xpathToTargetDataNodes) { + + final List addedDeltaReportEntries = new ArrayList<>(); + final Map xpathToAddedNodes = new LinkedHashMap<>(xpathToTargetDataNodes); + xpathToAddedNodes.keySet().removeAll(xpathToSourceDataNodes.keySet()); + for (final Map.Entry 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; + } + + +} diff --git a/cps-service/src/test/groovy/org/onap/cps/impl/CpsDeltaServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/impl/CpsDeltaServiceImplSpec.groovy index 97618defa8..dc48ec9f07 100644 --- a/cps-service/src/test/groovy/org/onap/cps/impl/CpsDeltaServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/impl/CpsDeltaServiceImplSpec.groovy @@ -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'])] -- 2.16.6