Query data NCMP-Operational with CPSpath

New GET Endpoint: /v1/ch/{cm-handle}/data/ds/{ncmp-datastore-name}/query?cps-path={CPSPath}
Implemented error for {ncmp-datastore-name} other than operational
- (Toine) Refactored and renamed (abstract) handler for better re-use
Mainly by introducing a separate handler for OperationalQuery

Reviewers Toine, Sourabh, Priyank

Issue-ID: CPS-1002
Signed-off-by: lukegleeson <luke.gleeson@est.tech>
Change-Id: Iaca018869d95d4ce800072431baa190050a6dad0
diff --git a/cps-ncmp-rest-stub/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java b/cps-ncmp-rest-stub/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java
index bb919b5..3990dd1 100644
--- a/cps-ncmp-rest-stub/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java
+++ b/cps-ncmp-rest-stub/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java
@@ -163,6 +163,16 @@
     }
 
     @Override
+    public ResponseEntity<Object> queryResourceDataForCmHandle(final String datastoreName,
+                                                               final String cmHandle,
+                                                               final String cpsPath,
+                                                               final String options,
+                                                               final String topic,
+                                                               final Boolean includeDescendants) {
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+    }
+
+    @Override
     public ResponseEntity<RestOutputCmHandle> retrieveCmHandleDetailsById(final String cmHandleId) {
         return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
     }
diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml
index 7ca09ce..b4b8c84 100644
--- a/cps-ncmp-rest/docs/openapi/components.yaml
+++ b/cps-ncmp-rest/docs/openapi/components.yaml
@@ -456,11 +456,16 @@
     cpsPathInQuery:
       name: cps-path
       in: query
-      description: cps-path
+      description: For more details on cps path, please refer https://docs.onap.org/projects/onap-cps/en/latest/cps-path.html
       required: false
       schema:
         type: string
         default: /
+      examples:
+        container cps path:
+          value: //bookstore
+        list attributes cps path:
+          value: //categories[@code=1]
     dmiPluginIdentifierInQuery:
       name: dmi-plugin-identifier
       in: query
@@ -527,7 +532,7 @@
         default: application/json
         example: application/yang-data+json
     datastoreName:
-      name: ncmp-datastore-name
+      name: datastore-name
       in: path
       description: The type of the requested data
       required: true
diff --git a/cps-ncmp-rest/docs/openapi/ncmp.yml b/cps-ncmp-rest/docs/openapi/ncmp.yml
index 38db26f..1f7cce9 100755
--- a/cps-ncmp-rest/docs/openapi/ncmp.yml
+++ b/cps-ncmp-rest/docs/openapi/ncmp.yml
@@ -194,6 +194,41 @@
       502:
         $ref: 'components.yaml#/components/responses/BadGateway'
 
+queryResourceDataForCmHandle:
+  get:
+    tags:
+      - network-cm-proxy
+    summary: Query resource data for a given cm handle
+    description: Query resource data for a given cm handle
+    operationId: queryResourceDataForCmHandle
+    parameters:
+      - $ref: 'components.yaml#/components/parameters/datastoreName'
+      - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
+      - $ref: 'components.yaml#/components/parameters/cpsPathInQuery'
+      - $ref: 'components.yaml#/components/parameters/optionsParamInQuery'
+      - $ref: 'components.yaml#/components/parameters/topicParamInQuery'
+      - $ref: 'components.yaml#/components/parameters/includeDescendantsOptionInQuery'
+    responses:
+      200:
+        description: OK
+        content:
+          application/json:
+            schema:
+              type: object
+            examples:
+              dataSampleResponse:
+                $ref: 'components.yaml#/components/examples/dataSampleResponse'
+      400:
+        $ref: 'components.yaml#/components/responses/BadRequest'
+      401:
+        $ref: 'components.yaml#/components/responses/Unauthorized'
+      403:
+        $ref: 'components.yaml#/components/responses/Forbidden'
+      500:
+        $ref: 'components.yaml#/components/responses/InternalServerError'
+      502:
+        $ref: 'components.yaml#/components/responses/BadGateway'
+
 fetchModuleReferencesByCmHandle:
   get:
     description: fetch all module references (name and revision) for a given cm handle
diff --git a/cps-ncmp-rest/docs/openapi/openapi.yml b/cps-ncmp-rest/docs/openapi/openapi.yml
index fe0c4ac..ee29366 100755
--- a/cps-ncmp-rest/docs/openapi/openapi.yml
+++ b/cps-ncmp-rest/docs/openapi/openapi.yml
@@ -31,9 +31,12 @@
       type: http
       scheme: basic
 paths:
