Get all cm handles by DMI plugin Identifier 84/130384/16
authoremaclee <lee.anjella.macabuhay@est.tech>
Fri, 19 Aug 2022 08:26:39 +0000 (09:26 +0100)
committerLee Anjella Macabuhay <lee.anjella.macabuhay@est.tech>
Thu, 1 Sep 2022 09:37:42 +0000 (09:37 +0000)
- api added to get cm handles by dmi plugin identifier
- response object refactored from RestOutputCmHandle to collection of
  Strings (cm handle ids)
- added public and private methods in CmHandleQueries to get cm handle ID by dmi plugin
- added unit tests including test to show that there are no duplicates
  on response

Issue-ID: CPS-1136
Signed-off-by: emaclee <lee.anjella.macabuhay@est.tech>
Change-Id: Ia3bdc16172a90ad3a3f9ae11cddcad1352188726

12 files changed:
cps-ncmp-rest/docs/openapi/components.yaml
cps-ncmp-rest/docs/openapi/ncmp-inventory.yml
cps-ncmp-rest/docs/openapi/openapi-inventory.yml
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleQueries.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/ModelledDmiServiceLeaves.java [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesSpec.groovy

index c1e0587..427f083 100644 (file)
@@ -168,7 +168,6 @@ components:
               }
             }
 
-
     CmHandleQueryParameters:
       type: object
       title: Cm Handle query parameters for executing cm handle search
@@ -462,6 +461,14 @@ components:
       schema:
         type: string
         default: /
+    dmiPluginIdentifierInQuery:
+      name: dmi-plugin-identifier
+      in: query
+      description: dmi-plugin-identifier
+      required: true
+      schema:
+        type: string
+        example: my-dmi-plugin
     resourceIdentifierInQuery:
       name: resourceIdentifier
       in: query
index 0a408c2..0c3dffd 100755 (executable)
@@ -97,3 +97,28 @@ updateDmiRegistration:
                   "errorText": "cm-handle has an invalid character(s) in id"
                 }
               ]
+
+getAllCmHandleIdsForRegisteredDmi:
+  get:
+    description: Get all cm handle IDs for a registered DMI plugin
+    tags:
+      - network-cm-proxy-inventory
+    summary: Get all cm handle IDs for a registered DMI plugin (DMI plugin, DMI data plugin, DMI model plugin)
+    operationId: getAllCmHandleIdsForRegisteredDmi
+    parameters:
+      - $ref: 'components.yaml#/components/parameters/dmiPluginIdentifierInQuery'
+    responses:
+      200:
+        description: OK
+        content:
+          application/json:
+            schema:
+              type: array
+              items:
+                type: string
+      401:
+        $ref: 'components.yaml#/components/responses/Unauthorized'
+      403:
+        $ref: 'components.yaml#/components/responses/Forbidden'
+      500:
+        $ref: 'components.yaml#/components/responses/InternalServerError'
\ No newline at end of file
index ee09d05..08270bc 100755 (executable)
@@ -1,5 +1,6 @@
 #  ============LICENSE_START=======================================================
 #  Copyright (C) 2021 Bell Canada
+#  Modifications 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.
@@ -26,3 +27,6 @@ servers:
 paths:
   /v1/ch:
     $ref: 'ncmp-inventory.yml#/updateDmiRegistration'
+
+  /v1/ch/cmHandles:
+    $ref: 'ncmp-inventory.yml#/getAllCmHandleIdsForRegisteredDmi'
\ No newline at end of file
index 105a6a5..0c428e4 100755 (executable)
@@ -22,6 +22,7 @@
 package org.onap.cps.ncmp.rest.controller;
 
 import java.util.List;
+import java.util.Set;
 import java.util.stream.Collectors;
 import javax.validation.Valid;
 import lombok.RequiredArgsConstructor;
@@ -46,6 +47,19 @@ public class NetworkCmProxyInventoryController implements NetworkCmProxyInventor
     private final NetworkCmProxyDataService networkCmProxyDataService;
     private final NcmpRestInputMapper ncmpRestInputMapper;
 
