Bug: Forward Empty attributes to DMI in Provmns GET 42/142442/1
authorseanbeirne <sean.beirne@est.tech>
Fri, 14 Nov 2025 11:35:33 +0000 (11:35 +0000)
committerseanbeirne <sean.beirne@est.tech>
Fri, 14 Nov 2025 12:41:48 +0000 (12:41 +0000)
- Modified RestServiceUrlTemplateBuilder to accept empty attributes
- Updated test ware to reflect change

Issue-ID: CPS-3046
Change-Id: I35d736cd6884154e1241fd50441cd6e1b0931f89
Signed-off-by: seanbeirne <sean.beirne@est.tech>
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/ProvMnsController.java
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/ProvMnsControllerSpec.groovy
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/provmns/ParametersBuilder.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/provmns/ParametersBuilderSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilderSpec.groovy

index 79acf2d..fdfd561 100644 (file)
@@ -68,11 +68,12 @@ public class ProvMnsController implements ProvMnS {
 
     @Override
     public ResponseEntity<Object> getMoi(final HttpServletRequest httpServletRequest, final Scope scope,
-                                                   final String filter, final List<String> attributes,
+                                                   final String filter, List<String> attributes,
                                                    final List<String> 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");
+    }
 }
index cecf24c..8936cfc 100644 (file)
@@ -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
index 2e34a3b..125ac46 100644 (file)
@@ -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");
index 659dcf5..3bc62cb 100644 (file)
@@ -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.
      *
index 6470131..67c364c 100644 (file)
@@ -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(
index 9e05115..26d1562 100644 (file)
@@ -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
+    }
 }