-  /v1/ch/{cm-handle}/data/ds/{ncmp-datastore-name}:
+  /v1/ch/{cm-handle}/data/ds/{datastore-name}:
     $ref: 'ncmp.yml#/resourceDataForCmHandle'
 
+  /v1/ch/{cm-handle}/data/ds/{datastore-name}/query:
+    $ref: 'ncmp.yml#/queryResourceDataForCmHandle'
+
   /v1/ch/{cm-handle}/modules:
     $ref: 'ncmp.yml#/fetchModuleReferencesByCmHandle'
 
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
index 2f6668a..9f171f6 100755
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
@@ -39,7 +39,7 @@
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi;
 import org.onap.cps.ncmp.rest.controller.handlers.DatastoreType;
-import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreResourceRequestHandler;
+import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreRequestHandler;
 import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreResourceRequestHandlerFactory;
 import org.onap.cps.ncmp.rest.exceptions.InvalidDatastoreException;
 import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper;
@@ -91,15 +91,42 @@
                                                              final String topicParamInQuery,
                                                              final Boolean includeDescendants) {
 
-        final NcmpDatastoreResourceRequestHandler ncmpDatastoreResourceRequestHandler =
+        final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler =
                 ncmpDatastoreResourceRequestHandlerFactory.getNcmpDatastoreResourceRequestHandler(
                         DatastoreType.fromDatastoreName(datastoreName));
 
-        return ncmpDatastoreResourceRequestHandler.getResourceData(cmHandle, resourceIdentifier,
+        return ncmpDatastoreRequestHandler.executeRequest(cmHandle, resourceIdentifier,
                 optionsParamInQuery, topicParamInQuery, includeDescendants);
     }
 
     /**
+     * Query resource data from datastore.
+     *
+     * @param datastoreName       name of the datastore
+     * @param cmHandle            cm handle identifier
+     * @param cpsPath             CPS Path
+     * @param optionsParamInQuery options query parameter
+     * @param topicParamInQuery   topic query parameter
+     * @param includeDescendants  whether include descendants
+     * @return {@code ResponseEntity} response from dmi plugin
+     */
+
+    @Override
+    public ResponseEntity<Object> queryResourceDataForCmHandle(final String datastoreName,
+                                                               final String cmHandle,
+                                                               final String cpsPath,
+                                                               final String optionsParamInQuery,
+                                                               final String topicParamInQuery,
+                                                               final Boolean includeDescendants) {
+        validateDataStore(DatastoreType.OPERATIONAL, datastoreName);
+        final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler =
+            ncmpDatastoreResourceRequestHandlerFactory.getNcmpDatastoreResourceQueryHandler();
+
+        return ncmpDatastoreRequestHandler.executeRequest(cmHandle, cpsPath, optionsParamInQuery,
+            topicParamInQuery, includeDescendants);
+    }
+
+    /**
      * Patch resource data from passthrough-running.
      *
      * @param resourceIdentifier resource identifier
@@ -117,7 +144,7 @@
                                                                       final Object requestBody,
                                                                       final String contentType) {
 
-        acceptPassthroughRunningOnly(datastoreName);
+        validateDataStore(DatastoreType.PASSTHROUGH_RUNNING, datastoreName);
 
         final Object responseObject = networkCmProxyDataService
                 .writeResourceDataPassThroughRunningForCmHandle(
@@ -143,7 +170,7 @@
                                                                      final Object requestBody,
                                                                      final String contentType) {
 
-        acceptPassthroughRunningOnly(datastoreName);
+        validateDataStore(DatastoreType.PASSTHROUGH_RUNNING, datastoreName);
 
         networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
                 resourceIdentifier, CREATE, jsonObjectMapper.asJsonString(requestBody), contentType);
@@ -167,7 +194,7 @@
                                                                        final String cmHandle,
                                                                        final Object requestBody,
                                                                        final String contentType) {
-        acceptPassthroughRunningOnly(datastoreName);
+        validateDataStore(DatastoreType.PASSTHROUGH_RUNNING, datastoreName);
 
         networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
                 resourceIdentifier, UPDATE, jsonObjectMapper.asJsonString(requestBody), contentType);
@@ -189,7 +216,7 @@
                                                                      final String resourceIdentifier,
                                                                      final String contentType) {
 
-        acceptPassthroughRunningOnly(datastoreName);
+        validateDataStore(DatastoreType.PASSTHROUGH_RUNNING, datastoreName);
 
         networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
                 resourceIdentifier, DELETE, NO_BODY, contentType);
@@ -332,11 +359,11 @@
         return restOutputCmHandle;
     }
 
-    private void acceptPassthroughRunningOnly(final String datastoreName) {
-        final DatastoreType datastoreType = DatastoreType.fromDatastoreName(datastoreName);
+    private void validateDataStore(final DatastoreType acceptableDataStoreType, final String requestedDatastoreName) {
+        final DatastoreType datastoreType = DatastoreType.fromDatastoreName(requestedDatastoreName);
 
-        if (DatastoreType.PASSTHROUGH_RUNNING != datastoreType) {
-            throw new InvalidDatastoreException(datastoreName + " is not supported");
+        if (acceptableDataStoreType != datastoreType) {
+            throw new InvalidDatastoreException(requestedDatastoreName + " is not supported");
         }
     }
 }
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalQueryHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalQueryHandler.java
new file mode 100644
index 0000000..0586d42
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalQueryHandler.java
@@ -0,0 +1,56 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation
+ *  ================================================================================
+ *  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.ncmp.rest.controller.handlers;
+
+import java.util.function.Supplier;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.NetworkCmProxyQueryService;
+import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
+import org.onap.cps.spi.FetchDescendantsOption;
+
+@Slf4j
+public class NcmpDatastoreOperationalQueryHandler extends NcmpDatastoreRequestHandler {
+
+    private final NetworkCmProxyQueryService networkCmProxyQueryService;
+
+    public NcmpDatastoreOperationalQueryHandler(final NetworkCmProxyQueryService networkCmProxyQueryService,
+                                                final CpsNcmpTaskExecutor cpsNcmpTaskExecutor,
+                                                final int timeOutInMilliSeconds,
+                                                final boolean notificationFeatureEnabled) {
+        super(null, cpsNcmpTaskExecutor, timeOutInMilliSeconds, notificationFeatureEnabled);
+        this.networkCmProxyQueryService = networkCmProxyQueryService;
+    }
+
+    @Override
+    public Supplier<Object> getTaskSupplier(final String cmHandle,
+                                            final String resourceIdentifier,
+                                            final String optionsParamInQuery,
+                                            final String topicParamInQuery,
+                                            final String requestId,
+                                            final Boolean includeDescendant) {
+
+        final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendant);
+
+        return () -> networkCmProxyQueryService.queryResourceDataOperational(cmHandle, resourceIdentifier,
+            fetchDescendantsOption);
+    }
+
+}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalResourceRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalResourceRequestHandler.java
index 6ed9b8c..a4720b2 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalResourceRequestHandler.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalResourceRequestHandler.java
@@ -27,7 +27,7 @@
 import org.onap.cps.spi.FetchDescendantsOption;
 
 @Slf4j
-public class NcmpDatastoreOperationalResourceRequestHandler extends NcmpDatastoreResourceRequestHandler {
+public class NcmpDatastoreOperationalResourceRequestHandler extends NcmpDatastoreRequestHandler {
 
     public NcmpDatastoreOperationalResourceRequestHandler(final NetworkCmProxyDataService networkCmProxyDataService,
                                                           final CpsNcmpTaskExecutor cpsNcmpTaskExecutor,
@@ -37,16 +37,14 @@
     }
 
     @Override
-    public Supplier<Object> getTask(final String cmHandle,
-                                    final String resourceIdentifier,
-                                    final String optionsParamInQuery,
-                                    final String topicParamInQuery,
-                                    final String requestId,
-                                    final Boolean includeDescendant) {
+    public Supplier<Object> getTaskSupplier(final String cmHandle,
+                                            final String resourceIdentifier,
+                                            final String optionsParamInQuery,
+                                            final String topicParamInQuery,
+                                            final String requestId,
+                                            final Boolean includeDescendant) {
 
-        final FetchDescendantsOption fetchDescendantsOption =
-                Boolean.TRUE.equals(includeDescendant) ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
-                        : FetchDescendantsOption.OMIT_DESCENDANTS;
+        final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendant);
 
         return () -> networkCmProxyDataService.getResourceDataOperational(cmHandle, resourceIdentifier,
                 fetchDescendantsOption);
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughOperationalResourceRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughOperationalResourceRequestHandler.java
index 196e5bd..1445e3e 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughOperationalResourceRequestHandler.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughOperationalResourceRequestHandler.java
@@ -26,7 +26,7 @@
 import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
 
 @Slf4j
-public class NcmpDatastorePassthroughOperationalResourceRequestHandler extends NcmpDatastoreResourceRequestHandler {
+public class NcmpDatastorePassthroughOperationalResourceRequestHandler extends NcmpDatastoreRequestHandler {
 
     public NcmpDatastorePassthroughOperationalResourceRequestHandler(
             final NetworkCmProxyDataService networkCmProxyDataService,
@@ -37,12 +37,12 @@
     }
 
     @Override
-    public Supplier<Object> getTask(final String cmHandle,
-                                    final String resourceIdentifier,
-                                    final String optionsParamInQuery,
-                                    final String topicParamInQuery,
-                                    final String requestId,
-                                    final Boolean includeDescendant) {
+    public Supplier<Object> getTaskSupplier(final String cmHandle,
+                                            final String resourceIdentifier,
+                                            final String optionsParamInQuery,
+                                            final String topicParamInQuery,
+                                            final String requestId,
+                                            final Boolean includeDescendant) {
 
         return () -> networkCmProxyDataService.getResourceDataOperationalForCmHandle(
                 cmHandle, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId);
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughRunningResourceRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughRunningResourceRequestHandler.java
index 5bf16b7..8194ec9 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughRunningResourceRequestHandler.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughRunningResourceRequestHandler.java
@@ -26,7 +26,7 @@
 import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
 
 @Slf4j
-public class NcmpDatastorePassthroughRunningResourceRequestHandler extends NcmpDatastoreResourceRequestHandler {
+public class NcmpDatastorePassthroughRunningResourceRequestHandler extends NcmpDatastoreRequestHandler {
 
     public NcmpDatastorePassthroughRunningResourceRequestHandler(
             final NetworkCmProxyDataService networkCmProxyDataService,
@@ -37,12 +37,12 @@
     }
 
     @Override
-    public Supplier<Object> getTask(final String cmHandle,
-                                    final String resourceIdentifier,
-                                    final String optionsParamInQuery,
-                                    final String topicParamInQuery,
-                                    final String requestId,
-                                    final Boolean includeDescendant) {
+    public Supplier<Object> getTaskSupplier(final String cmHandle,
+                                            final String resourceIdentifier,
+                                            final String optionsParamInQuery,
+                                            final String topicParamInQuery,
+                                            final String requestId,
+                                            final Boolean includeDescendant) {
 
         return () -> networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle(
                 cmHandle, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId);
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java
new file mode 100644
index 0000000..8502003
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java
@@ -0,0 +1,106 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation
+ *  ================================================================================
+ *  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.ncmp.rest.controller.handlers;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.function.Supplier;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
+import org.onap.cps.ncmp.rest.util.TopicValidator;
+import org.onap.cps.spi.FetchDescendantsOption;
+import org.springframework.http.ResponseEntity;
+
+@RequiredArgsConstructor
+@Slf4j
+public abstract class NcmpDatastoreRequestHandler {
+
+    private static final String NO_REQUEST_ID = null;
+    private static final String NO_TOPIC = null;
+
+    protected final NetworkCmProxyDataService networkCmProxyDataService;
+    protected final CpsNcmpTaskExecutor cpsNcmpTaskExecutor;
+    protected final int timeOutInMilliSeconds;
+    protected final boolean notificationFeatureEnabled;
+
+    protected abstract Supplier<Object> getTaskSupplier(final String cmHandle,
+                                                        final String resourceIdentifier,
+                                                        final String optionsParamInQuery,
+                                                        final String topicParamInQuery,
+                                                        final String requestId,
+                                                        final Boolean includeDescendant);
+
+    /**
+     * Execute a request on a datastore.
+     *
+     * @param cmHandleId          the cm handle
+     * @param resourceIdentifier  the resource identifier
+     * @param optionsParamInQuery the options param in query
+     * @param topicParamInQuery   the topic param in query
+     * @param includeDescendants  whether include descendants
+     * @return the response entity
+     */
+    public ResponseEntity<Object> executeRequest(final String cmHandleId,
+                                                 final String resourceIdentifier,
+                                                 final String optionsParamInQuery,
+                                                 final String topicParamInQuery,
+                                                 final Boolean includeDescendants) {
+
+        final boolean asyncResponseRequested = topicParamInQuery != null;
+        if (asyncResponseRequested && notificationFeatureEnabled) {
+            final String requestId = UUID.randomUUID().toString();
+            final Supplier<Object> taskSupplier = getTaskSupplier(cmHandleId, resourceIdentifier, optionsParamInQuery,
+                topicParamInQuery, requestId, includeDescendants);
+            return executeTaskAsync(topicParamInQuery, requestId, taskSupplier);
+        }
+
+        if (asyncResponseRequested) {
+            log.warn("Asynchronous request is unavailable as notification feature is currently disabled, "
+                + "will use synchronous operation.");
+        }
+        final Supplier<Object> taskSupplier = getTaskSupplier(cmHandleId, resourceIdentifier, optionsParamInQuery,
+            NO_TOPIC, NO_REQUEST_ID, includeDescendants);
+        return executeTaskSync(taskSupplier);
+    }
+
+    protected ResponseEntity<Object> executeTaskAsync(final String topicParamInQuery,
+                                                      final String requestId,
+                                                      final Supplier<Object> taskSupplier) {
+
+        TopicValidator.validateTopicName(topicParamInQuery);
+        log.debug("Received Async request with id {}", requestId);
+        cpsNcmpTaskExecutor.executeTask(taskSupplier, timeOutInMilliSeconds);
+
+        return ResponseEntity.ok(Map.of("requestId", requestId));
+    }
+
+    protected ResponseEntity<Object> executeTaskSync(final Supplier<Object> taskSupplier) {
+        return ResponseEntity.ok(taskSupplier.get());
+    }
+
+    protected static FetchDescendantsOption getFetchDescendantsOption(final Boolean includeDescendant) {
+        return Boolean.TRUE.equals(includeDescendant) ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
+            : FetchDescendantsOption.OMIT_DESCENDANTS;
+    }
+
+}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandler.java
deleted file mode 100644
index a6d313b..0000000
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandler.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022 Nordix Foundation
- *  ================================================================================
- *  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.ncmp.rest.controller.handlers;
-
-import java.util.Map;
-import java.util.UUID;
-import java.util.function.Supplier;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
-import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
-import org.onap.cps.ncmp.rest.util.TopicValidator;
-import org.springframework.http.ResponseEntity;
-
-@RequiredArgsConstructor
-@Slf4j
-public abstract class NcmpDatastoreResourceRequestHandler {
-
-    private static final String NO_REQUEST_ID = null;
-    private static final String NO_TOPIC = null;
-
-    protected final NetworkCmProxyDataService networkCmProxyDataService;
-    protected final CpsNcmpTaskExecutor cpsNcmpTaskExecutor;
-    protected final int timeOutInMilliSeconds;
-    protected final boolean notificationFeatureEnabled;
-
-    protected abstract Supplier<Object> getTask(final String cmHandle,
-                                                final String resourceIdentifier,
-                                                final String optionsParamInQuery,
-                                                final String topicParamInQuery,
-                                                final String requestId,
-                                                final Boolean includeDescendant);
-
-
-    /**
-     * Get resource data from datastore.
-     *
-     * @param cmHandleId          the cm handle
-     * @param resourceIdentifier  the resource identifier
-     * @param optionsParamInQuery the options param in query
-     * @param topicParamInQuery   the topic param in query
-     * @param includeDescendants  whether include descendants
-     * @return the response entity
-     */
-    public ResponseEntity<Object> getResourceData(final String cmHandleId,
-                                                  final String resourceIdentifier,
-                                                  final String optionsParamInQuery,
-                                                  final String topicParamInQuery,
-                                                  final Boolean includeDescendants) {
-
-        final String requestId = UUID.randomUUID().toString();
-        final boolean asyncResponseRequested = topicParamInQuery != null;
-
-        if (asyncResponseRequested && notificationFeatureEnabled) {
-            TopicValidator.validateTopicName(topicParamInQuery);
-            log.debug("Received Async request with id {}", requestId);
-            cpsNcmpTaskExecutor.executeTask(
-                    getTask(cmHandleId, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId,
-                            includeDescendants), timeOutInMilliSeconds);
-
-            return ResponseEntity.ok(Map.of("requestId", requestId));
-        }
-
-        if (asyncResponseRequested) {
-            log.warn("Asynchronous messaging is currently disabled, will use synchronous operation.");
-        }
-        
-        final Object responseObject =
-                getTask(cmHandleId, resourceIdentifier, optionsParamInQuery, NO_TOPIC, NO_REQUEST_ID,
-                        includeDescendants).get();
-
-        return ResponseEntity.ok(responseObject);
-    }
-}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java
index 7db7542..ff7bda6 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java
@@ -22,6 +22,7 @@
 
 import lombok.RequiredArgsConstructor;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.api.NetworkCmProxyQueryService;
 import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
