Get all cm handles by DMI plugin Identifier

- 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
diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml
index c1e0587..427f083 100644
--- a/cps-ncmp-rest/docs/openapi/components.yaml
+++ b/cps-ncmp-rest/docs/openapi/components.yaml
@@ -168,7 +168,6 @@
               }
             }
 
-
     CmHandleQueryParameters:
       type: object
       title: Cm Handle query parameters for executing cm handle search
@@ -462,6 +461,14 @@
       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
diff --git a/cps-ncmp-rest/docs/openapi/ncmp-inventory.yml b/cps-ncmp-rest/docs/openapi/ncmp-inventory.yml
index 0a408c2..0c3dffd 100755
--- a/cps-ncmp-rest/docs/openapi/ncmp-inventory.yml
+++ b/cps-ncmp-rest/docs/openapi/ncmp-inventory.yml
@@ -97,3 +97,28 @@
                   "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
diff --git a/cps-ncmp-rest/docs/openapi/openapi-inventory.yml b/cps-ncmp-rest/docs/openapi/openapi-inventory.yml
index ee09d05..08270bc 100755
--- a/cps-ncmp-rest/docs/openapi/openapi-inventory.yml
+++ b/cps-ncmp-rest/docs/openapi/openapi-inventory.yml
@@ -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 @@
 paths:
   /v1/ch:
     $ref: 'ncmp-inventory.yml#/updateDmiRegistration'
+
+  /v1/ch/cmHandles:
+    $ref: 'ncmp-inventory.yml#/getAllCmHandleIdsForRegisteredDmi'
\ No newline at end of file
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java
index 105a6a5..0c428e4 100755
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java
@@ -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;
@@ -47,6 +48,19 @@
     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).
      *
      * @param restDmiPluginRegistration the registration data
@@ -69,7 +83,6 @@
         return dmiPluginRegistrationErrorResponse.getFailedCreatedCmHandles().isEmpty()
             && dmiPluginRegistrationErrorResponse.getFailedUpdatedCmHandles().isEmpty()
             && dmiPluginRegistrationErrorResponse.getFailedRemovedCmHandles().isEmpty();
-
     }
 
     private DmiPluginRegistrationErrorResponse getFailureRegistrationResponse(
@@ -103,5 +116,3 @@
     }
 
 }
-
-
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy
index 6673b21..b5a089b 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy
@@ -27,6 +27,7 @@
 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.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 @@
             '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')
     }