Changing resource identifier to a query param 74/124574/9
authorniamhcore <niamh.core@est.tech>
Wed, 29 Sep 2021 15:43:35 +0000 (16:43 +0100)
committerniamhcore <niamh.core@est.tech>
Wed, 6 Oct 2021 09:03:15 +0000 (10:03 +0100)
*Update dmi operations to build dmi url using query param

Issue-ID: CPS-679
Signed-off-by: niamhcore <niamh.core@est.tech>
Change-Id: I2292507c5057837932f8e21f1a8e80721066b336

cps-ncmp-rest/docs/openapi/components.yaml
cps-ncmp-rest/docs/openapi/ncmproxy.yml
cps-ncmp-rest/docs/openapi/openapi.yml
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy

index ffb8dde..560c945 100644 (file)
@@ -104,13 +104,27 @@ components:
       schema:
         type: string
         default: /
-    resourceIdentifierInPath:
+    resourceIdentifierInQuery:
       name: resourceIdentifier
-      in: path
-      description: Resource identifier to get/set the resource data
+      in: query
+      description: The format of resource identifier depend on the associated DMI Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but it can really be anything.
       required: true
+      allowReserved: true
       schema:
         type: string
+      examples:
+        sample1:
+          value:
+            resourceIdentifier: \parent\child
+        sample2:
+          value:
+            resourceIdentifier: \parent\listElement[key=value]
+        sample3:
+          value:
+            resourceIdentifier: \parent\listElement[key=value]\grandChild
+        sample4:
+          value:
+            resourceIdentifier: parent=1,child=abc
     acceptParamInHeader:
       name: Accept
       in: header
index 2e5eba7..263c76c 100755 (executable)
@@ -211,7 +211,7 @@ getResourceDataForPassthroughOperational:
     operationId: getResourceDataOperationalForCmHandle
     parameters:
       - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
-      - $ref: 'components.yaml#/components/parameters/resourceIdentifierInPath'
+      - $ref: 'components.yaml#/components/parameters/resourceIdentifierInQuery'
       - $ref: 'components.yaml#/components/parameters/acceptParamInHeader'
       - $ref: 'components.yaml#/components/parameters/fieldsParamInQuery'
       - $ref: 'components.yaml#/components/parameters/depthParamInQuery'
@@ -236,7 +236,7 @@ resourceDataForPassthroughRunning:
     operationId: getResourceDataRunningForCmHandle
     parameters:
       - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
-      - $ref: 'components.yaml#/components/parameters/resourceIdentifierInPath'
+      - $ref: 'components.yaml#/components/parameters/resourceIdentifierInQuery'
       - $ref: 'components.yaml#/components/parameters/acceptParamInHeader'
       - $ref: 'components.yaml#/components/parameters/fieldsParamInQuery'
       - $ref: 'components.yaml#/components/parameters/depthParamInQuery'
@@ -259,7 +259,7 @@ resourceDataForPassthroughRunning:
     operationId: createResourceDataRunningForCmHandle
     parameters:
       - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
-      - $ref: 'components.yaml#/components/parameters/resourceIdentifierInPath'
+      - $ref: 'components.yaml#/components/parameters/resourceIdentifierInQuery'
       - $ref: 'components.yaml#/components/parameters/contentParamInHeader'
     requestBody:
       required: true
index 12356b5..1620eba 100755 (executable)
@@ -41,10 +41,10 @@ paths:
   /v1/ch:
     $ref: 'ncmproxy.yml#/updateDmiRegistration'
 
-  /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-operational/{resourceIdentifier}:
+  /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-operational:
     $ref: 'ncmproxy.yml#/getResourceDataForPassthroughOperational'
 
-  /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-running/{resourceIdentifier}:
+  /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-running:
     $ref: 'ncmproxy.yml#/resourceDataForPassthroughRunning'
 
   /v1/ch/{cm-handle}/modules:
index a4d94ce..0a1a641 100755 (executable)
@@ -27,7 +27,6 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import java.util.Collection;
 import javax.validation.Valid;
-import javax.validation.constraints.Min;
 import javax.validation.constraints.NotNull;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