@@ -31,6 +32,7 @@
 public class NcmpDatastoreResourceRequestHandlerFactory {
 
     private final NetworkCmProxyDataService networkCmProxyDataService;
+    private final NetworkCmProxyQueryService networkCmProxyQueryService;
     private final CpsNcmpTaskExecutor cpsNcmpTaskExecutor;
 
     @Value("${notification.async.executor.time-out-value-in-ms:2000}")
@@ -44,7 +46,7 @@
      * @param datastoreType the datastore type
      * @return the ncmp datastore handler
      */
-    public NcmpDatastoreResourceRequestHandler getNcmpDatastoreResourceRequestHandler(
+    public NcmpDatastoreRequestHandler getNcmpDatastoreResourceRequestHandler(
             final DatastoreType datastoreType) {
 
         switch (datastoreType) {
@@ -60,4 +62,15 @@
                         cpsNcmpTaskExecutor, timeOutInMilliSeconds, notificationFeatureEnabled);
         }
     }
+
+    /**
+     * Gets ncmp datastore query handler.
+     * Note. Currently only ncmp-datastore:operational supports query operations
+     * @return a ncmp datastore query handler.
+     */
+    public NcmpDatastoreRequestHandler getNcmpDatastoreResourceQueryHandler() {
+        return new NcmpDatastoreOperationalQueryHandler(networkCmProxyQueryService, cpsNcmpTaskExecutor,
+            timeOutInMilliSeconds, notificationFeatureEnabled);
+    }
+
 }
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
index b6194bc..d67804e 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
@@ -27,20 +27,24 @@
 import org.mapstruct.factory.Mappers
 import org.onap.cps.TestUtils
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
+import org.onap.cps.ncmp.api.NetworkCmProxyQueryService
 import org.onap.cps.ncmp.api.inventory.CmHandleState
 import org.onap.cps.ncmp.api.inventory.CompositeState
 import org.onap.cps.ncmp.api.inventory.DataStoreSyncState
 import org.onap.cps.ncmp.api.inventory.LockReasonCategory
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
 import org.onap.cps.ncmp.rest.controller.handlers.DatastoreType