+    /**
+     * Get all cm-handle IDs under a registered DMI plugin.
+     *
+     * @param dmiPluginIdentifier DMI plugin identifier
+     * @return list of cm handle IDs
+     */
+    @Override
+    public ResponseEntity<List<String>> getAllCmHandleIdsForRegisteredDmi(final String dmiPluginIdentifier) {
+        final Set<String> cmHandleIds =
+                networkCmProxyDataService.getAllCmHandleIdsByDmiPluginIdentifier(dmiPluginIdentifier);
+        return ResponseEntity.ok(List.copyOf(cmHandleIds));
+    }
+
     /**
      * Update DMI Plugin Registration (used for first registration also).
      *
@@ -69,7 +83,6 @@ public class NetworkCmProxyInventoryController implements NetworkCmProxyInventor
         return dmiPluginRegistrationErrorResponse.getFailedCreatedCmHandles().isEmpty()
             && dmiPluginRegistrationErrorResponse.getFailedUpdatedCmHandles().isEmpty()
             && dmiPluginRegistrationErrorResponse.getFailedRemovedCmHandles().isEmpty();
-
     }
 
     private DmiPluginRegistrationErrorResponse getFailureRegistrationResponse(
@@ -103,5 +116,3 @@ public class NetworkCmProxyInventoryController implements NetworkCmProxyInventor
     }
 
 }
-
-
index 6673b21..b5a089b 100644 (file)
@@ -27,6 +27,7 @@ import org.onap.cps.ncmp.api.NetworkCmProxyDataService
 import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
 import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
 import org.onap.cps.ncmp.rest.model.CmHandlerRegistrationErrorResponse
 import org.onap.cps.ncmp.rest.model.DmiPluginRegistrationErrorResponse
 import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration
@@ -41,6 +42,7 @@ import org.springframework.http.MediaType
 import org.springframework.test.web.servlet.MockMvc
 import spock.lang.Specification
 
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
 
 @WebMvcTest(NetworkCmProxyInventoryController)
@@ -158,6 +160,23 @@ class NetworkCmProxyInventoryControllerSpec extends Specification {
             'update delete failed' | successResponse('cm-handle-1') | failedResponse('cm-handle-2')  | failedResponse('cm-handle-3')  || []                                  | [failedRestResponse('cm-handle-2')] | [failedRestResponse('cm-handle-3')]
     }
 
+    def 'Get all cm handle IDs by DMI plugin identifier.'() {
+        given: 'an endpoint for returning cm handle IDs for a registered dmi plugin'
+            def getUrl = "$ncmpBasePathV1/ch/cmHandles?dmi-plugin-identifier=some-dmi-plugin-identifier"
+        and: 'a collection of cm handle IDs are returned'
+            1 * mockNetworkCmProxyDataService.getAllCmHandleIdsByDmiPluginIdentifier('some-dmi-plugin-identifier')
+                    >> ['cm-handle-id-1','cm-handle-id-2']
+        when: 'the endpoint is invoked'
+            def response = mvc.perform(
+                    get(getUrl)
+                            .contentType(MediaType.APPLICATION_JSON)
+                            .accept(MediaType.APPLICATION_JSON_VALUE)
+            ).andReturn().response
+        then: 'the response matches the result returned by the service layer'
+            assert response.contentAsString.contains('cm-handle-id-1')
+            assert response.contentAsString.contains('cm-handle-id-2')
+    }
+
     def failedRestResponse(cmHandle) {
         return new CmHandlerRegistrationErrorResponse('cmHandle': cmHandle, 'errorCode': '00', 'errorText': 'Failed')
     }
index 3295a6e..45dba21 100644 (file)
@@ -162,4 +162,12 @@ public interface NetworkCmProxyDataService {
      * @param dataSyncEnabled data sync enabled flag
      */
     void setDataSyncEnabled(String cmHandleId, boolean dataSyncEnabled);
+
+    /**
+     * Get all cm handle IDs by DMI plugin identifier.
+     *
+     * @param dmiPluginIdentifier DMI plugin identifier
+     * @return set of cm handle IDs
+     */
+    Set<String> getAllCmHandleIdsByDmiPluginIdentifier(String dmiPluginIdentifier);
 }
index 0fdecde..5b072f3 100755 (executable)
@@ -30,6 +30,7 @@ import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -44,6 +45,7 @@ import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
 import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
 import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.CmHandleQueries;
 import org.onap.cps.ncmp.api.inventory.CmHandleState;
 import org.onap.cps.ncmp.api.inventory.CompositeState;
 import org.onap.cps.ncmp.api.inventory.CompositeStateUtils;
@@ -80,6 +82,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
 
     private final InventoryPersistence inventoryPersistence;
 
+    private final CmHandleQueries cmHandleQueries;
+
     private final NetworkCmProxyCmHandlerQueryService networkCmProxyCmHandlerQueryService;
 
     private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler;
@@ -218,6 +222,23 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         }
     }
 