@@ -167,8 +166,8 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
     public ResponseEntity<Object> getResourceDataOperationalForCmHandle(final String cmHandle,
                                                                         final String resourceIdentifier,
                                                                         final String accept,
-                                                                        final @Valid String fields,
-                                                                        final @Min(1) @Valid Integer depth) {
+                                                                        final String fields,
+                                                                        final Integer depth) {
         final Object responseObject = networkCmProxyDataService.getResourceDataOperationalForCmHandle(cmHandle,
                 resourceIdentifier,
                 accept,
@@ -191,8 +190,8 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
     public ResponseEntity<Object> getResourceDataRunningForCmHandle(final String cmHandle,
                                                                     final String resourceIdentifier,
                                                                     final String accept,
-                                                                    final @Valid String fields,
-                                                                    final @Min(1) @Valid Integer depth) {
+                                                                    final String fields,
+                                                                    final Integer depth) {
         final Object responseObject = networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle(cmHandle,
                 resourceIdentifier,
                 accept,
@@ -205,15 +204,15 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
      * Create resource data in datastore pass through running
      * for given cm-handle.
      *
-     * @param cmHandle cm handle identifier
      * @param resourceIdentifier resource identifier
+     * @param cmHandle cm handle identifier
      * @param requestBody requestBody
      * @param contentType content type of body
      * @return {@code ResponseEntity} response from dmi plugi
      */
     @Override
-    public ResponseEntity<Void> createResourceDataRunningForCmHandle(final String cmHandle,
-                                                                     final String resourceIdentifier,
+    public ResponseEntity<Void> createResourceDataRunningForCmHandle(final String resourceIdentifier,
+                                                                     final String cmHandle,
                                                                      final String requestBody,
                                                                      final String contentType) {
         networkCmProxyDataService.createResourceDataPassThroughRunningForCmHandle(cmHandle,
index 9f2b4e1..d62ae93 100644 (file)
@@ -193,7 +193,7 @@ class NetworkCmProxyControllerSpec extends Specification {
     def 'Get Resource Data from pass-through operational.' () {
         given: 'resource data url'
             def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational" +
-                    "/testResourceIdentifier?fields=testFields&depth=5"
+                    "?resourceIdentifier=parent/child&fields=testFields&depth=5"
         when: 'get data resource request is performed'
             def response = mvc.perform(
                     get(getUrl)
@@ -202,7 +202,7 @@ class NetworkCmProxyControllerSpec extends Specification {
             ).andReturn().response
         then: 'the NCMP data service is called with getResourceDataOperationalForCmHandle'
             1 * mockNetworkCmProxyDataService.getResourceDataOperationalForCmHandle('testCmHandle',
-                    'testResourceIdentifier',
+                    'parent/child',
                     'application/json',
                     'testFields',
                     5)
@@ -210,16 +210,16 @@ class NetworkCmProxyControllerSpec extends Specification {
             response.status == HttpStatus.OK.value()
     }
 
-    def 'Get Resource Data from pass-through running.' () {
+    def 'Get Resource Data from pass-through running with #scenario value in resource identifier param.' () {
         given: 'resource data url'
             def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
-                    "/testResourceIdentifier?fields=testFields&depth=5"
+                    "?resourceIdentifier=" + resourceIdentifier + "&fields=testFields&depth=5"
         and: 'ncmp service returns json object'
             mockNetworkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
-                'testResourceIdentifier',
-                'application/json',
-                'testFields',
-                5) >> '{valid-json}'
+                    resourceIdentifier,
+                    'application/json',
+                    'testFields',
+                    5) >> '{valid-json}'
         when: 'get data resource request is performed'
             def response = mvc.perform(
                     get(getUrl)
@@ -230,12 +230,20 @@ class NetworkCmProxyControllerSpec extends Specification {
             response.status == HttpStatus.OK.value()
         and: 'response contains valid object body'
             response.getContentAsString() == '{valid-json}'
+        where: 'tokens are used in the resource identifier parameter'
+            scenario                       | resourceIdentifier
+            '/'                            | 'id/with/slashes'
+            '?'                            | 'idWith?'
+            ','                            | 'idWith,'
+            '='                            | 'idWith='
+            '[]'                           | 'idWith[]'
+            '? needs to be encoded as %3F' | 'idWith%3F'
     }
 
     def 'Create Resource Data from pass-through running with #scenario.' () {
         given: 'resource data url'
             def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
-                    "/testResourceIdentifier"
+                    "?resourceIdentifier=parent/child"
         when: 'get data resource request is performed'
             def response = mvc.perform(
                     post(getUrl)
@@ -244,7 +252,7 @@ class NetworkCmProxyControllerSpec extends Specification {
             ).andReturn().response
         then: 'ncmp service method to create resource called'
             1 * mockNetworkCmProxyDataService.createResourceDataPassThroughRunningForCmHandle('testCmHandle',
-                    'testResourceIdentifier', requestBody, 'application/json;charset=UTF-8')
+                    'parent/child', requestBody, 'application/json;charset=UTF-8')
         and: 'resource is created'
             response.status == HttpStatus.CREATED.value()
         where: 'given request body'
index 71af3d4..c295e03 100644 (file)
@@ -52,6 +52,8 @@ public class DmiOperations {
     private static final String DMI_CM_HANDLE_PATH = "/v1/ch/{cmHandle}";
     private static final String DMI_CM_HANDLE_DATASTORE_PATH = DMI_CM_HANDLE_PATH + "/data/ds";
     private static final String URL_SEPARATOR = "/";
+    private static final String RESOURCE_IDENTIFIER = "resourceIdentifier";
+
 
     /**
      * Constructor for {@code DmiOperations}. This method also manipulates url properties.
@@ -199,7 +201,7 @@ public class DmiOperations {
         stringBuilder.append(DMI_API_PATH);
         stringBuilder.append(DMI_CM_HANDLE_DATASTORE_PATH.replace("{cmHandle}", cmHandle));
         stringBuilder.append(URL_SEPARATOR + dataStoreEnum.getValue());
-        stringBuilder.append(URL_SEPARATOR + resourceId);
+        stringBuilder.append("?" + RESOURCE_IDENTIFIER + "=" + resourceId);
         return stringBuilder;
     }
 
@@ -208,15 +210,10 @@ public class DmiOperations {
                                       final Integer depthQuery) {
         final var doesFieldExists = (fieldsQuery != null && !fieldsQuery.isEmpty());
         if (doesFieldExists) {
-            stringBuilder.append("?").append("fields=").append(fieldsQuery);
+            stringBuilder.append("&").append("fields=").append(fieldsQuery);
         }
         if (depthQuery != null) {
-            if (doesFieldExists) {
-                stringBuilder.append("&");
-            } else {
-                stringBuilder.append("?");
-            }
-            stringBuilder.append("depth=").append(depthQuery);
+            stringBuilder.append("&").append("depth=").append(depthQuery);
         }
     }
 
index 6a1ce1a..8af7781 100644 (file)
@@ -42,11 +42,11 @@ class DmiOperationsSpec extends Specification {
     def 'call get resource data for pass-through:operational datastore from DMI.'() {
         given: 'expected url'
         def expectedUrl = 'testDmiBasePath/dmi/v1/ch/testCmhandle/data/ds' +
-                '/ncmp-datastore:passthrough-operational/testResourceId?fields=testFieldsQuery&depth=10'
+                '/ncmp-datastore:passthrough-operational?resourceIdentifier=parent/child&fields=testFieldsQuery&depth=10'
         when: 'get resource data is called to DMI'
         objectUnderTest.getResourceDataOperationalFromDmi('testDmiBasePath',
                 'testCmhandle',
-                'testResourceId',
+                'parent/child',
                 'testFieldsQuery',
                 10,
                 'testAcceptJson',
@@ -57,11 +57,11 @@ class DmiOperationsSpec extends Specification {
     def 'call get resource data for pass-through:running datastore from DMI.'() {
         given: 'expected url'
         def expectedUrl = 'testDmiBasePath/dmi/v1/ch/testCmhandle/data/ds' +
-                '/ncmp-datastore:passthrough-running/testResourceId?fields=testFieldsQuery&depth=10'
+                '/ncmp-datastore:passthrough-running?resourceIdentifier=parent/child&fields=testFieldsQuery&depth=10'
         when: 'get resource data is called to DMI'
         objectUnderTest.getResourceDataPassThroughRunningFromDmi('testDmiBasePath',
                 'testCmhandle',
-                'testResourceId',
+                'parent/child',
                 'testFieldsQuery',
                 10,
                 'testAcceptJson',
@@ -72,11 +72,11 @@ class DmiOperationsSpec extends Specification {
     def 'call create resource data for pass-through:running datastore from DMI.'() {
         given: 'expected url'
         def expectedUrl = 'testDmiBasePath/dmi/v1/ch/testCmhandle/data/ds' +
-                '/ncmp-datastore:passthrough-running/testResourceId'
+                '/ncmp-datastore:passthrough-running?resourceIdentifier=parent/child'
         when: 'get resource data is called to DMI'
         objectUnderTest.createResourceDataPassThroughRunningFromDmi('testDmiBasePath',
                 'testCmhandle',
-                'testResourceId',
+                'parent/child',
                 'testJsonbody')
         then: 'the put operation is executed with the correct URL'
         1 * mockDmiRestClient.postOperationWithJsonData(expectedUrl, 'testJsonbody', _ as HttpHeaders)