+import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreOperationalQueryHandler
 import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreOperationalResourceRequestHandler
 import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastorePassthroughOperationalResourceRequestHandler
 import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastorePassthroughRunningResourceRequestHandler
 import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreResourceRequestHandlerFactory
+import org.onap.cps.ncmp.rest.exceptions.InvalidDatastoreException
 import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor
 import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper
 import org.onap.cps.ncmp.rest.util.DeprecationHelper
 import org.onap.cps.spi.FetchDescendantsOption
+import org.onap.cps.spi.exceptions.DataValidationException
 import org.onap.cps.spi.model.ModuleDefinition
 import org.onap.cps.spi.model.ModuleReference
 import org.onap.cps.utils.JsonObjectMapper
@@ -84,6 +88,9 @@
     NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
 
     @SpringBean
+    NetworkCmProxyQueryService mockNetworkCmProxyQueryService = Mock()
+
+    @SpringBean
     ObjectMapper objectMapper = new ObjectMapper()
 
     @SpringBean
@@ -131,6 +138,10 @@
             DatastoreType.PASSTHROUGH_RUNNING) >>
             new NcmpDatastorePassthroughRunningResourceRequestHandler(
                 mockNetworkCmProxyDataService, spiedCpsTaskExecutor, TIMEOUT_IN_MS, NOTIFICATION_ENABLED)