+    /**
+     * Get all cm handle IDs by DMI plugin identifier.
+     *
+     * @param dmiPluginIdentifier DMI plugin identifier
+     * @return set of cm handle IDs
+     */
+    @Override
+    public Set<String> getAllCmHandleIdsByDmiPluginIdentifier(final String dmiPluginIdentifier) {
+        final Set<NcmpServiceCmHandle> ncmpServiceCmHandles =
+                cmHandleQueries.getCmHandlesByDmiPluginIdentifier(dmiPluginIdentifier);
+        final Set<String> cmHandleIds = new HashSet<>(ncmpServiceCmHandles.size());
+        ncmpServiceCmHandles.forEach(cmHandle -> {
+            cmHandleIds.add(cmHandle.getCmHandleId());
+        });
+        return cmHandleIds;
+    }
+
     /**
      * Retrieve cm handle details for a given cm handle.
      *
index 9655612..569e91e 100644 (file)
@@ -27,8 +27,10 @@ import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
@@ -57,21 +59,21 @@ public class CmHandleQueries {
      * @return CmHandles which have these public properties
      */
     public Map<String, NcmpServiceCmHandle> queryCmHandlePublicProperties(
-        final Map<String, String> publicPropertyQueryPairs) {
+            final Map<String, String> publicPropertyQueryPairs) {
         if (publicPropertyQueryPairs.isEmpty()) {
             return Collections.emptyMap();
         }
         Map<String, NcmpServiceCmHandle> cmHandleIdToNcmpServiceCmHandles = null;
         for (final Map.Entry<String, String> publicPropertyQueryPair : publicPropertyQueryPairs.entrySet()) {
             final String cpsPath = "//public-properties[@name=\"" + publicPropertyQueryPair.getKey()
-                + "\" and @value=\"" + publicPropertyQueryPair.getValue() + "\"]";
+                    + "\" and @value=\"" + publicPropertyQueryPair.getValue() + "\"]";
 
             final Collection<DataNode> dataNodes = queryCmHandleDataNodesByCpsPath(cpsPath, INCLUDE_ALL_DESCENDANTS);
             if (cmHandleIdToNcmpServiceCmHandles == null) {
                 cmHandleIdToNcmpServiceCmHandles = collectDataNodesToNcmpServiceCmHandles(dataNodes);
             } else {
                 final Collection<String> cmHandleIdsToRetain = dataNodes.parallelStream()
-                    .map(dataNode -> dataNode.getLeaves().get("id").toString()).collect(Collectors.toSet());
+                        .map(dataNode -> dataNode.getLeaves().get("id").toString()).collect(Collectors.toSet());
                 cmHandleIdToNcmpServiceCmHandles.keySet().retainAll(cmHandleIdsToRetain);
             }
             if (cmHandleIdToNcmpServiceCmHandles.isEmpty()) {
@@ -89,8 +91,8 @@ public class CmHandleQueries {
      * @return combined Map of CmHandles
      */
     public Map<String, NcmpServiceCmHandle> combineCmHandleQueries(
-        final Map<String, NcmpServiceCmHandle> firstQuery,
-        final Map<String, NcmpServiceCmHandle> secondQuery) {
+            final Map<String, NcmpServiceCmHandle> firstQuery,
+            final Map<String, NcmpServiceCmHandle> secondQuery) {
         if (firstQuery == NO_QUERY_TO_EXECUTE && secondQuery == NO_QUERY_TO_EXECUTE) {
             return NO_QUERY_TO_EXECUTE;
         } else if (firstQuery == NO_QUERY_TO_EXECUTE) {
@@ -150,7 +152,7 @@ public class CmHandleQueries {
     }
 
     private Map<String, NcmpServiceCmHandle> collectDataNodesToNcmpServiceCmHandles(
-        final Collection<DataNode> dataNodes) {
+            final Collection<DataNode> dataNodes) {
         final Map<String, NcmpServiceCmHandle> cmHandleIdToNcmpServiceCmHandle = new HashMap<>();
         dataNodes.forEach(dataNode -> {
             final NcmpServiceCmHandle ncmpServiceCmHandle = createNcmpServiceCmHandle(dataNode);
@@ -161,7 +163,36 @@ public class CmHandleQueries {
 
     private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
         return convertYangModelCmHandleToNcmpServiceCmHandle(YangDataConverter
-            .convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString()));
+                .convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString()));
+    }
+
+    /**
+     * Get all cm handles by DMI plugin identifier.
+     *
+     * @param dmiPluginIdentifier DMI plugin identifier
+     * @return set of cm handles
+     */
+    public Set<NcmpServiceCmHandle> getCmHandlesByDmiPluginIdentifier(final String dmiPluginIdentifier) {
+        final Map<String, DataNode> cmHandleAsDataNodePerCmHandleId = new HashMap<>();
+        for (final ModelledDmiServiceLeaves modelledDmiServiceLeaf : ModelledDmiServiceLeaves.values()) {
+            for (final DataNode cmHandleAsDataNode: getCmHandlesByDmiPluginIdentifierAndDmiProperty(
+                    dmiPluginIdentifier,
+                    modelledDmiServiceLeaf.getLeafName())) {
+                cmHandleAsDataNodePerCmHandleId.put(
+                        cmHandleAsDataNode.getLeaves().get("id").toString(), cmHandleAsDataNode);
+            }
+        }
+        final Set<NcmpServiceCmHandle> ncmpServiceCmHandles = new HashSet<>(cmHandleAsDataNodePerCmHandleId.size());
+        cmHandleAsDataNodePerCmHandleId.values().forEach(
+                cmHandleAsDataNode -> ncmpServiceCmHandles.add(createNcmpServiceCmHandle(cmHandleAsDataNode)));
+        return ncmpServiceCmHandles;
+    }
+
+    private List<DataNode> getCmHandlesByDmiPluginIdentifierAndDmiProperty(final String dmiPluginIdentifier,
+                                                             final String dmiProperty) {
+        return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
+                "/dmi-registry/cm-handles[@" + dmiProperty + "='" + dmiPluginIdentifier + "']",
+                OMIT_DESCENDANTS);
     }
 
     private DataNode getCmHandleState(final String cmHandleId) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/ModelledDmiServiceLeaves.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/ModelledDmiServiceLeaves.java
new file mode 100644 (file)
index 0000000..0546c38
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  ============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.inventory;
+
+public enum ModelledDmiServiceLeaves {
+    DMI_SERVICE_NAME("dmi-service-name"),
+    DMI_DATA_SERVICE_NAME("dmi-data-service-name"),
+    DMI_MODEL_SERVICE_NAME("dmi-model-service-name");
+
+    private String leafName;
+
+    ModelledDmiServiceLeaves(final String dmiPluginIdentifierKey) {
+        this.leafName = dmiPluginIdentifierKey;
+    }
+
+    public String getLeafName() {
+        return leafName;
+    }
+
+}
index 8d8b3b4..ed985ec 100644 (file)
@@ -29,6 +29,7 @@ import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler
 import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
 import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+import org.onap.cps.ncmp.api.inventory.CmHandleQueries
 import org.onap.cps.ncmp.api.inventory.CmHandleState
 import org.onap.cps.ncmp.api.inventory.InventoryPersistence
 import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse
@@ -59,6 +60,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
     def mockDmiDataOperations = Mock(DmiDataOperations)
     def mockNetworkCmProxyDataServicePropertyHandler = Mock(NetworkCmProxyDataServicePropertyHandler)
     def mockInventoryPersistence = Mock(InventoryPersistence)
+    def mockCmhandleQueries = Mock(CmHandleQueries)
     def stubbedNetworkCmProxyCmHandlerQueryService = Stub(NetworkCmProxyCmHandlerQueryService)
     def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler)
     def mockCpsDataService = Mock(CpsDataService)
@@ -352,7 +354,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
 
     def getObjectUnderTest() {
         return Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations,
-            mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, stubbedNetworkCmProxyCmHandlerQueryService,
-                mockLcmEventsCmHandleStateHandler, mockCpsDataService))
+            mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCmhandleQueries,
+                stubbedNetworkCmProxyCmHandlerQueryService, mockLcmEventsCmHandleStateHandler, mockCpsDataService))
     }
 }
