From b423251134468015ace3f0af07f9525af4ced269 Mon Sep 17 00:00:00 2001 From: seanbeirne Date: Fri, 14 Nov 2025 11:35:33 +0000 Subject: [PATCH] Bug: Forward Empty attributes to DMI in Provmns GET - Modified RestServiceUrlTemplateBuilder to accept empty attributes - Updated test ware to reflect change Issue-ID: CPS-3046 Change-Id: I35d736cd6884154e1241fd50441cd6e1b0931f89 Signed-off-by: seanbeirne --- .../cps/ncmp/rest/controller/ProvMnsController.java | 6 +++++- .../rest/controller/ProvMnsControllerSpec.groovy | 3 --- .../cps/ncmp/impl/provmns/ParametersBuilder.java | 2 +- .../utils/http/RestServiceUrlTemplateBuilder.java | 19 ++++++++++++++++++- .../ncmp/impl/provmns/ParametersBuilderSpec.groovy | 21 ++++++++++++++++++++- .../http/RestServiceUrlTemplateBuilderSpec.groovy | 18 ++++++++++++++++++ 6 files changed, 62 insertions(+), 7 deletions(-) diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/ProvMnsController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/ProvMnsController.java index 79acf2dc2e..fdfd5615ac 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/ProvMnsController.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/ProvMnsController.java @@ -68,11 +68,12 @@ public class ProvMnsController implements ProvMnS { @Override public ResponseEntity getMoi(final HttpServletRequest httpServletRequest, final Scope scope, - final String filter, final List attributes, + final String filter, List attributes, final List fields, final ClassNameIdGetDataNodeSelectorParameter dataNodeSelector) { final RequestPathParameters requestPathParameters = parameterMapper.extractRequestParameters(httpServletRequest); + attributes = isAttributesInRequest(httpServletRequest) ? attributes : null; try { final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle( alternateIdMatcher.getCmHandleIdByLongestMatchingAlternateId( @@ -224,4 +225,7 @@ public class ProvMnsController implements ProvMnS { return alternateId + " not found"; } + private boolean isAttributesInRequest(final HttpServletRequest httpServletRequest) { + return httpServletRequest.getParameterMap().containsKey("attributes"); + } } diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/ProvMnsControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/ProvMnsControllerSpec.groovy index cecf24c129..8936cfc0c0 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/ProvMnsControllerSpec.groovy +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/ProvMnsControllerSpec.groovy @@ -22,8 +22,6 @@ package org.onap.cps.ncmp.rest.controller import com.fasterxml.jackson.databind.ObjectMapper import jakarta.servlet.ServletException -import org.onap.cps.ncmp.api.data.models.OperationType -import org.onap.cps.ncmp.api.exceptions.ProvMnSException import org.onap.cps.ncmp.api.inventory.models.CompositeState import org.onap.cps.ncmp.exceptions.NoAlternateIdMatchFoundException import org.onap.cps.ncmp.impl.data.policyexecutor.PolicyExecutor @@ -31,7 +29,6 @@ import org.onap.cps.ncmp.impl.dmi.DmiRestClient import org.onap.cps.ncmp.impl.inventory.InventoryPersistence import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle import org.onap.cps.ncmp.impl.provmns.model.PatchItem -import org.onap.cps.ncmp.impl.provmns.model.PatchOperation import org.onap.cps.ncmp.impl.provmns.model.ResourceOneOf import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher import org.onap.cps.ncmp.rest.provmns.ErrorResponseBuilder diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/provmns/ParametersBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/provmns/ParametersBuilder.java index 2e34a3bab1..125ac460d5 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/provmns/ParametersBuilder.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/provmns/ParametersBuilder.java @@ -61,7 +61,7 @@ public class ParametersBuilder { .queryParameter("scopeType", scope.getScopeType() != null ? scope.getScopeType().getValue() : null) .queryParameter("scopeLevel", scope.getScopeLevel() != null ? scope.getScopeLevel().toString() : null) .queryParameter("filter", filter) - .queryParameter("attributes", attributesString.isBlank() ? null : attributesString) + .queryParameterWithBlankValue("attributes", attributes == null ? null : attributesString) .queryParameter("fields", fieldsString.isBlank() ? null : fieldsString) .queryParameter("dataNodeSelector", dataNodeSelector.getDataNodeSelector()) .createUrlTemplateParameters(dmiServiceName, "ProvMnS"); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java index 659dcf5fe6..3bc62cb125 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java @@ -73,7 +73,7 @@ public class RestServiceUrlTemplateBuilder { /** * Add a query parameter to the URL. - * Do NOT encode as the builder wil take care of encoding + * Do NOT encode as the builder will take care of encoding * * @param queryParameterName the name of the variable * @param queryParameterValue the value of the variable (only Strings are supported). @@ -88,6 +88,23 @@ public class RestServiceUrlTemplateBuilder { return this; } + /** + * Add a query parameter to the URL. Query parameter could have a blank value. + * Do NOT encode as the builder will take care of encoding + * + * @param queryParameterName the name of the variable + * @param queryParameterValue the value of the variable (only Strings are supported). + * + * @return this builder instance + */ + public RestServiceUrlTemplateBuilder queryParameterWithBlankValue(final String queryParameterName, + final String queryParameterValue) { + if (queryParameterValue != null) { + queryParameters.put(queryParameterName, queryParameterValue); + } + return this; + } + /** * Constructs a URL template with variables based on the accumulated path segments and query parameters. * diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/provmns/ParametersBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/provmns/ParametersBuilderSpec.groovy index 6470131856..67c364c9ac 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/provmns/ParametersBuilderSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/provmns/ParametersBuilderSpec.groovy @@ -38,7 +38,7 @@ class ParametersBuilderSpec extends Specification{ new ClassNameIdGetDataNodeSelectorParameter(dataNodeSelector: 'my dataNodeSelector'), new YangModelCmHandle(dmiServiceName: 'myDmiService'), new RequestPathParameters(uriLdnFirstPart:'myPathVariable=myPathValue', className: 'myClassName', id:'myId')) - then: 'the template has the correct correct' + then: 'the template has the correct result' assert result.urlTemplate.toString().startsWith('myDmiService/ProvMnS/v1/myPathVariable=myPathValue/myClassName=myId') and: 'all url variable have been set correctly' assert result.urlVariables.size() == 6 @@ -65,6 +65,25 @@ class ParametersBuilderSpec extends Specification{ assert result.urlVariables.keySet()[0] == 'dataNodeSelector' } + def 'Create url template parameters for GET with empty attributes'() { + when: 'Creating URL parameters for GET with empty attributes and fields' + def result = objectUnderTest.createUrlTemplateParametersForRead(new Scope(), + null, + [], + [], + new ClassNameIdGetDataNodeSelectorParameter(dataNodeSelector: 'my dataNodeSelector'), + new YangModelCmHandle(dmiServiceName: 'myDmiService'), + new RequestPathParameters(uriLdnFirstPart:'myPathVariable=myPathValue', className: 'myClassName', id:'myId')) + then: 'the template has the correct result' + assert result.urlTemplate.toString().startsWith('myDmiService/ProvMnS/v1/myPathVariable=myPathValue/myClassName=myId') + and: 'The url variables contains a data node selector and attributes parameters' + assert result.urlVariables.size() == 2 + assert result.urlVariables.keySet()[0] == 'dataNodeSelector' + assert result.urlVariables.keySet()[1] == 'attributes' + and: 'the attributes value is blank' + assert result.urlVariables.attributes == '' + } + def 'Create url template parameters for PUT and PATCH.'() { when: 'Creating URL parameters for PUT (or PATCH)' def result = objectUnderTest.createUrlTemplateParametersForWrite( diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilderSpec.groovy index 9e051156f7..26d156279f 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilderSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilderSpec.groovy @@ -60,4 +60,22 @@ class RestServiceUrlTemplateBuilderSpec extends Specification { where: 'the following parameter values are used' value << [ null, '', ' ' ] } + + def 'Build URL template parameters with empty value query parameters.'() { + when: 'the query parameter with a blank value is given to the builder' + objectUnderTest.queryParameterWithBlankValue('myParam', '') + and: 'the URL template parameters are created' + def result = objectUnderTest.createUrlTemplateParameters('myServer', 'myBasePath') + then: 'parameter myParam is added with empty value' + assert result.urlVariables() == ['myParam': ''] + } + + def 'Build URL template parameters with null value query parameters.'() { + when: 'the query parameter with null value is given to the builder' + objectUnderTest.queryParameterWithBlankValue('myParam', null) + and: 'the URL template parameters are created' + def result = objectUnderTest.createUrlTemplateParameters('myServer', 'myBasePath') + then: 'parameter myParam is not added' + assert result.urlVariables().size() == 0 + } } -- 2.16.6