From 9f6a02b5e78f4e1159672d71b4cd9ff5c0df20eb Mon Sep 17 00:00:00 2001 From: Arpit Singh Date: Fri, 14 Nov 2025 17:54:29 +0530 Subject: [PATCH] Fix response code returned by Get delta between 2 anchors API - Get delta between 2 anchors returned a 200 OK response in case an invalid xpath is provided with the request. - The patch fixes that and now the API returns 400 BAD RERQUEST when an invalid xpath is used Issue-ID: CPS-3041 Change-Id: Ic73003fdcf8e2f67cdf715f8da7641016ba61258 Signed-off-by: Arpit Singh --- .../java/org/onap/cps/impl/CpsDeltaServiceImpl.java | 20 +++++++++++++++++--- .../org/onap/cps/impl/CpsDeltaServiceImplSpec.groovy | 12 +++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) 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 e9f5137464..51e48e2062 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2023-2025 TechMahindra Ltd. + * Copyright (C) 2023-2025 Deutsche Telekom AG * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ package org.onap.cps.impl; +import static org.onap.cps.cpspath.parser.CpsPathUtil.ROOT_NODE_XPATH; import static org.onap.cps.utils.ContentType.JSON; import io.micrometer.core.annotation.Timed; @@ -34,10 +35,13 @@ import org.onap.cps.api.CpsAnchorService; import org.onap.cps.api.CpsDataService; import org.onap.cps.api.CpsDeltaService; import org.onap.cps.api.DataNodeFactory; +import org.onap.cps.api.exceptions.DataValidationException; import org.onap.cps.api.model.Anchor; import org.onap.cps.api.model.DataNode; import org.onap.cps.api.model.DeltaReport; import org.onap.cps.api.parameters.FetchDescendantsOption; +import org.onap.cps.cpspath.parser.CpsPathUtil; +import org.onap.cps.cpspath.parser.PathParsingException; import org.onap.cps.utils.CpsValidator; import org.onap.cps.utils.DataMapper; import org.onap.cps.utils.JsonObjectMapper; @@ -71,10 +75,11 @@ public class CpsDeltaServiceImpl implements CpsDeltaService { final FetchDescendantsOption fetchDescendantsOption, final boolean groupDataNodes) { + final String xpathForDeltaReport = validateXpath(xpath); final Collection sourceDataNodes = cpsDataService.getDataNodesForMultipleXpaths(dataspaceName, - sourceAnchorName, Collections.singletonList(xpath), fetchDescendantsOption); + sourceAnchorName, Collections.singletonList(xpathForDeltaReport), fetchDescendantsOption); final Collection targetDataNodes = cpsDataService.getDataNodesForMultipleXpaths(dataspaceName, - targetAnchorName, Collections.singletonList(xpath), fetchDescendantsOption); + targetAnchorName, Collections.singletonList(xpathForDeltaReport), fetchDescendantsOption); return getDeltaReports(sourceDataNodes, targetDataNodes, groupDataNodes); } @@ -153,4 +158,13 @@ public class CpsDeltaServiceImpl implements CpsDeltaService { } } + private String validateXpath(final String xpath) { + try { + return ROOT_NODE_XPATH.equals(xpath) ? ROOT_NODE_XPATH : CpsPathUtil.getNormalizedXpath(xpath); + } catch (final PathParsingException pathParsingException) { + throw new DataValidationException("Invalid xpath: " + xpath, pathParsingException.getMessage(), + pathParsingException); + } + } + } 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 e6cac2a580..076c4de2b1 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2023-2025 TechMahindra Ltd. + * Copyright (C) 2023-2025 Deutsche Telekom AG * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -142,6 +142,16 @@ class CpsDeltaServiceImplSpec extends Specification { 'updated with grouping enabled' | sourceDataNode | targetDataNode | GROUPING_ENABLED || 'replace' | ['parent':['parent-leaf': 'parent-leaf-as-source-data']] | ['parent':['parent-leaf': 'parent-leaf-as-target-data']] } + def 'Get delta between 2 anchors with invalid xpath'() { + given: 'an invalid xpath' + def invalidXpath = '/test[invalid' + when: 'attempt to get delta between 2 anchors with invalid xpath' + objectUnderTest.getDeltaByDataspaceAndAnchors(dataspaceName, ANCHOR_NAME_1, ANCHOR_NAME_2, invalidXpath, INCLUDE_ALL_DESCENDANTS, GROUPING_DISABLED) + then: 'DataValidationException is thrown' + def exception = thrown(DataValidationException) + assert exception.message == 'Invalid xpath: /test[invalid' + } + def 'Delta Report between parent nodes with children where data node is #scenario without grouping of data nodes'() { given: 'root node xpath and expected source and target data' def xpath = '/' -- 2.16.6