+
+        stubbedNcmpDatastoreResourceRequestHandlerFactory.getNcmpDatastoreResourceQueryHandler() >>
+            new NcmpDatastoreOperationalQueryHandler(mockNetworkCmProxyQueryService, spiedCpsTaskExecutor,
+                TIMEOUT_IN_MS, NOTIFICATION_ENABLED);
     }
 
     def 'Get Resource Data from pass-through operational.'() {
@@ -194,6 +205,40 @@
             'invalid non-empty topic value in url' | 'passthrough-running'     | '&topic=1_5_*_#'
     }
 
+    def 'Query Resource Data from operational.'() {
+        given: 'the query resource data url'
+            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:operational/query" +
+                "?cps-path=/cps/path"
+        when: 'the query data resource request is performed'
+            def response = mvc.perform(
+                get(getUrl)
+                    .contentType(MediaType.APPLICATION_JSON)
+            ).andReturn().response
+        then: 'the NCMP query service is called with queryResourceDataOperationalForCmHandle'
+            1 * mockNetworkCmProxyQueryService.queryResourceDataOperational('testCmHandle',
+                '/cps/path',
+                FetchDescendantsOption.OMIT_DESCENDANTS)
+        and: 'response status is Ok'
+            response.status == HttpStatus.OK.value()
+    }
+
+    def 'Query Resource Data using datastore of #datastore'() {
+        given: 'the query resource data url'
+            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:${datastore}/query" +
+                "?cps-path=/cps/path"
+        when: 'the query data resource request is performed'
+            def response = mvc.perform(
+                get(getUrl)
+                    .contentType(MediaType.APPLICATION_JSON)
+            ).andReturn().response
+        then: 'a 400 BAD_REQUEST is returned for the unsupported datastore'
+            response.status == 400
+        and: 'the error message is that datastore #datastore is not supported'
+            response.contentAsString.contains("ncmp-datastore:${datastore} is not supported")
+        where: 'the following datastore is used'
+            datastore << ["passthrough-running", "passthrough-operational"]
+    }
+
     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" +
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerFactorySpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerFactorySpec.groovy
new file mode 100644
index 0000000..7c50498
--- /dev/null
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerFactorySpec.groovy
@@ -0,0 +1,40 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation
+ *  ================================================================================
+ *  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.ncmp.rest.controller.handlers
+
+import spock.lang.Specification
+
+class NcmpDatastoreRequestHandlerFactorySpec extends Specification {
+
+    def objectUnderTest = new NcmpDatastoreResourceRequestHandlerFactory(null, null, null)
+
+    def 'Creating ncmp datastore request handlers.'() {
+        when: 'a ncmp datastore request handler is created for #datastoreType'
+            def result = objectUnderTest.getNcmpDatastoreResourceRequestHandler(datastoreType)
+        then: 'the result is of the expected class'
+            result.class == expectedClass
+        where: 'the following type of datastore is used'
+            datastoreType                         || expectedClass
+            DatastoreType.OPERATIONAL             || NcmpDatastoreOperationalResourceRequestHandler
+            DatastoreType.PASSTHROUGH_OPERATIONAL || NcmpDatastorePassthroughOperationalResourceRequestHandler
+            DatastoreType.PASSTHROUGH_RUNNING     || NcmpDatastorePassthroughRunningResourceRequestHandler
+    }
+}
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactorySpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactorySpec.groovy
deleted file mode 100644
index 3f7a8a5..0000000
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactorySpec.groovy
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.onap.cps.ncmp.rest.controller.handlers
-
-import spock.lang.Specification
-
-class NcmpDatastoreResourceRequestHandlerFactorySpec extends Specification {
-
-    def objectUnderTest = new NcmpDatastoreResourceRequestHandlerFactory(null, null)
-
-    def 'Creating ncmp datastore request handlers.'() {
-        when: 'a ncmp datastore request handler is created for #datastoreType'
-            def result = objectUnderTest.getNcmpDatastoreResourceRequestHandler(datastoreType)
-        then: 'the result is of the expected class'
-            result.class == expectedClass
-        where: 'the following type of datastore is used'
-            datastoreType                         || expectedClass
-            DatastoreType.OPERATIONAL             || NcmpDatastoreOperationalResourceRequestHandler
-            DatastoreType.PASSTHROUGH_OPERATIONAL || NcmpDatastorePassthroughOperationalResourceRequestHandler
-            DatastoreType.PASSTHROUGH_RUNNING     || NcmpDatastorePassthroughRunningResourceRequestHandler
-    }
-}
\ No newline at end of file
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyQueryService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyQueryService.java
new file mode 100644
index 0000000..340806b
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyQueryService.java
@@ -0,0 +1,41 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation
+ *  ================================================================================
+ *  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.ncmp.api;
+
+import org.onap.cps.spi.FetchDescendantsOption;
+
+/*
+ * Datastore interface for handling cached CPS data query requests.
+ */
+public interface NetworkCmProxyQueryService {
+
+    /**
+     * Get resource data for operational.
+     *
+     * @param cmHandleId cm handle identifier
+     * @param cpsPath cps path
+     * @Link FetchDescendantsOption fetch descendants option
+     * @return {@code Object} resource data
+     */
+    Object queryResourceDataOperational(String cmHandleId,
+                                      String cpsPath,
+                                      FetchDescendantsOption fetchDescendantsOption);
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImpl.java
new file mode 100644
index 0000000..5540ecd
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImpl.java
@@ -0,0 +1,46 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation
+ *  ================================================================================
+ *  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.ncmp.api.impl;
+
+import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.api.CpsQueryService;
+import org.onap.cps.ncmp.api.NetworkCmProxyQueryService;
+import org.onap.cps.spi.FetchDescendantsOption;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class NetworkCmProxyQueryServiceImpl implements NetworkCmProxyQueryService {
+
+    private final CpsQueryService cpsQueryService;
+
+    @Override
+    public Object queryResourceDataOperational(final String cmHandleId,
+                                               final String cpsPath,
+                                               final FetchDescendantsOption fetchDescendantsOption) {
+        return cpsQueryService.queryDataNodes(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, cpsPath,
+            fetchDescendantsOption);
+    }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImplSpec.groovy
new file mode 100644
index 0000000..1e86a0b
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImplSpec.groovy
@@ -0,0 +1,46 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation
+ *  ================================================================================
+ *  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.ncmp.api.impl
+
+import org.onap.cps.api.CpsQueryService
+import org.onap.cps.spi.FetchDescendantsOption
+import org.onap.cps.spi.model.DataNode
+import spock.lang.Specification
+
+class NetworkCmProxyQueryServiceImplSpec extends Specification {
+
+    def mockCpsQueryService = Mock(CpsQueryService)
+
+    def objectUnderTest = new NetworkCmProxyQueryServiceImpl(mockCpsQueryService)
+
+    def 'Query resource data for operational from DMI.'() {
+        given: 'a list of datanodes'
+            def dataNodes = [new DataNode(xpath: '/cps/path'), new DataNode(xpath: '/cps/path/child')]
+        and: 'the list of datanodes is returned for query data node'
+            1 * mockCpsQueryService.queryDataNodes('NFP-Operational', 'ncmp-dmi-registry',
+                '//cps/path', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNodes
+        when: 'query resource data operational for cm-handle is called'
+            def response = objectUnderTest.queryResourceDataOperational('ncmp-dmi-registry',
+                '//cps/path', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS)
+        then: 'the expected datanodes are returned from the DMI'
+            response == dataNodes
+    }
+}
diff --git a/docs/api/swagger/ncmp/openapi.yaml b/docs/api/swagger/ncmp/openapi.yaml
index b9eee56..44c4788 100644
--- a/docs/api/swagger/ncmp/openapi.yaml
+++ b/docs/api/swagger/ncmp/openapi.yaml
@@ -6,7 +6,7 @@
 servers:
 - url: /ncmp
 paths:
-  /v1/ch/{cm-handle}/data/ds/{ncmp-datastore-name}:
+  /v1/ch/{cm-handle}/data/ds/{datastore-name}:
     get:
       tags:
       - network-cm-proxy
@@ -14,7 +14,7 @@
       description: Get resource data for given cm handle
       operationId: getResourceDataForCmHandle
       parameters:
-      - name: ncmp-datastore-name
+      - name: datastore-name
         in: path
         description: The type of the requested data
         required: true
@@ -154,7 +154,7 @@
         handle
       operationId: updateResourceDataRunningForCmHandle
       parameters:
-      - name: ncmp-datastore-name
+      - name: datastore-name
         in: path
         description: The type of the requested data
         required: true
@@ -277,7 +277,7 @@
       description: create resource data from pass-through running for given cm handle
       operationId: createResourceDataRunningForCmHandle
       parameters:
-      - name: ncmp-datastore-name
+      - name: datastore-name
         in: path
         description: The type of the requested data
         required: true
@@ -397,7 +397,7 @@
       description: Delete resource data from pass-through running for a given cm handle
       operationId: deleteResourceDataRunningForCmHandle
       parameters:
-      - name: ncmp-datastore-name
+      - name: datastore-name
         in: path
         description: The type of the requested data
         required: true
@@ -513,7 +513,7 @@
         handle
       operationId: patchResourceDataRunningForCmHandle
       parameters:
-      - name: ncmp-datastore-name
+      - name: datastore-name
         in: path
         description: The type of the requested data
         required: true
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index 195f062..b757f19 100755
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -37,6 +37,7 @@
 +--------------------------------------+--------------------------------------------------------+
 Features
 --------
+   - `CPS-1002 <https://jira.onap.org/browse/CPS-1002>`_  Query data NCMP-Operational with CPSpath
    - `CPS-1185 <https://jira.onap.org/browse/CPS-1185>`_  Get all dataspaces
    - `CPS-1186 <https://jira.onap.org/browse/CPS-1186>`_  Get all schema sets for a dataspace
    - `CPS-1187 <https://jira.onap.org/browse/CPS-1187>`_  Get single dataspace