Get cm-handle public properties endpoint 74/129174/8
authorlukegleeson <luke.gleeson@est.tech>
Fri, 6 May 2022 11:02:42 +0000 (12:02 +0100)
committerlukegleeson <luke.gleeson@est.tech>
Fri, 20 May 2022 13:43:05 +0000 (14:43 +0100)
Added RestOuputCmHandlePublicProperties OpenApi Object
Added Get cm-handle public properties endpoint
Added rest and service layer functionality for endpoint with tests
Fixed Copyright Checker violations

Issue-ID: CPS-1018
Signed-off-by: lukegleeson <luke.gleeson@est.tech>
Change-Id: Ifc13cde350a49f6ba705a09e31853dc9c73be168

cps-ncmp-rest/docs/openapi/components.yaml
cps-ncmp-rest/docs/openapi/ncmp.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-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.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/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy

index 7ed2efe..32d25e3 100644 (file)
@@ -217,6 +217,12 @@ components:
           type: string
           example: Book Type
 
+    RestOutputCmHandlePublicProperties:
+      type: object
+      properties:
+        publicCmHandleProperties:
+          $ref: '#/components/schemas/CmHandlePublicProperties'
+
   examples:
     dataSampleRequest:
         summary: Sample request
index 05e4b84..318e6e6 100755 (executable)
@@ -296,6 +296,27 @@ retrieveCmHandleDetailsById:
       500:
         $ref: 'components.yaml#/components/responses/InternalServerError'
 
+getCmHandlePropertiesById:
+  get:
+    description: Get CM handle properties by cm handle id
+    tags:
+      - network-cm-proxy
+    summary: Get CM handle properties
+    operationId: getCmHandlePublicPropertiesByCmHandleId
+    parameters:
+      - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
+    responses:
+      200:
+        description: OK
+        content:
+          application/json:
+            schema:
+              $ref: 'components.yaml#/components/schemas/RestOutputCmHandlePublicProperties'
+      404:
+        $ref: 'components.yaml#/components/responses/NotFound'
+      500:
+        $ref: 'components.yaml#/components/responses/InternalServerError'
+
 queryCmHandles:
   post:
     description: Execute cm handle query search
index 935b657..b408291 100755 (executable)
@@ -41,5 +41,8 @@ paths:
   /v1/ch/{cm-handle}:
     $ref: 'ncmp.yml#/retrieveCmHandleDetailsById'
 
+  /v1/ch/{cm-handle}/properties:
+    $ref: 'ncmp.yml#/getCmHandlePropertiesById'
+
   /v1/data/ch/searches:
     $ref: 'ncmp.yml#/queryCmHandles'
index 5c1f870..ca7e258 100755 (executable)
@@ -2,8 +2,8 @@
  *  ============LICENSE_START=======================================================
  *  Copyright (C) 2021 Pantheon.tech
  *  Modifications Copyright (C) 2021-2022 Nordix Foundation
- *  Modification Copyright (C) 2021 highstreet technologies GmbH
- *  Modifications (C) 2021-2022 Bell Canada
+ *  Modifications Copyright (C) 2021 highstreet technologies GmbH
+ *  Modifications Copyright (C) 2021-2022 Bell Canada
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -57,6 +57,7 @@ import org.onap.cps.ncmp.rest.model.ModuleNameAsJsonObject;
 import org.onap.cps.ncmp.rest.model.ModuleNamesAsJsonArray;
 import org.onap.cps.ncmp.rest.model.RestModuleReference;
 import org.onap.cps.ncmp.rest.model.RestOutputCmHandle;
+import org.onap.cps.ncmp.rest.model.RestOutputCmHandlePublicProperties;
 import org.onap.cps.utils.CpsValidator;
 import org.onap.cps.utils.JsonObjectMapper;
 import org.springframework.http.HttpStatus;
@@ -240,6 +241,22 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
         return ResponseEntity.ok(restOutputCmHandle);
     }
 