index a114b61..02cfb15 100644 (file)
@@ -25,6 +25,7 @@ package org.onap.cps.ncmp.api.impl
 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService
 import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+import org.onap.cps.ncmp.api.inventory.CmHandleQueries
 import org.onap.cps.ncmp.api.inventory.CmHandleState
 import org.onap.cps.ncmp.api.inventory.CompositeState
 import org.onap.cps.ncmp.api.inventory.InventoryPersistence
@@ -63,6 +64,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
     def mockDmiDataOperations = Mock(DmiDataOperations)
     def nullNetworkCmProxyDataServicePropertyHandler = null
     def mockInventoryPersistence = Mock(InventoryPersistence)
+    def mockCmHandleQueries = Mock(CmHandleQueries)
     def mockDmiPluginRegistration = Mock(DmiPluginRegistration)
     def mockCpsCmHandlerQueryService = Mock(NetworkCmProxyCmHandlerQueryService)
     def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler)
@@ -79,6 +81,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
             mockDmiDataOperations,
             nullNetworkCmProxyDataServicePropertyHandler,
             mockInventoryPersistence,
+            mockCmHandleQueries,
             mockCpsCmHandlerQueryService,
             mockLcmEventsCmHandleStateHandler,
             mockCpsDataService)
@@ -370,6 +373,19 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
             0 * mockInventoryPersistence.saveCmHandleState(_, _)
     }
 