+    /**
+     * Get Cm Handle Properties by Cm Handle Id.
+     * @param cmHandleId cm-handle identifier
+     * @return cm handle and its properties
+     */
+    @Override
+    public ResponseEntity<RestOutputCmHandlePublicProperties> getCmHandlePublicPropertiesByCmHandleId(
+        final String cmHandleId) {
+        final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties();
+        cmHandlePublicProperties.add(networkCmProxyDataService.getCmHandlePublicProperties(cmHandleId));
+        final RestOutputCmHandlePublicProperties restOutputCmHandlePublicProperties =
+            new RestOutputCmHandlePublicProperties();
+        restOutputCmHandlePublicProperties.setPublicCmHandleProperties(cmHandlePublicProperties);
+        return ResponseEntity.ok(restOutputCmHandlePublicProperties);
+    }
+
     /**
      * Return module references for a cm handle.
      *
index b34b0ff..ba49321 100644 (file)
@@ -1,15 +1,16 @@
 /*
  *  ============LICENSE_START=======================================================
  *  Copyright (C) 2021 Pantheon.tech
- *  Modification Copyright (C) 2021 highstreet technologies GmbH
- *  Modification Copyright (C) 2021-2022 Nordix Foundation
- *  Modification Copyright (C) 2021-2022 Bell Canada.
+ *  Modifications Copyright (C) 2021 highstreet technologies GmbH
+ *  Modifications Copyright (C) 2021-2022 Nordix Foundation
+ *  Modifications Copyright (C) 2021-2022 Bell Canada.
  *  ================================================================================
  *  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.
@@ -226,14 +227,14 @@ class NetworkCmProxyControllerSpec extends Specification {
 
     def 'Get Cm Handle details by Cm Handle id.' () {
         given: 'an endpoint and a cm handle'
-            def cmHandleDetailsEndpoint = "$ncmpBasePathV1/ch/Some-Cm-Handle"
+            def cmHandleDetailsEndpoint = "$ncmpBasePathV1/ch/some-cm-handle"
         and: 'an existing ncmp service cm handle'
-            def cmHandleId = 'Some-Cm-Handle'
+            def cmHandleId = 'some-cm-handle'
             def dmiProperties = [ prop:'some DMI property' ]
             def publicProperties = [ "public prop":'some public property' ]
             def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, dmiProperties: dmiProperties, publicProperties: publicProperties)
         and: 'the service method is invoked with the cm handle id'
-            1 * mockNetworkCmProxyDataService.getNcmpServiceCmHandle('Some-Cm-Handle') >> ncmpServiceCmHandle
+            1 * mockNetworkCmProxyDataService.getNcmpServiceCmHandle('some-cm-handle') >> ncmpServiceCmHandle
         when: 'the cm handle details api is invoked'
             def response = mvc.perform(get(cmHandleDetailsEndpoint)).andReturn().response
         then: 'the correct response is returned'
@@ -246,6 +247,21 @@ class NetworkCmProxyControllerSpec extends Specification {
             !response.contentAsString.contains("some DMI property")
     }
 
+    def 'Get Cm Handle public properties by Cm Handle id.' () {
+        given: 'a cm handle properties endpoint'
+            def cmHandlePropertiesEndpoint = "$ncmpBasePathV1/ch/some-cm-handle/properties"
+        and: 'some cm handle public properties'
+            def publicProperties =  [ 'public prop':'some public property' ]
+        and: 'the service method is invoked with the cm handle id returning the cm handle public properties'
+            1 * mockNetworkCmProxyDataService.getCmHandlePublicProperties('some-cm-handle') >> publicProperties
+        when: 'the cm handle properties api is invoked'
+            def response = mvc.perform(get(cmHandlePropertiesEndpoint)).andReturn().response
+        then: 'the correct response is returned'
+            response.status == HttpStatus.OK.value()
+        and: 'the response returns public properties and the correct properties'
+            response.contentAsString.equals('{"publicCmHandleProperties":[{"public prop":"some public property"}]}')
+    }
+
     def 'Call execute cm handle searches with unrecognized condition name.'() {
         given: 'an endpoint and json data'
             def searchesEndpoint = "$ncmpBasePathV1/ch/searches"
index 30b6beb..6673b21 100644 (file)
@@ -41,8 +41,6 @@ import org.springframework.http.MediaType
 import org.springframework.test.web.servlet.MockMvc
 import spock.lang.Specification
 
-import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError.CM_HANDLE_ALREADY_EXIST
-import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError.CM_HANDLE_DOES_NOT_EXIST
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
 
 @WebMvcTest(NetworkCmProxyInventoryController)
index 1f6c384..751fdcd 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * ============LICENSE_START=======================================================
+ *  ============LICENSE_START=======================================================
  *  Copyright (C) 2021 highstreet technologies GmbH
- *  Modification Copyright (C) 2021-2022 Nordix Foundation
+ *  Modifications Copyright (C) 2021-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.
index 058c42b..7527ae5 100644 (file)
@@ -26,6 +26,7 @@ package org.onap.cps.ncmp.api;
 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum;
 
 import java.util.Collection;
+import java.util.Map;
 import java.util.Set;
 import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
@@ -121,6 +122,14 @@ public interface NetworkCmProxyDataService {
      */
     NcmpServiceCmHandle getNcmpServiceCmHandle(String cmHandleId);
 
+    /**
+     * Get cm handle public properties by cm handle id.
+     *
+     * @param cmHandleId cm handle identifier
+     * @return a collection of cm handle public properties.
+     */
+    Map<String, String> getCmHandlePublicProperties(String cmHandleId);
+
     /**
      * Query and return cm handles that match the given query parameters.
      *
index c0f73d9..0e748c7 100755 (executable)
@@ -34,6 +34,7 @@ import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED;
 import com.google.common.base.Strings;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -193,6 +194,23 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         return ncmpServiceCmHandle;
     }
 
+    /**
+     * Get cm handle public properties for a given cm handle id.
+     *
+     * @param cmHandleId cm handle identifier
+     * @return cm handle public properties
+     */
+    @Override
+    public Map<String, String> getCmHandlePublicProperties(final String cmHandleId) {
+        CpsValidator.validateNameCharacters(cmHandleId);
+        final YangModelCmHandle yangModelCmHandle =
+            yangModelCmHandleRetriever.getYangModelCmHandle(cmHandleId);
+        final List<YangModelCmHandle.Property> yangModelPublicProperties = yangModelCmHandle.getPublicProperties();
+        final Map<String, String> cmHandlePublicProperties = new HashMap<>();
+        asPropertiesMap(yangModelPublicProperties, cmHandlePublicProperties);
+        return cmHandlePublicProperties;
+    }
+
     /**
      * THis method registers a cm handle and initiates modules sync.
      *
index 65f007d..01f3bfe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * ============LICENSE_START=======================================================
+ *  ============LICENSE_START=======================================================
  *  Copyright (C) 2021-2022 Nordix Foundation
  *  Modifications Copyright (C) 2021 Pantheon.tech
  *  Modifications Copyright (C) 2021-2022 Bell Canada
@@ -74,7 +74,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
 
     def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
 
-    def dataNode = new DataNode(leaves: ['id': 'Some-Cm-Handle', 'dmi-service-name': 'testDmiService'])
+    def dataNode = new DataNode(leaves: ['id': 'some-cm-handle', 'dmi-service-name': 'testDmiService'])
 
     def 'Write resource data for pass-through running from DMI using POST #scenario cm handle properties.'() {
         given: 'cpsDataService returns valid datanode'
@@ -284,12 +284,12 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
             def dmiServiceName = 'some service name'
             def dmiProperties = [new YangModelCmHandle.Property('Book', 'Romance Novel')]
             def publicProperties = [new YangModelCmHandle.Property('Public Book', 'Public Romance Novel')]
-            def yangModelCmHandle = new YangModelCmHandle(id:'Some-Cm-Handle', dmiServiceName: dmiServiceName, dmiProperties: dmiProperties, publicProperties: publicProperties)
-            1 * mockYangModelCmHandleRetriever.getYangModelCmHandle('Some-Cm-Handle') >> yangModelCmHandle
+            def yangModelCmHandle = new YangModelCmHandle(id:'some-cm-handle', dmiServiceName: dmiServiceName, dmiProperties: dmiProperties, publicProperties: publicProperties)
+            1 * mockYangModelCmHandleRetriever.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle
         when: 'getting cm handle details for a given cm handle id from ncmp service'
-            def result = objectUnderTest.getNcmpServiceCmHandle('Some-Cm-Handle')
+            def result = objectUnderTest.getNcmpServiceCmHandle('some-cm-handle')
         then: 'the result returns the correct data'
-            result.cmHandleId == 'Some-Cm-Handle'
+            result.cmHandleId == 'some-cm-handle'
             result.dmiProperties ==[ Book:'Romance Novel' ]
             result.publicProperties == [ "Public Book":'Public Romance Novel' ]
 
@@ -304,6 +304,28 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
             0 * mockYangModelCmHandleRetriever.getYangModelCmHandle(_)
     }
 
+    def 'Get cm handle public properties'() {
+        given: 'a yang modelled cm handle'
+            def dmiProperties = [new YangModelCmHandle.Property('prop', 'some DMI property')]
+            def publicProperties = [new YangModelCmHandle.Property('public prop', 'some public prop')]
+            def yangModelCmHandle = new YangModelCmHandle(id:'some-cm-handle', dmiServiceName: 'some service name', dmiProperties: dmiProperties, publicProperties: publicProperties)
+        and: 'the system returns this yang modelled cm handle'
+            1 * mockYangModelCmHandleRetriever.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle
+        when: 'getting cm handle public properties for a given cm handle id from ncmp service'
+            def result = objectUnderTest.getCmHandlePublicProperties('some-cm-handle')
+        then: 'the result returns the correct data'
+            result == [ 'public prop' : 'some public prop' ]
+    }
+
+    def 'Get cm handle public properties with an invalid id.'() {
+        when: 'getting cm handle details for a given cm handle id with an invalid name'
+            objectUnderTest.getCmHandlePublicProperties('invalid cm handle with spaces')
+        then: 'an exception is thrown'
+            thrown(DataValidationException)
+        and: 'the yang model cm handle retriever is not invoked'
+            0 * mockYangModelCmHandleRetriever.getYangModelCmHandle(_)
+    }
+
     def 'Update resource data for pass-through running from dmi using POST #scenario DMI properties.'() {
         given: 'cpsDataService returns valid datanode'
             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',