+    def 'Get all cm handle IDs by DMI plugin identifier.' () {
+        given: 'cm handle queries service returns cm handles'
+            1 * mockCmHandleQueries.getCmHandlesByDmiPluginIdentifier('some-dmi-plugin-identifier')
+                    >> [new NcmpServiceCmHandle(cmHandleId: 'cm-handle-1'),
+                        new NcmpServiceCmHandle(cmHandleId: 'cm-handle-2')]
+        when: 'cm handle Ids are requested with dmi plugin identifier'
+            def result = objectUnderTest.getAllCmHandleIdsByDmiPluginIdentifier('some-dmi-plugin-identifier')
+        then: 'the result size is correct'
+            assert result.size() == 2
+        and: 'the result returns the correct details'
+            assert result.containsAll('cm-handle-1','cm-handle-2')
+    }
+
     def dataStores() {
         CompositeState.DataStores.builder()
             .operationalDataStore(CompositeState.Operational.builder()
index 21aa164..26b3613 100644 (file)
@@ -135,6 +135,17 @@ class CmHandleQueriesSpec extends Specification {
             assert result.contains(cmHandleDataNode)
     }
 
+    def 'Get all cm handles by dmi plugin identifier'() {
+        given: 'the DataNodes queried for a given cpsPath are returned from the persistence service.'
+            mockResponses()
+        when: 'cm Handles are fetched for a given dmi plugin identifier'
+            def result = objectUnderTest.getCmHandlesByDmiPluginIdentifier('my-dmi-plugin-identifier')
+        then: 'result is the correct size'
+            assert result.size() == 3
+        and: 'result contains the correct cm handles'
+            assert result.cmHandleId.containsAll('PNFDemo', 'PNFDemo2', 'PNFDemo4')
+    }
+
     void mockResponses() {
         cpsDataPersistenceService.queryDataNodes(_, _, '//public-properties[@name=\"Contact\" and @value=\"newemailforstore@bookstore.com\"]/ancestor::cm-handles', _) >> [pnfDemo, pnfDemo2, pnfDemo4]
         cpsDataPersistenceService.queryDataNodes(_, _, '//public-properties[@name=\"wont_match\" and @value=\"wont_match\"]/ancestor::cm-handles', _) >> []
@@ -142,6 +153,9 @@ class CmHandleQueriesSpec extends Specification {
         cpsDataPersistenceService.queryDataNodes(_, _, '//public-properties[@name=\"Contact2\" and @value=\"\"]/ancestor::cm-handles', _) >> []
         cpsDataPersistenceService.queryDataNodes(_, _, '//state[@cm-handle-state=\"READY\"]/ancestor::cm-handles', _) >> [pnfDemo, pnfDemo3]
         cpsDataPersistenceService.queryDataNodes(_, _, '//state[@cm-handle-state=\"LOCKED\"]/ancestor::cm-handles', _) >> [pnfDemo2, pnfDemo4]
+        cpsDataPersistenceService.queryDataNodes('NCMP-Admin','ncmp-dmi-registry','/dmi-registry/cm-handles[@dmi-service-name=\'my-dmi-plugin-identifier\']',OMIT_DESCENDANTS) >> [pnfDemo, pnfDemo2]
+        cpsDataPersistenceService.queryDataNodes('NCMP-Admin','ncmp-dmi-registry','/dmi-registry/cm-handles[@dmi-data-service-name=\'my-dmi-plugin-identifier\']',OMIT_DESCENDANTS) >> [pnfDemo,pnfDemo4]
+        cpsDataPersistenceService.queryDataNodes('NCMP-Admin','ncmp-dmi-registry','/dmi-registry/cm-handles[@dmi-model-service-name=\'my-dmi-plugin-identifier\']',OMIT_DESCENDANTS) >> [pnfDemo2,pnfDemo4]
     }
 
     def static createDataNode(dataNodeId) {