Create Endpoint For Get Cm Handles By Name 44/126844/25
authorDylanB95EST <dylan.byrne@est.tech>
Thu, 27 Jan 2022 17:12:52 +0000 (17:12 +0000)
committerDylan Byrne <dylan.byrne@est.tech>
Tue, 1 Mar 2022 16:17:16 +0000 (16:17 +0000)
Create endpoint and implement logic for
get cm handle details by cm handle name

Issue-ID: CPS-817
Change-Id: I83bd2da9219d13fac715a08b19108028ca6f6751
Signed-off-by: DylanB95EST <dylan.byrne@est.tech>
36 files changed:
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/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.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/RestInputMapperSpec.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/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetriever.java with 70% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/PersistenceCmHandle.java with 62% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandlesList.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/PersistenceCmHandlesList.java with 53% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandle.java with 92% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy
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/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetrieverSpec.groovy [deleted file]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/PersistenceCmHandleSpec.groovy with 82% similarity]
cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java
csit/tests/cps-model-sync/cps-model-sync.robot
docs/api/swagger/ncmp/openapi-inventory.yaml
docs/api/swagger/ncmp/openapi.yaml
docs/release-notes.rst

index fd02b6e..d82813b 100644 (file)
@@ -50,7 +50,7 @@ components:
         createdCmHandles:
           type: array
           items:
-            $ref: '#/components/schemas/RestCmHandle'
+            $ref: '#/components/schemas/RestInputCmHandle'
         updatedCmHandles:
           type: array
           example:
@@ -64,14 +64,14 @@ components:
               update-my-property: updated-property
               delete-my-property: '~'
           items:
-            $ref: '#/components/schemas/RestCmHandle'
+            $ref: '#/components/schemas/RestInputCmHandle'
         removedCmHandles:
           type: array
           items:
             type: string
             example: [my-cm-handle1, my-cm-handle2, my-cm-handle3]
 
-    RestCmHandle:
+    RestInputCmHandle:
       required:
         - cmHandle
       type: object
@@ -146,6 +146,23 @@ components:
           type: string
           example: my-module-revision
 
+    RestOutputCmHandle:
+      type: object
+      title: CM handle Details
+      properties:
+        cmHandle:
+          type: string
+          example: my-cm-handle1
+        publicCmHandleProperties:
+          $ref: '#/components/schemas/CmHandlePublicProperties'
+    CmHandlePublicProperties:
+      type: array
+      items:
+        type: object
+        additionalProperties:
+          type: string
+          example: Book Type
+
   examples:
     dataSampleRequest:
         summary: Sample request
index 3a71aba..a267fb4 100755 (executable)
@@ -262,3 +262,30 @@ executeCmHandleSearch:
         $ref: 'components.yaml#/components/responses/Forbidden'
       500:
         $ref: 'components.yaml#/components/responses/InternalServerError'
+
+retrieveCmHandleDetailsById:
+  get:
+    description: Retrieve CM handle details and properties by cm handle id
+    tags:
+      - network-cm-proxy
+    summary: Retrieve CM handle details
+    operationId: retrieveCmHandleDetailsById
+    parameters:
+      - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
+    responses:
+      200:
+        description: OK
+        content:
+          application/json:
+            schema:
+              $ref: 'components.yaml#/components/schemas/RestOutputCmHandle'
+      400:
+        $ref: 'components.yaml#/components/responses/BadRequest'
+      401:
+        $ref: 'components.yaml#/components/responses/Unauthorized'
+      403:
+        $ref: 'components.yaml#/components/responses/Forbidden'
+      404:
+        $ref: 'components.yaml#/components/responses/NotFound'
+      500:
+        $ref: 'components.yaml#/components/responses/InternalServerError'
\ No newline at end of file
index 838a0d0..12a8318 100755 (executable)
@@ -36,4 +36,7 @@ paths:
     $ref: 'ncmp.yml#/fetchModuleReferencesByCmHandle'
 
   /v1/ch/searches:
-    $ref: 'ncmp.yml#/executeCmHandleSearch'
\ No newline at end of file
+    $ref: 'ncmp.yml#/executeCmHandleSearch'
+
+  /v1/ch/{cm-handle}:
+    $ref: 'ncmp.yml#/retrieveCmHandleDetailsById'
\ No newline at end of file
index 419f6e9..86f4460 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  *  ============LICENSE_START=======================================================
  *  Copyright (C) 2021 Pantheon.tech
- *  Modifications (C) 2021-2022 Nordix Foundation
+ *  Modifications Copyright (C) 2021-2022 Nordix Foundation
  *  Modification Copyright (C) 2021 highstreet technologies GmbH
  *  Modifications (C) 2021 Bell Canada
  *  ================================================================================
@@ -10,6 +10,7 @@
  *  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.
@@ -38,15 +39,18 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.modelmapper.ModelMapper;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi;
 import org.onap.cps.ncmp.rest.model.CmHandleProperties;
 import org.onap.cps.ncmp.rest.model.CmHandleProperty;
+import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties;
 import org.onap.cps.ncmp.rest.model.CmHandles;
 import org.onap.cps.ncmp.rest.model.ConditionProperties;
 import org.onap.cps.ncmp.rest.model.Conditions;
 import org.onap.cps.ncmp.rest.model.ModuleNameAsJsonObject;
 import org.onap.cps.ncmp.rest.model.ModuleNamesAsJsonArray;
 import org.onap.cps.ncmp.rest.model.ModuleReference;
+import org.onap.cps.ncmp.rest.model.RestOutputCmHandle;
 import org.onap.cps.utils.JsonObjectMapper;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -185,6 +189,18 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
         return ResponseEntity.ok(cmHandles);
     }
 
+    /**
+     * Search for Cm Handle and Properties by Name.
+     * @param cmHandleId cm-handle identifier
+     * @return cm handle and its properties
+     */
+    @Override
+    public ResponseEntity<RestOutputCmHandle> retrieveCmHandleDetailsById(final String cmHandleId) {
+        final NcmpServiceCmHandle ncmpServiceCmHandle = networkCmProxyDataService.getNcmpServiceCmHandle(cmHandleId);
+        final RestOutputCmHandle restOutputCmHandle = toRestOutputCmHandle(ncmpServiceCmHandle);
+        return ResponseEntity.ok(restOutputCmHandle);
+    }
+
     /**
      * Return module references for a cm handle.
      *
@@ -233,4 +249,13 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
         }
         return cmHandleProperties;
     }
+
+    private RestOutputCmHandle toRestOutputCmHandle(final NcmpServiceCmHandle ncmpServiceCmHandle) {
+        final RestOutputCmHandle restOutputCmHandle = new RestOutputCmHandle();
+        final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties();
+        restOutputCmHandle.setCmHandle(ncmpServiceCmHandle.getCmHandleID());
+        cmHandlePublicProperties.add(ncmpServiceCmHandle.getPublicProperties());
+        restOutputCmHandle.setPublicCmHandleProperties(cmHandlePublicProperties);
+        return restOutputCmHandle;
+    }
 }
index d38204c..a1d046e 100644 (file)
@@ -22,13 +22,12 @@ package org.onap.cps.ncmp.rest.controller;
 
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
-import org.mapstruct.Mappings;
 import org.mapstruct.NullValueMappingStrategy;
 import org.mapstruct.NullValuePropertyMappingStrategy;
-import org.onap.cps.ncmp.api.models.CmHandle;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
-import org.onap.cps.ncmp.rest.model.RestCmHandle;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration;
+import org.onap.cps.ncmp.rest.model.RestInputCmHandle;
 
 @Mapper(componentModel = "spring", nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT,
     nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
@@ -36,11 +35,9 @@ public interface RestInputMapper {
 
     DmiPluginRegistration toDmiPluginRegistration(final RestDmiPluginRegistration restDmiPluginRegistration);
 
-    @Mappings({
-        @Mapping(source = "cmHandle", target = "cmHandleID"),
-        @Mapping(source = "cmHandleProperties", target = "dmiProperties"),
-        @Mapping(source = "publicCmHandleProperties", target = "publicProperties")
-    })
-    CmHandle toCmHandle(final RestCmHandle restCmHandle);
+    @Mapping(source = "cmHandle", target = "cmHandleID")
+    @Mapping(source = "cmHandleProperties", target = "dmiProperties")
+    @Mapping(source = "publicCmHandleProperties", target = "publicProperties")
+    NcmpServiceCmHandle toNcmpServiceCmHandle(final RestInputCmHandle restInputCmHandle);
 
 }
index fd01096..5aaf1c3 100755 (executable)
@@ -59,23 +59,13 @@ public class NetworkCmProxyRestExceptionHandler {
         return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
     }
 
-    @ExceptionHandler({CpsException.class})
-    public static ResponseEntity<Object> handleAnyOtherCpsExceptions(final CpsException exception) {
+    @ExceptionHandler({CpsException.class, ServerNcmpException.class})
+    public static ResponseEntity<Object> handleAnyOtherCpsExceptions(final Exception exception) {
         return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
     }
 
-    @ExceptionHandler({ServerNcmpException.class})
-    public static ResponseEntity<Object> handleServerNcmpExceptions(final ServerNcmpException exception) {
-        return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
-    }
-
-    @ExceptionHandler({DmiRequestException.class})
-    public static ResponseEntity<Object> handleDmiRequestExceptions(final DmiRequestException exception) {
-        return buildErrorResponse(HttpStatus.BAD_REQUEST, exception);
-    }
-
-    @ExceptionHandler({DataValidationException.class, HttpMessageNotReadableException.class})
-    public static ResponseEntity<Object> handleDataValidatedExceptions(final Exception exception) {
+    @ExceptionHandler({DmiRequestException.class, DataValidationException.class, HttpMessageNotReadableException.class})
+    public static ResponseEntity<Object> handleDmiRequestExceptions(final Exception exception) {
         return buildErrorResponse(HttpStatus.BAD_REQUEST, exception);
     }
 
index 0c8b222..c997714 100644 (file)
@@ -22,6 +22,9 @@
 
 package org.onap.cps.ncmp.rest.controller
 
+
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
+
 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
@@ -180,6 +183,28 @@ class NetworkCmProxyControllerSpec extends Specification {
             response.contentAsString == '{"cmHandles":[{"cmHandleId":"some-cmhandle-id1"},{"cmHandleId":"some-cmhandle-id2"}]}'
     }
 
+    def 'Get Cm Handle details by Cm Handle id.' () {
+        given: 'an endpoint and a cm handle'
+            def cmHandleDetailsEndpoint = "$ncmpBasePathV1/ch/Some-Cm-Handle"
+        and: 'an existing ncmp service 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
+        when: 'the cm handle details api is invoked'
+            def response = mvc.perform(get(cmHandleDetailsEndpoint)).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.contains('publicCmHandleProperties')
+            response.contentAsString.contains('public prop')
+            response.contentAsString.contains('some public property')
+        and: 'the content does not contain dmi properties'
+            !response.contentAsString.contains("some DMI property")
+    }
+
     def 'Call execute cm handle searches with unrecognized condition name.'() {
         given: 'an endpoint and json data'
             def searchesEndpoint = "$ncmpBasePathV1/ch/searches"
index c48a8ed..ed93881 100644 (file)
@@ -21,8 +21,8 @@
 package org.onap.cps.ncmp.rest.controller
 
 import org.mapstruct.factory.Mappers
-import org.onap.cps.ncmp.rest.model.RestCmHandle
 import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration
+import org.onap.cps.ncmp.rest.model.RestInputCmHandle
 import spock.lang.Specification
 
 class RestInputMapperSpec extends Specification {
@@ -31,7 +31,7 @@ class RestInputMapperSpec extends Specification {
 
     def 'Convert a created REST CM Handle Input to an NCMP Service CM Handle with #scenario'() {
         given: 'a rest cm handle input'
-            def inputRestCmHandle = new RestCmHandle(cmHandle : 'example-id', cmHandleProperties: dmiProperties,
+            def inputRestCmHandle = new RestInputCmHandle(cmHandle : 'example-id', cmHandleProperties: dmiProperties,
                 publicCmHandleProperties: publicProperties)
             def restDmiPluginRegistration = new RestDmiPluginRegistration(
                 createdCmHandles: [inputRestCmHandle])
index 306f546..8004328 100644 (file)
@@ -29,6 +29,7 @@ import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
 import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException
 import org.onap.cps.ncmp.rest.controller.RestInputMapper
 import org.onap.cps.spi.exceptions.CpsException
+import org.onap.cps.spi.exceptions.DataNodeNotFoundException
 import org.onap.cps.spi.exceptions.DataValidationException
 import org.onap.cps.utils.JsonObjectMapper
 import org.spockframework.spring.SpringBean
@@ -78,6 +79,8 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
     def errorMessage = 'some error message'
     @Shared
     def errorDetails = 'some error details'
+    @Shared
+    def dataNodeNotFoundErrorMessage = 'DataNode not found'
 
     def setup() {
         dataNodeBaseEndpointNcmp = "$basePathNcmp/v1"
@@ -89,13 +92,14 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
             setupTestException(exception, NCMP)
             def response = performTestRequest(NCMP)
         then: 'an HTTP response is returned with correct message and details'
-            assertTestResponse(response, expectedErrorCode, errorMessage, expectedErrorDetails)
+            assertTestResponse(response, expectedErrorCode, expectedErrorMessage, expectedErrorDetails)
         where:
-            scenario      | exception                                           || expectedErrorDetails | expectedErrorCode
-            'CPS'         | new CpsException(errorMessage, errorDetails)        || errorDetails         | INTERNAL_SERVER_ERROR
-            'NCMP-server' | new ServerNcmpException(errorMessage, errorDetails) || null                 | INTERNAL_SERVER_ERROR
-            'NCMP-client' | new DmiRequestException(errorMessage, errorDetails) || null                 | BAD_REQUEST
-            'other'       | new IllegalStateException(errorMessage)             || null                 | INTERNAL_SERVER_ERROR
+            scenario              | exception                                                                 || expectedErrorDetails | expectedErrorMessage          | expectedErrorCode
+            'CPS'                 | new CpsException(errorMessage, errorDetails)                              || errorDetails         |  errorMessage                 | INTERNAL_SERVER_ERROR
+            'NCMP-server'         | new ServerNcmpException(errorMessage, errorDetails)                       || null                 |  errorMessage                 | INTERNAL_SERVER_ERROR
+            'NCMP-client'         | new DmiRequestException(errorMessage, errorDetails)                       || null                 |  errorMessage                 | BAD_REQUEST
+            'DataNode Validation' | new DataNodeNotFoundException(dataNodeNotFoundErrorMessage, errorDetails) || null                 |  dataNodeNotFoundErrorMessage | BAD_REQUEST
+            'other'               | new IllegalStateException(errorMessage)                                   || null                 |  errorMessage                 | INTERNAL_SERVER_ERROR
     }
 
     def 'Post request with exception returns correct HTTP Status.'() {
index 5d2ab53..471e97e 100644 (file)
@@ -26,6 +26,7 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
 
 import java.util.Collection;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.cps.spi.model.ModuleReference;
 
 /*
@@ -44,13 +45,13 @@ public interface NetworkCmProxyDataService {
      * Get resource data for data store pass-through operational
      * using dmi.
      *
-     * @param cmHandle cm handle
+     * @param cmHandleId cm handle identifier
      * @param resourceIdentifier resource identifier
      * @param acceptParamInHeader accept param
      * @param optionsParamInQuery options query
      * @return {@code Object} resource data
      */
-    Object getResourceDataOperationalForCmHandle(String cmHandle,
+    Object getResourceDataOperationalForCmHandle(String cmHandleId,
                                                  String resourceIdentifier,
                                                  String acceptParamInHeader,
                                                  String optionsParamInQuery);
@@ -59,13 +60,13 @@ public interface NetworkCmProxyDataService {
      * Get resource data for data store pass-through running
      * using dmi.
      *
-     * @param cmHandle cm handle
+     * @param cmHandleId cm handle identifier
      * @param resourceIdentifier resource identifier
      * @param acceptParamInHeader accept param
      * @param optionsParamInQuery options query
      * @return {@code Object} resource data
      */
-    Object getResourceDataPassThroughRunningForCmHandle(String cmHandle,
+    Object getResourceDataPassThroughRunningForCmHandle(String cmHandleId,
                                                         String resourceIdentifier,
                                                         String acceptParamInHeader,
                                                         String optionsParamInQuery);
@@ -73,14 +74,14 @@ public interface NetworkCmProxyDataService {
     /**
      * Write resource data for data store pass-through running
      * using dmi for given cm-handle.
-     *  @param cmHandle cm handle
+     *  @param cmHandleId cm handle identifier
      * @param resourceIdentifier resource identifier
      * @param operation required operation
      * @param requestBody request body to create resource
      * @param contentType content type in body
      * @return {@code Object} return data
      */
-    Object writeResourceDataPassThroughRunningForCmHandle(String cmHandle,
+    Object writeResourceDataPassThroughRunningForCmHandle(String cmHandleId,
                                                         String resourceIdentifier,
                                                         OperationEnum operation,
                                                         String requestBody,
@@ -89,10 +90,10 @@ public interface NetworkCmProxyDataService {
     /**
      * Retrieve module references for the given cm handle.
      *
-     * @param cmHandle cm handle
+     * @param cmHandleId cm handle identifier
      * @return a collection of modules names and revisions
      */
-    Collection<ModuleReference> getYangResourcesModuleReferences(String cmHandle);
+    Collection<ModuleReference> getYangResourcesModuleReferences(String cmHandleId);
 
     /**
      * Query cm handle identifiers for the given collection of module names.
@@ -103,4 +104,12 @@ public interface NetworkCmProxyDataService {
      */
     Collection<String> executeCmHandleHasAllModulesSearch(Collection<String> moduleNames);
 
+    /**
+     * Query cm handle details by cm handle's name.
+     *
+     * @param cmHandleId cm handle identifier
+     * @return a collection of cm handle details.
+     */
+    NcmpServiceCmHandle getNcmpServiceCmHandle(String cmHandleId);
+
 }
index 446e45b..1762e46 100755 (executable)
@@ -34,6 +34,7 @@ import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -47,10 +48,11 @@ import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException;
 import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
 import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations;
 import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
-import org.onap.cps.ncmp.api.models.CmHandle;
+import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandlesList;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandlesList;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
 import org.onap.cps.spi.exceptions.DataValidationException;
 import org.onap.cps.spi.model.ModuleReference;
@@ -77,6 +79,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
 
     private final NetworkCmProxyDataServicePropertyHandler networkCmProxyDataServicePropertyHandler;
 
+    private final YangModelCmHandleRetriever yangModelCmHandleRetriever;
+
     @Override
     public void updateDmiRegistrationAndSyncModule(final DmiPluginRegistration dmiPluginRegistration) {
         dmiPluginRegistration.validateDmiPluginRegistration();
@@ -97,12 +101,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     }
 
     @Override
-    public Object getResourceDataOperationalForCmHandle(final String cmHandle,
+    public Object getResourceDataOperationalForCmHandle(final String cmHandleId,
                                                         final String resourceIdentifier,
                                                         final String acceptParamInHeader,
                                                         final String optionsParamInQuery) {
         return handleResponse(dmiDataOperations.getResourceDataFromDmi(
-            cmHandle,
+            cmHandleId,
             resourceIdentifier,
             optionsParamInQuery,
             acceptParamInHeader,
@@ -110,12 +114,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     }
 
     @Override
-    public Object getResourceDataPassThroughRunningForCmHandle(final String cmHandle,
+    public Object getResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
                                                                final String resourceIdentifier,
                                                                final String acceptParamInHeader,
                                                                final String optionsParamInQuery) {
         return handleResponse(dmiDataOperations.getResourceDataFromDmi(
-            cmHandle,
+            cmHandleId,
             resourceIdentifier,
             optionsParamInQuery,
             acceptParamInHeader,
@@ -123,21 +127,21 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     }
 
     @Override
-    public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandle,
+    public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
                                                                final String resourceIdentifier,
                                                                final OperationEnum operation,
                                                                final String requestData,
                                                                final String dataType) {
         return handleResponse(
             dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(
-                cmHandle, resourceIdentifier, operation, requestData, dataType),
+                cmHandleId, resourceIdentifier, operation, requestData, dataType),
             "Not able to " + operation + " resource data.");
     }
 
 
     @Override
-    public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandle) {
-        return cpsModuleService.getYangResourcesModuleReferences(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandle);
+    public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandleId) {
+        return cpsModuleService.getYangResourcesModuleReferences(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId);
     }
 
     /**
@@ -152,16 +156,56 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     }
 
     /**
-     * THis method registers a cm handle and intiates modules sync.
+     * Retrieve cm handle details for a given cm handle.
+     * @param cmHandleId cm handle identifier
+     * @return cm handle details
+     */
+    @Override
+    public NcmpServiceCmHandle getNcmpServiceCmHandle(final String cmHandleId) {
+        final NcmpServiceCmHandle ncmpServiceCmHandle = new NcmpServiceCmHandle();
+        final YangModelCmHandle yangModelCmHandle =
+            yangModelCmHandleRetriever.getDmiServiceNamesAndProperties(cmHandleId);
+        final List<YangModelCmHandle.Property> dmiProperties = yangModelCmHandle.getDmiProperties();
+        final List<YangModelCmHandle.Property> publicProperties = yangModelCmHandle.getPublicProperties();
+        ncmpServiceCmHandle.setCmHandleID(yangModelCmHandle.getId());
+        setDmiProperties(dmiProperties, ncmpServiceCmHandle);
+        setPublicProperties(publicProperties, ncmpServiceCmHandle);
+        return ncmpServiceCmHandle;
+    }
+
+    private void setDmiProperties(final List<YangModelCmHandle.Property> dmiProperties,
+                                  final NcmpServiceCmHandle ncmpServiceCmHandle) {
+        final Map<String, String> dmiPropertiesMap = new LinkedHashMap<>(dmiProperties.size());
+        asPropertiesMap(dmiProperties, dmiPropertiesMap);
+        ncmpServiceCmHandle.setDmiProperties(dmiPropertiesMap);
+    }
+
+    private void setPublicProperties(final List<YangModelCmHandle.Property> publicProperties,
+                                     final NcmpServiceCmHandle ncmpServiceCmHandle) {
+        final Map<String, String> publicPropertiesMap = new LinkedHashMap<>();
+        asPropertiesMap(publicProperties, publicPropertiesMap);
+        ncmpServiceCmHandle.setPublicProperties(publicPropertiesMap);
+    }
+
+    private void asPropertiesMap(final List<YangModelCmHandle.Property> properties,
+                                 final Map<String, String> propertiesMap) {
+        for (final YangModelCmHandle.Property property: properties) {
+            propertiesMap.put(property.getName(), property.getValue());
+        }
+    }
+
+    /**
+     * THis method registers a cm handle and initiates modules sync.
      *
      * @param dmiPluginRegistration dmi plugin registration information.
      * @throws JsonProcessingException thrown if json is malformed or missing.
      */
     public void parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(
         final DmiPluginRegistration dmiPluginRegistration) throws JsonProcessingException {
-        final PersistenceCmHandlesList createdPersistenceCmHandlesList =
-            getUpdatedPersistenceCmHandlesList(dmiPluginRegistration, dmiPluginRegistration.getCreatedCmHandles());
-        registerAndSyncNewCmHandles(createdPersistenceCmHandlesList);
+        final YangModelCmHandlesList createdYangModelCmHandlesList =
+            getUpdatedYangModelCmHandlesList(dmiPluginRegistration,
+                dmiPluginRegistration.getCreatedCmHandles());
+        registerAndSyncNewCmHandles(createdYangModelCmHandlesList);
     }
 
     private static Object handleResponse(final ResponseEntity<?> responseEntity,
@@ -179,29 +223,29 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         networkCmProxyDataServicePropertyHandler.updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles());
     }
 
-    private PersistenceCmHandlesList getUpdatedPersistenceCmHandlesList(
+    private YangModelCmHandlesList getUpdatedYangModelCmHandlesList(
         final DmiPluginRegistration dmiPluginRegistration,
-        final List<CmHandle> updatedCmHandles) {
-        return PersistenceCmHandlesList.toPersistenceCmHandlesList(
+        final List<NcmpServiceCmHandle> updatedCmHandles) {
+        return YangModelCmHandlesList.toYangModelCmHandlesList(
             dmiPluginRegistration.getDmiPlugin(),
             dmiPluginRegistration.getDmiDataPlugin(),
             dmiPluginRegistration.getDmiModelPlugin(),
             updatedCmHandles);
     }
 
-    private void registerAndSyncNewCmHandles(final PersistenceCmHandlesList persistenceCmHandlesList) {
-        final String cmHandleJsonData = jsonObjectMapper.asJsonString(persistenceCmHandlesList);
+    private void registerAndSyncNewCmHandles(final YangModelCmHandlesList yangModelCmHandlesList) {
+        final String cmHandleJsonData = jsonObjectMapper.asJsonString(yangModelCmHandlesList);
         cpsDataService.saveListElements(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT,
                 cmHandleJsonData, NO_TIMESTAMP);
 
-        for (final PersistenceCmHandle persistenceCmHandle : persistenceCmHandlesList.getPersistenceCmHandles()) {
-            syncModulesAndCreateAnchor(persistenceCmHandle);
+        for (final YangModelCmHandle yangModelCmHandle : yangModelCmHandlesList.getYangModelCmHandles()) {
+            syncModulesAndCreateAnchor(yangModelCmHandle);
         }
     }
 
-    protected void syncModulesAndCreateAnchor(final PersistenceCmHandle persistenceCmHandle) {
-        syncAndCreateSchemaSet(persistenceCmHandle);
-        createAnchor(persistenceCmHandle);
+    protected void syncModulesAndCreateAnchor(final YangModelCmHandle yangModelCmHandle) {
+        syncAndCreateSchemaSet(yangModelCmHandle);
+        createAnchor(yangModelCmHandle);
     }
 
     private void parseAndRemoveCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) {
@@ -225,9 +269,9 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         }
     }
 
-    private void syncAndCreateSchemaSet(final PersistenceCmHandle persistenceCmHandle) {
+    private void syncAndCreateSchemaSet(final YangModelCmHandle yangModelCmHandle) {
         final Collection<ModuleReference> moduleReferencesFromCmHandle =
-            dmiModelOperations.getModuleReferences(persistenceCmHandle);
+            dmiModelOperations.getModuleReferences(yangModelCmHandle);
 
         final Collection<ModuleReference> identifiedNewModuleReferencesFromCmHandle = cpsModuleService
             .identifyNewModuleReferences(moduleReferencesFromCmHandle);
@@ -241,16 +285,16 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         if (identifiedNewModuleReferencesFromCmHandle.isEmpty()) {
             newModuleNameToContentMap = new HashMap<>();
         } else {
-            newModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(persistenceCmHandle,
+            newModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle,
                 identifiedNewModuleReferencesFromCmHandle);
         }
         cpsModuleService
-            .createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, persistenceCmHandle.getId(),
+            .createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, yangModelCmHandle.getId(),
                 newModuleNameToContentMap, existingModuleReferencesFromCmHandle);
     }
 
-    private void createAnchor(final PersistenceCmHandle persistenceCmHandle) {
-        cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, persistenceCmHandle.getId(),
-            persistenceCmHandle.getId());
+    private void createAnchor(final YangModelCmHandle yangModelCmHandle) {
+        cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, yangModelCmHandle.getId(),
+            yangModelCmHandle.getId());
     }
 }
index 3599213..ca2f578 100644 (file)
@@ -37,7 +37,7 @@ import java.util.regex.Pattern;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.api.CpsDataService;
-import org.onap.cps.ncmp.api.models.CmHandle;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.cps.spi.FetchDescendantsOption;
 import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
 import org.onap.cps.spi.model.DataNode;
@@ -56,28 +56,31 @@ public class NetworkCmProxyDataServicePropertyHandler {
     private final CpsDataService cpsDataService;
 
     /**
-     * Iterates over incoming cmHandles and update the dataNodes based on the updated attributes.
+     * Iterates over incoming ncmpServiceCmHandles and update the dataNodes based on the updated attributes.
      * The attributes which are not passed will remain as is.
      *
-     * @param cmHandles collection of cmHandles
+     * @param ncmpServiceCmHandles collection of ncmpServiceCmHandles
      */
-    public void updateCmHandleProperties(final Collection<CmHandle> cmHandles) throws DataNodeNotFoundException {
-        for (final CmHandle cmHandle : cmHandles) {
+    public void updateCmHandleProperties(final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles)
+        throws DataNodeNotFoundException {
+        for (final NcmpServiceCmHandle ncmpServiceCmHandle : ncmpServiceCmHandles) {
             try {
-                final String cmHandleXpath = String.format(CM_HANDLE_XPATH_TEMPLATE, cmHandle.getCmHandleID());
+                final String cmHandleXpath = String.format(CM_HANDLE_XPATH_TEMPLATE,
+                    ncmpServiceCmHandle.getCmHandleID());
                 final DataNode existingCmHandleDataNode =
                         cpsDataService.getDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cmHandleXpath,
                                 FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
-                processUpdates(existingCmHandleDataNode, cmHandle);
+                processUpdates(existingCmHandleDataNode, ncmpServiceCmHandle);
             } catch (final DataNodeNotFoundException e) {
-                log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}", cmHandle.getCmHandleID(),
+                log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}",
+                    ncmpServiceCmHandle.getCmHandleID(),
                         e.getMessage());
                 throw e;
             }
         }
     }
 
-    private void processUpdates(final DataNode existingCmHandleDataNode, final CmHandle incomingCmHandle) {
+    private void processUpdates(final DataNode existingCmHandleDataNode, final NcmpServiceCmHandle incomingCmHandle) {
         if (!incomingCmHandle.getPublicProperties().isEmpty()) {
             updateProperties(existingCmHandleDataNode, PUBLIC_PROPERTY, incomingCmHandle.getPublicProperties());
         }
index bce3ac3..229d4fc 100644 (file)
@@ -27,7 +27,7 @@ import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.DATA;
 
 import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
 import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
 import org.onap.cps.utils.JsonObjectMapper;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.ResponseEntity;
@@ -44,7 +44,7 @@ public class DmiDataOperations extends DmiOperations {
      *
      * @param dmiRestClient {@code DmiRestClient}
      */
-    public DmiDataOperations(final PersistenceCmHandleRetriever cmHandlePropertiesRetriever,
+    public DmiDataOperations(final YangModelCmHandleRetriever cmHandlePropertiesRetriever,
                              final JsonObjectMapper jsonObjectMapper,
                              final NcmpConfiguration.DmiProperties dmiProperties,
                              final DmiRestClient dmiRestClient) {
@@ -55,28 +55,28 @@ public class DmiDataOperations extends DmiOperations {
      * This method fetches the resource data from operational data store for given cm handle
      * identifier on given resource using dmi client.
      *
-     * @param cmHandle    network resource identifier
+     * @param cmHandleId    network resource identifier
      * @param resourceId  resource identifier
      * @param optionsParamInQuery options query
      * @param acceptParamInHeader accept parameter
      * @param dataStore  data store enum
      * @return {@code ResponseEntity} response entity
      */
-    public ResponseEntity<Object> getResourceDataFromDmi(final String cmHandle,
+    public ResponseEntity<Object> getResourceDataFromDmi(final String cmHandleId,
                                                           final String resourceId,
                                                           final String optionsParamInQuery,
                                                           final String acceptParamInHeader,
                                                           final DataStoreEnum dataStore) {
-        final PersistenceCmHandle persistenceCmHandle =
-            cmHandlePropertiesRetriever.retrieveCmHandleDmiServiceNameAndDmiProperties(cmHandle);
+        final YangModelCmHandle yangModelCmHandle =
+            yangModelCmHandleRetriever.getDmiServiceNamesAndProperties(cmHandleId);
         final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
             .operation(READ)
             .build();
-        dmiRequestBody.asDmiProperties(persistenceCmHandle.getDmiProperties());
+        dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties());
         final String jsonBody = jsonObjectMapper.asJsonString(dmiRequestBody);
 
         final var dmiResourceDataUrl = getDmiDatastoreUrlWithOptions(
-            persistenceCmHandle.resolveDmiServiceName(DATA), cmHandle, resourceId,
+            yangModelCmHandle.resolveDmiServiceName(DATA), cmHandleId, resourceId,
             optionsParamInQuery, dataStore);
         final var httpHeaders = prepareHeader(acceptParamInHeader);
         return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonBody, httpHeaders);
@@ -86,38 +86,38 @@ public class DmiDataOperations extends DmiOperations {
      * This method creates the resource data from pass-through running data store for given cm handle
      * identifier on given resource using dmi client.
      *
-     * @param cmHandle    network resource identifier
+     * @param cmHandleId    network resource identifier
      * @param resourceId  resource identifier
      * @param operation   operation enum
      * @param requestData the request data
      * @param dataType    data type
      * @return {@code ResponseEntity} response entity
      */
-    public ResponseEntity<Object> writeResourceDataPassThroughRunningFromDmi(final String cmHandle,
+    public ResponseEntity<Object> writeResourceDataPassThroughRunningFromDmi(final String cmHandleId,
                                                                              final String resourceId,
                                                                              final OperationEnum operation,
                                                                              final String requestData,
                                                                              final String dataType) {
-        final PersistenceCmHandle persistenceCmHandle =
-            cmHandlePropertiesRetriever.retrieveCmHandleDmiServiceNameAndDmiProperties(cmHandle);
+        final YangModelCmHandle yangModelCmHandle =
+            yangModelCmHandleRetriever.getDmiServiceNamesAndProperties(cmHandleId);
         final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
             .operation(operation)
             .data(requestData)
             .dataType(dataType)
             .build();
-        dmiRequestBody.asDmiProperties(persistenceCmHandle.getDmiProperties());
+        dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties());
         final String jsonBody = jsonObjectMapper.asJsonString(dmiRequestBody);
         final String dmiUrl =
-            getResourceInDataStoreUrl(persistenceCmHandle.resolveDmiServiceName(DATA),
-            cmHandle, resourceId, PASSTHROUGH_RUNNING);
+            getResourceInDataStoreUrl(yangModelCmHandle.resolveDmiServiceName(DATA),
+                cmHandleId, resourceId, PASSTHROUGH_RUNNING);
         return dmiRestClient.postOperationWithJsonData(dmiUrl, jsonBody, new HttpHeaders());
     }
 
     private String getResourceInDataStoreUrl(final String dmiServiceName,
-                                             final String cmHandle,
+                                             final String cmHandleId,
                                              final String resourceId,
                                              final DataStoreEnum dataStoreEnum) {
-        return getCmHandleUrl(dmiServiceName, cmHandle)
+        return getCmHandleUrl(dmiServiceName, cmHandleId)
             + "data"
             + URL_SEPARATOR
             + "ds"
@@ -128,12 +128,12 @@ public class DmiDataOperations extends DmiOperations {
     }
 
     private String getDmiDatastoreUrlWithOptions(final String dmiServiceName,
-                                                 final String cmHandle,
+                                                 final String cmHandleId,
                                                  final String resourceId,
                                                  final String optionsParamInQuery,
                                                  final DataStoreEnum dataStoreEnum) {
         final String resourceInDataStoreUrl = getResourceInDataStoreUrl(dmiServiceName,
-            cmHandle, resourceId, dataStoreEnum);
+            cmHandleId, resourceId, dataStoreEnum);
         return appendOptionsQuery(resourceInDataStoreUrl, optionsParamInQuery);
     }
 
index aec4517..bfe934d 100644 (file)
@@ -31,7 +31,7 @@ import java.util.List;
 import java.util.Map;
 import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
 import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
 import org.onap.cps.ncmp.api.models.YangResource;
 import org.onap.cps.spi.model.ModuleReference;
 import org.onap.cps.utils.JsonObjectMapper;
@@ -50,7 +50,7 @@ public class DmiModelOperations extends DmiOperations {
      *
      * @param dmiRestClient {@code DmiRestClient}
      */
-    public DmiModelOperations(final PersistenceCmHandleRetriever dmiPropertiesRetriever,
+    public DmiModelOperations(final YangModelCmHandleRetriever dmiPropertiesRetriever,
                               final JsonObjectMapper jsonObjectMapper,
                               final NcmpConfiguration.DmiProperties dmiProperties,
                               final DmiRestClient dmiRestClient) {
@@ -60,34 +60,34 @@ public class DmiModelOperations extends DmiOperations {
     /**
      * Retrieves module references.
      *
-     * @param persistenceCmHandle the persistence cm handle
+     * @param yangModelCmHandle the yang model cm handle
      * @return module references
      */
-    public List<ModuleReference> getModuleReferences(final PersistenceCmHandle persistenceCmHandle) {
+    public List<ModuleReference> getModuleReferences(final YangModelCmHandle yangModelCmHandle) {
         final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
             .build();
-        dmiRequestBody.asDmiProperties(persistenceCmHandle.getDmiProperties());
+        dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties());
         final ResponseEntity<Object> dmiFetchModulesResponseEntity = getResourceFromDmiWithJsonData(
-            persistenceCmHandle.resolveDmiServiceName(MODEL),
-                jsonObjectMapper.asJsonString(dmiRequestBody), persistenceCmHandle.getId(), "modules");
+            yangModelCmHandle.resolveDmiServiceName(MODEL),
+                jsonObjectMapper.asJsonString(dmiRequestBody), yangModelCmHandle.getId(), "modules");
         return toModuleReferences((Map) dmiFetchModulesResponseEntity.getBody());
     }
 
     /**
      * Retrieve yang resources from dmi for any modules that CPS-NCMP hasn't cached before.
      *
-     * @param persistenceCmHandle the persistenceCmHandle
+     * @param yangModelCmHandle the yangModelCmHandle
      * @param newModuleReferences the unknown module references
      * @return yang resources as map of module name to yang(re)source
      */
-    public Map<String, String> getNewYangResourcesFromDmi(final PersistenceCmHandle persistenceCmHandle,
+    public Map<String, String> getNewYangResourcesFromDmi(final YangModelCmHandle yangModelCmHandle,
                                                           final Collection<ModuleReference> newModuleReferences) {
         final String jsonWithDataAndDmiProperties = getRequestBodyToFetchYangResources(
-            newModuleReferences, persistenceCmHandle.getDmiProperties());
+            newModuleReferences, yangModelCmHandle.getDmiProperties());
         final ResponseEntity<Object> responseEntity = getResourceFromDmiWithJsonData(
-            persistenceCmHandle.resolveDmiServiceName(MODEL),
+            yangModelCmHandle.resolveDmiServiceName(MODEL),
             jsonWithDataAndDmiProperties,
-            persistenceCmHandle.getId(),
+            yangModelCmHandle.getId(),
             "moduleResources");
         return asModuleNameToYangResourceMap(responseEntity);
     }
@@ -110,7 +110,7 @@ public class DmiModelOperations extends DmiOperations {
     }
 
     private static String getRequestBodyToFetchYangResources(final Collection<ModuleReference> newModuleReferences,
-        final List<PersistenceCmHandle.Property> dmiProperties) {
+        final List<YangModelCmHandle.Property> dmiProperties) {
         final JsonArray moduleReferencesAsJson = getModuleReferencesAsJson(newModuleReferences);
         final JsonObject data = new JsonObject();
         data.add("modules", moduleReferencesAsJson);
@@ -132,10 +132,10 @@ public class DmiModelOperations extends DmiOperations {
         return moduleReferences;
     }
 
-    private static JsonObject toJsonObject(final List<PersistenceCmHandle.Property>
+    private static JsonObject toJsonObject(final List<YangModelCmHandle.Property>
                                                dmiProperties) {
         final JsonObject asJsonObject = new JsonObject();
-        for (final PersistenceCmHandle.Property additionalProperty : dmiProperties) {
+        for (final YangModelCmHandle.Property additionalProperty : dmiProperties) {
             asJsonObject.addProperty(additionalProperty.getName(), additionalProperty.getValue());
         }
         return asJsonObject;
index 2f7376e..645d979 100644 (file)
@@ -46,7 +46,7 @@ public class DmiOperations {
         }
     }
 
-    protected final PersistenceCmHandleRetriever cmHandlePropertiesRetriever;
+    protected final YangModelCmHandleRetriever yangModelCmHandleRetriever;
     protected final JsonObjectMapper jsonObjectMapper;
     protected final NcmpConfiguration.DmiProperties dmiProperties;
     protected final DmiRestClient dmiRestClient;
index 1066eac..d97e90c 100644 (file)
@@ -28,7 +28,7 @@ import java.util.List;
 import java.util.Map;
 import lombok.Builder;
 import lombok.Getter;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @Getter
@@ -60,14 +60,14 @@ public class DmiRequestBody {
     private Map<String, String> dmiProperties;
 
     /**
-     * Set DMI Properties by converting a list of PersistenceCmHandle.Property objects.
+     * Set DMI Properties by converting a list of YangModelCmHandle.Property objects.
      *
-     * @param dmiPropertiesAsList list of cm handle dmi properties
+     * @param yangModelCmHandleProperties list of cm handle dmi properties
      */
     public void asDmiProperties(
-        final List<PersistenceCmHandle.Property> dmiPropertiesAsList) {
+        final List<YangModelCmHandle.Property> yangModelCmHandleProperties) {
         dmiProperties = new LinkedHashMap<>();
-        for (final PersistenceCmHandle.Property dmiProperty : dmiPropertiesAsList) {
+        for (final YangModelCmHandle.Property dmiProperty : yangModelCmHandleProperties) {
             dmiProperties.put(dmiProperty.getName(), dmiProperty.getValue());
         }
     }
@@ -24,39 +24,39 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import lombok.AllArgsConstructor;
 import org.onap.cps.api.CpsDataService;
-import org.onap.cps.ncmp.api.models.CmHandle;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.cps.spi.FetchDescendantsOption;
 import org.onap.cps.spi.model.DataNode;
 import org.springframework.stereotype.Component;
 
 /**
- * Retrieves PersistenceCmHandles & properties.
+ * Retrieves YangModelCmHandles & properties.
  */
 @Component
 @AllArgsConstructor
-public class PersistenceCmHandleRetriever {
+public class YangModelCmHandleRetriever {
 
     private static final String NCMP_DATASPACE_NAME = "NCMP-Admin";
     private static final String NCMP_DMI_REGISTRY_ANCHOR = "ncmp-dmi-registry";
 
-    private final CpsDataService cpsDataService;
+    private CpsDataService cpsDataService;
 
     /**
      * This method retrieves DMI service name and DMI properties for a given cm handle.
      * @param cmHandleId the id of the cm handle
-     * @return persistence cm handle
+     * @return yang model cm handle
      */
-    public PersistenceCmHandle retrieveCmHandleDmiServiceNameAndDmiProperties(final String cmHandleId) {
+    public YangModelCmHandle getDmiServiceNamesAndProperties(final String cmHandleId) {
         final DataNode cmHandleDataNode = getCmHandleDataNode(cmHandleId);
-        final CmHandle cmHandle = new CmHandle();
-        cmHandle.setCmHandleID(cmHandleId);
-        populateCmHandleDmiProperties(cmHandleDataNode, cmHandle);
-        return PersistenceCmHandle.toPersistenceCmHandle(
+        final NcmpServiceCmHandle ncmpServiceCmHandle = new NcmpServiceCmHandle();
+        ncmpServiceCmHandle.setCmHandleID(cmHandleId);
+        populateCmHandleProperties(cmHandleDataNode, ncmpServiceCmHandle);
+        return YangModelCmHandle.toYangModelCmHandle(
             String.valueOf(cmHandleDataNode.getLeaves().get("dmi-service-name")),
             String.valueOf(cmHandleDataNode.getLeaves().get("dmi-data-service-name")),
             String.valueOf(cmHandleDataNode.getLeaves().get("dmi-model-service-name")),
-            cmHandle
+            ncmpServiceCmHandle
         );
     }
 
@@ -68,14 +68,19 @@ public class PersistenceCmHandleRetriever {
             FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
     }
 
-    private static void populateCmHandleDmiProperties(final DataNode cmHandleDataNode, final CmHandle cmHandle) {
+    private static void populateCmHandleProperties(final DataNode cmHandleDataNode,
+                                                   final NcmpServiceCmHandle ncmpServiceCmHandle) {
         final Map<String, String> dmiProperties = new LinkedHashMap<>();
+        final Map<String, String> publicProperties = new LinkedHashMap<>();
         for (final DataNode childDataNode: cmHandleDataNode.getChildDataNodes()) {
             if (childDataNode.getXpath().contains("/additional-properties[@name=")) {
                 addProperty(childDataNode, dmiProperties);
+            } else if (childDataNode.getXpath().contains("/public-properties[@name=")) {
+                addProperty(childDataNode, publicProperties);
             }
         }
-        cmHandle.setDmiProperties(dmiProperties);
+        ncmpServiceCmHandle.setDmiProperties(dmiProperties);
+        ncmpServiceCmHandle.setPublicProperties(publicProperties);
     }
 
     private static void addProperty(final DataNode propertyDataNode, final Map<String, String> propertiesAsMap) {
@@ -19,7 +19,7 @@
  */
 
 
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.impl.yangmodels;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Strings;
@@ -32,14 +32,16 @@ import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
 import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 
 /**
- * DmiRegistry.
+ * Cm Handle which follows the Yang resource dmi registry model when persisting data to DMI or the DB.
+ * Yang model CmHandle
  */
 @Getter
 @Setter
 @NoArgsConstructor
-public class PersistenceCmHandle {
+public class YangModelCmHandle {
 
     private String id;
 
@@ -59,25 +61,26 @@ public class PersistenceCmHandle {
     private List<Property> publicProperties;
 
     /**
-     * Create a persistenceCmHandle.
+     * Create a yangModelCmHandle.
      * @param dmiServiceName dmi service name
      * @param dmiDataServiceName dmi data service name
      * @param dmiModelServiceName dmi model service name
-     * @param cmHandle the cm handle
-     * @return instance of persistenceCmHandle
+     * @param ncmpServiceCmHandle the cm handle
+     * @return instance of yangModelCmHandle
      */
-    public static PersistenceCmHandle toPersistenceCmHandle(final String dmiServiceName,
-                                                            final String dmiDataServiceName,
-                                                            final String dmiModelServiceName,
-                                                            final CmHandle cmHandle) {
-        final PersistenceCmHandle persistenceCmHandle = new PersistenceCmHandle();
-        persistenceCmHandle.setId(cmHandle.getCmHandleID());
-        persistenceCmHandle.setDmiServiceName(dmiServiceName);
-        persistenceCmHandle.setDmiDataServiceName(dmiDataServiceName);
-        persistenceCmHandle.setDmiModelServiceName(dmiModelServiceName);
-        persistenceCmHandle.setDmiProperties(asPersistenceCmHandleProperties(cmHandle.getDmiProperties()));
-        persistenceCmHandle.setPublicProperties(asPersistenceCmHandleProperties(cmHandle.getPublicProperties()));
-        return persistenceCmHandle;
+    public static YangModelCmHandle toYangModelCmHandle(final String dmiServiceName,
+                                                        final String dmiDataServiceName,
+                                                        final String dmiModelServiceName,
+                                                        final NcmpServiceCmHandle ncmpServiceCmHandle) {
+        final YangModelCmHandle yangModelCmHandle = new YangModelCmHandle();
+        yangModelCmHandle.setId(ncmpServiceCmHandle.getCmHandleID());
+        yangModelCmHandle.setDmiServiceName(dmiServiceName);
+        yangModelCmHandle.setDmiDataServiceName(dmiDataServiceName);
+        yangModelCmHandle.setDmiModelServiceName(dmiModelServiceName);
+        yangModelCmHandle.setDmiProperties(asYangModelCmHandleProperties(ncmpServiceCmHandle.getDmiProperties()));
+        yangModelCmHandle.setPublicProperties(asYangModelCmHandleProperties(
+            ncmpServiceCmHandle.getPublicProperties()));
+        return yangModelCmHandle;
     }
 
     /**
@@ -95,12 +98,12 @@ public class PersistenceCmHandle {
         return dmiServiceName;
     }
 
-    private static List<Property> asPersistenceCmHandleProperties(final Map<String, String> propertiesAsMap) {
-        final List<Property> persistenceCmHandleProperties = new ArrayList<>(propertiesAsMap.size());
+    private static List<Property> asYangModelCmHandleProperties(final Map<String, String> propertiesAsMap) {
+        final List<Property> yangModelCmHandleProperties = new ArrayList<>(propertiesAsMap.size());
         for (final Map.Entry<String, String> entry : propertiesAsMap.entrySet()) {
-            persistenceCmHandleProperties.add(new PersistenceCmHandle.Property(entry.getKey(), entry.getValue()));
+            yangModelCmHandleProperties.add(new YangModelCmHandle.Property(entry.getKey(), entry.getValue()));
         }
-        return persistenceCmHandleProperties;
+        return yangModelCmHandleProperties;
     }
 
     private static boolean isNullEmptyOrBlank(final String serviceName) {
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2021 Nordix Foundation
+ *  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.
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.impl.yangmodels;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import lombok.Getter;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 
 @Getter
-public class PersistenceCmHandlesList {
+public class YangModelCmHandlesList {
 
     @JsonProperty("cm-handles")
-    private final List<PersistenceCmHandle> persistenceCmHandles = new ArrayList<>();
+    private final List<YangModelCmHandle> yangModelCmHandles = new ArrayList<>();
 
     /**
-     * Create a PersistenceCmHandleList given all service names and a collection of cmHandles.
+     * Create a YangModelCmHandleList given all service names and a collection of cmHandles.
      * @param dmiServiceName the dmi service name
      * @param dmiDataServiceName the dmi data service name
      * @param dmiModelServiceName the dmi model service name
-     * @param cmHandles cm handles
-     * @return instance of PersistenceCmHandleList
+     * @param ncmpServiceCmHandles cm handles rest model
+     * @return instance of YangModelCmHandleList
      */
-    public static PersistenceCmHandlesList toPersistenceCmHandlesList(final String dmiServiceName,
-                                                                      final String dmiDataServiceName,
-                                                                      final String dmiModelServiceName,
-                                                                      final Collection<CmHandle> cmHandles) {
-        final PersistenceCmHandlesList persistenceCmHandlesList = new PersistenceCmHandlesList();
-        for (final CmHandle cmHandle : cmHandles) {
-            final PersistenceCmHandle persistenceCmHandle =
-                PersistenceCmHandle.toPersistenceCmHandle(
+    public static YangModelCmHandlesList toYangModelCmHandlesList(final String dmiServiceName,
+                                                                  final String dmiDataServiceName,
+                                                                  final String dmiModelServiceName,
+                                                                  final Collection<NcmpServiceCmHandle>
+                                                            ncmpServiceCmHandles) {
+        final YangModelCmHandlesList yangModelCmHandlesList = new YangModelCmHandlesList();
+        for (final NcmpServiceCmHandle ncmpServiceCmHandle : ncmpServiceCmHandles) {
+            final YangModelCmHandle yangModelCmHandle =
+                YangModelCmHandle.toYangModelCmHandle(
                     dmiServiceName,
                     dmiDataServiceName,
                     dmiModelServiceName,
-                    cmHandle);
-            persistenceCmHandlesList.add(persistenceCmHandle);
+                    ncmpServiceCmHandle);
+            yangModelCmHandlesList.add(yangModelCmHandle);
         }
-        return persistenceCmHandlesList;
+        return yangModelCmHandlesList;
     }
 
     /**
-     * Add a persistenceCmHandle.
+     * Add a yangModelCmHandle.
      *
-     * @param persistenceCmHandle the persistenceCmHandle to add
+     * @param yangModelCmHandle the yangModelCmHandle to add
      */
-    public void add(final PersistenceCmHandle persistenceCmHandle) {
-        persistenceCmHandles.add(persistenceCmHandle);
+    public void add(final YangModelCmHandle yangModelCmHandle) {
+        yangModelCmHandles.add(yangModelCmHandle);
     }
 }
index c302f7d..d1360c3 100644 (file)
@@ -44,15 +44,14 @@ public class DmiPluginRegistration {
 
     private String dmiModelPlugin;
 
-    private List<CmHandle> createdCmHandles = Collections.emptyList();
+    private List<NcmpServiceCmHandle> createdCmHandles = Collections.emptyList();
 
-    private List<CmHandle> updatedCmHandles = Collections.emptyList();
+    private List<NcmpServiceCmHandle> updatedCmHandles = Collections.emptyList();
 
     private List<String> removedCmHandles = Collections.emptyList();
 
     /**
      * Validates plugin service names.
-     *
      * @throws NcmpException if validation fails.
      */
     public void validateDmiPluginRegistration() throws NcmpException {
@@ -30,13 +30,14 @@ import lombok.Setter;
 import org.springframework.validation.annotation.Validated;
 
 /**
- * CmHandle.
+ * The NCMP Service model used for the java service API.
+ * NCMP Service CmHandle.
  */
 @Validated
 @Getter
 @Setter
 @NoArgsConstructor
-public class CmHandle {
+public class NcmpServiceCmHandle {
 
     private String cmHandleID;
 
index 3f82f5e..553ac72 100644 (file)
@@ -24,8 +24,9 @@ import org.onap.cps.api.CpsAdminService
 import org.onap.cps.api.CpsModuleService
 import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
 import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
-import org.onap.cps.ncmp.api.models.CmHandle
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle
+import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
 import org.onap.cps.spi.model.ModuleReference
 import org.onap.cps.utils.JsonObjectMapper
 import spock.lang.Specification
@@ -38,34 +39,35 @@ class NetworkCmProxyDataServiceImplModelSyncSpec extends Specification {
     def mockCpsAdminService = Mock(CpsAdminService)
     def mockDmiModelOperations = Mock(DmiModelOperations)
     def mockDmiDataOperations = Mock(DmiDataOperations)
+    def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever)
     def nullNetworkCmProxyDataServicePropertyHandler = null
 
     def objectUnderTest = new NetworkCmProxyDataServiceImpl(nullCpsDataService, mockJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
-        mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler)
+            mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler,mockYangModelCmHandleRetriever)
 
     def expectedDataspaceName = 'NFP-Operational'
 
     def 'Sync model for a (new) cm handle with #scenario'() {
-        given: 'persistence cm handle is given'
-            def cmHandle = new CmHandle()
+        given: 'a cm handle'
+            def ncmpServiceCmHandle = new NcmpServiceCmHandle()
             def dmiServiceName = 'some service name'
-            cmHandle.cmHandleID = 'cm handle id 1'
-            def persistenceCmHandle = PersistenceCmHandle.toPersistenceCmHandle(dmiServiceName, '' , '', cmHandle)
+            ncmpServiceCmHandle.cmHandleID = 'cm handle id 1'
+            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '' , '', ncmpServiceCmHandle)
         and: 'DMI operations returns some module references'
             def moduleReferences =  [ new ModuleReference(moduleName:'module1',revision:'1'),
                                                             new ModuleReference(moduleName:'module2',revision:'2') ]
-            mockDmiModelOperations.getModuleReferences(persistenceCmHandle) >> moduleReferences
+            mockDmiModelOperations.getModuleReferences(yangModelCmHandle) >> moduleReferences
         and: 'CPS-Core returns list of existing module resources'
             mockCpsModuleService.getYangResourceModuleReferences(expectedDataspaceName) >> toModuleReference(existingModuleResourcesInCps)
         and: 'DMI-Plugin returns resource(s) for "new" module(s)'
-            mockDmiModelOperations.getNewYangResourcesFromDmi(persistenceCmHandle, [new ModuleReference('module1', '1')]) >> yangResourceToContentMap
+            mockDmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, [new ModuleReference('module1', '1')]) >> yangResourceToContentMap
         when: 'module sync is triggered'
             mockCpsModuleService.identifyNewModuleReferences(moduleReferences) >> toModuleReference(identifiedNewModuleReferences)
-            objectUnderTest.syncModulesAndCreateAnchor(persistenceCmHandle)
+            objectUnderTest.syncModulesAndCreateAnchor(yangModelCmHandle)
         then: 'the CPS module service is called once with the correct parameters'
-            1 * mockCpsModuleService.createSchemaSetFromModules(expectedDataspaceName, persistenceCmHandle.getId(), yangResourceToContentMap, toModuleReference(expectedKnownModules))
+            1 * mockCpsModuleService.createSchemaSetFromModules(expectedDataspaceName, yangModelCmHandle.getId(), yangResourceToContentMap, toModuleReference(expectedKnownModules))
         and: 'admin service create anchor method has been called with correct parameters'
-            1 * mockCpsAdminService.createAnchor(expectedDataspaceName, persistenceCmHandle.getId(), persistenceCmHandle.getId())
+            1 * mockCpsAdminService.createAnchor(expectedDataspaceName, yangModelCmHandle.getId(), yangModelCmHandle.getId())
         where: 'the following parameters are used'
             scenario             | existingModuleResourcesInCps           | identifiedNewModuleReferences | yangResourceToContentMap      || expectedKnownModules
             'one new module'     | [['module2' : '2'], ['module3' : '3']] | [['module1' : '1']]           | [module1: 'some yang source'] || [['module2' : '2']]
index a475f9c..e410463 100644 (file)
@@ -28,8 +28,9 @@ import org.onap.cps.api.CpsModuleService
 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.operations.DmiModelOperations
-import org.onap.cps.ncmp.api.models.CmHandle
+import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
 import org.onap.cps.spi.exceptions.DataNodeNotFoundException
 import org.onap.cps.spi.exceptions.DataValidationException
 import org.onap.cps.utils.JsonObjectMapper
@@ -41,7 +42,7 @@ import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED
 class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
 
     @Shared
-    def persistenceCmHandle = new CmHandle()
+    def ncmpServiceCmHandle = new NcmpServiceCmHandle()
 
     @Shared
     def cmHandlesArray = ['cmHandle001']
@@ -53,16 +54,17 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
     def mockDmiModelOperations = Mock(DmiModelOperations)
     def mockDmiDataOperations = Mock(DmiDataOperations)
     def mockNetworkCmProxyDataServicePropertyHandler = Mock(NetworkCmProxyDataServicePropertyHandler)
+    def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever)
 
     def noTimestamp = null
 
     def 'Register or re-register a DMI Plugin for the given cm-handle(s) with #scenario process.'() {
         given: 'a registration'
             def objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
-            def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server')
-            persistenceCmHandle.cmHandleID = '123'
-            persistenceCmHandle.dmiProperties = [dmiProp1: 'dmiValue1', dmiProp2: 'dmiValue2']
-            persistenceCmHandle.publicProperties = [publicProp1: 'publicValue1', publicProp2: 'publicValue2']
+            def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:'my-server')
+            ncmpServiceCmHandle.cmHandleID = '123'
+            ncmpServiceCmHandle.dmiProperties = [dmiProp1: 'dmiValue1', dmiProp2: 'dmiValue2']
+            ncmpServiceCmHandle.publicProperties = [publicProp1: 'publicValue1', publicProp2: 'publicValue2' ]
             dmiPluginRegistration.createdCmHandles = createdCmHandles
             dmiPluginRegistration.updatedCmHandles = updatedCmHandles
             dmiPluginRegistration.removedCmHandles = removedCmHandles
@@ -81,13 +83,13 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             expectedCallsToDeleteSchemaSetAndListElement * mockCpsModuleService.deleteSchemaSet('NFP-Operational', 'cmHandle001', CASCADE_DELETE_ALLOWED)
         and: 'delete list or list element is invoked with the correct parameters'
             expectedCallsToDeleteSchemaSetAndListElement * mockCpsDataService.deleteListOrListElement('NCMP-Admin',
-                'ncmp-dmi-registry', "/dmi-registry/cm-handles[@id='cmHandle001']", noTimestamp)
+                    'ncmp-dmi-registry', "/dmi-registry/cm-handles[@id='cmHandle001']", noTimestamp)
         where:
             scenario                    | createdCmHandles      | updatedCmHandles      | removedCmHandles || expectedCallsToSaveNode | expectedCallsToDeleteSchemaSetAndListElement | expectedCallsToUpdateCmHandleProperty
-            'create'                    | [persistenceCmHandle] | []                    | []               || 1                       | 0                                            | 0
-            'update'                    | []                    | [persistenceCmHandle] | []               || 0                       | 0                                            | 1
+            'create'                    | [ncmpServiceCmHandle] | []                    | []               || 1                       | 0                                            | 0
+            'update'                    | []                    | [ncmpServiceCmHandle] | []               || 0                       | 0                                            | 1
             'delete'                    | []                    | []                    | cmHandlesArray   || 0                       | 1                                            | 0
-            'create, update and delete' | [persistenceCmHandle] | [persistenceCmHandle] | cmHandlesArray   || 1                       | 1                                            | 1
+            'create, update and delete' | [ncmpServiceCmHandle] | [ncmpServiceCmHandle] | cmHandlesArray   || 1                       | 1                                            | 1
             'no valid data'             | []                    | []                    | []               || 0                       | 0                                            | 0
     }
 
@@ -95,10 +97,10 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
         given: 'a registration without cm-handle properties'
             NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:'my-server')
-            persistenceCmHandle.cmHandleID = '123'
-            persistenceCmHandle.dmiProperties = Collections.emptyMap()
-            persistenceCmHandle.publicProperties = Collections.emptyMap()
-            dmiPluginRegistration.createdCmHandles = [persistenceCmHandle]
+            ncmpServiceCmHandle.cmHandleID = '123'
+            ncmpServiceCmHandle.dmiProperties = Collections.emptyMap()
+            ncmpServiceCmHandle.publicProperties = Collections.emptyMap()
+            dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle]
             def expectedJsonData = '{"cm-handles":[{"id":"123","dmi-service-name":"my-server","dmi-data-service-name":null,"dmi-model-service-name":null,"additional-properties":[],"public-properties":[]}]}'
         when: 'registration is updated'
             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
@@ -111,7 +113,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
         given: 'a registration without cm-handle properties '
             NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:'some-plugin')
-            dmiPluginRegistration.createdCmHandles = [persistenceCmHandle]
+            dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle]
         and: 'an json processing exception occurs'
             spiedJsonObjectMapper.asJsonString(_) >> { throw (new JsonProcessingException('')) }
         when: 'registration is updated and modules are synced'
@@ -151,7 +153,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             def objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:dmiPlugin, dmiModelPlugin:dmiModelPlugin,
                     dmiDataPlugin:dmiDataPlugin)
-            dmiPluginRegistration.createdCmHandles = [persistenceCmHandle]
+            dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle]
         when: 'update registration and sync module is called with correct DMI plugin information'
             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
         then: 'create cm handles registration and sync modules is called with the correct plugin information'
@@ -168,7 +170,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             def objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:dmiPlugin, dmiModelPlugin:dmiModelPlugin,
                     dmiDataPlugin:dmiDataPlugin)
-            dmiPluginRegistration.createdCmHandles = [persistenceCmHandle]
+            dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle]
         when: 'registration is called with incorrect DMI plugin information'
             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
         then: 'a DMI Request Exception is thrown with correct message details'
@@ -194,7 +196,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
         and: 'dmi plugin registration input update request'
             def dmiPluginReg = new DmiPluginRegistration();
             dmiPluginReg.dmiPlugin = 'onap.dmap.plugin';
-            dmiPluginReg.updatedCmHandles = [new CmHandle(cmHandleID: 'unknownHandle')]
+            dmiPluginReg.updatedCmHandles = [new NcmpServiceCmHandle(cmHandleID: 'unknownHandle')]
         and: 'update data node leaves is unable to find data node'
             mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(*_) >> { throw new DataNodeNotFoundException('NCMP-Admin', 'ncmp-dmi-registry') }
         when: 'update dmi registration is called'
@@ -206,7 +208,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
 
     def getObjectUnderTestWithModelSyncDisabled() {
         def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
-            mockCpsModuleService, mockCpsAdminService, mockNetworkCmProxyDataServicePropertyHandler))
+                mockCpsModuleService, mockCpsAdminService, mockNetworkCmProxyDataServicePropertyHandler,mockYangModelCmHandleRetriever))
         objectUnderTest.syncModulesAndCreateAnchor(*_) >> null
         return objectUnderTest
     }
index 6d7bdef..b2a3d77 100644 (file)
@@ -22,6 +22,9 @@
 
 package org.onap.cps.ncmp.api.impl
 
+import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+
 import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL
 import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING
 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE
@@ -52,9 +55,10 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
     def mockDmiModelOperations = Mock(DmiModelOperations)
     def mockDmiDataOperations = Mock(DmiDataOperations)
     def nullNetworkCmProxyDataServicePropertyHandler = null
+    def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever)
 
     def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
-        mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler)
+        mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler, mockYangModelCmHandleRetriever)
 
     def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
 
@@ -210,6 +214,22 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
             1 * mockCpsAdminService.queryAnchorNames('NFP-Operational', ['some-module-name'])
     }
 
+    def 'Get a cm handle.'() {
+        given: 'the system returns a yang modelled cm handle'
+            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.getDmiServiceNamesAndProperties('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')
+        then: 'the result returns the correct data'
+            result.cmHandleID == 'Some-Cm-Handle'
+            result.dmiProperties ==[ Book:'Romance Novel' ]
+            result.publicProperties == [ "Public Book":'Public Romance Novel' ]
+
+    }
+
     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',
index 5bdb744..9b8d4ad 100644 (file)
@@ -21,7 +21,7 @@
 package org.onap.cps.ncmp.api.impl
 
 import org.onap.cps.api.CpsDataService
-import org.onap.cps.ncmp.api.models.CmHandle
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
 import org.onap.cps.spi.FetchDescendantsOption
 import org.onap.cps.spi.exceptions.DataNodeNotFoundException
 import org.onap.cps.spi.exceptions.DataValidationException
@@ -50,7 +50,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification {
         given: 'the CPS service return a CM handle'
             mockCpsDataService.getDataNode(dataspaceName, anchorName, cmHandleXpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
         and: 'an update cm handle request with public properties updates'
-            def cmHandleUpdateRequest = [new CmHandle(cmHandleID: cmHandleId, publicProperties: updatedPublicProperties)]
+            def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: updatedPublicProperties)]
         when: 'update data node leaves is called with the update request'
             objectUnderTest.updateCmHandleProperties(cmHandleUpdateRequest)
         then: 'the replace list method is called with correct params'
@@ -72,7 +72,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification {
         given: 'the CPS service return a CM handle'
             mockCpsDataService.getDataNode(dataspaceName, anchorName, cmHandleXpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
         and: 'an update cm handle request with DMI properties updates'
-            def cmHandleUpdateRequest = [new CmHandle(cmHandleID: cmHandleId, dmiProperties: updatedDmiProperties)]
+            def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, dmiProperties: updatedDmiProperties)]
         when: 'update data node leaves is called with the update request'
             objectUnderTest.updateCmHandleProperties(cmHandleUpdateRequest)
         then: 'replace list method should is called with correct params'
@@ -96,7 +96,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification {
             def cmHandleDataNode = new DataNode(xpath: cmHandleXpath, childDataNodes: originalPropertyDataNodes)
             mockCpsDataService.getDataNode(dataspaceName, anchorName, cmHandleXpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
         and: 'an update cm handle request that removes all public properties(existing and non-existing)'
-            def cmHandleUpdateRequest = [new CmHandle(cmHandleID: cmHandleId, publicProperties: ['publicProp3': null, 'publicProp4': null])]
+            def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: ['publicProp3': null, 'publicProp4': null])]
         when: 'update data node leaves is called with the update request'
             objectUnderTest.updateCmHandleProperties(cmHandleUpdateRequest)
         then: 'the replace list method is not called'
@@ -115,7 +115,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification {
 
     def 'Exception thrown when we try to update cmHandle'() {
         given: 'cm handles request'
-            def cmHandleUpdateRequest = [new CmHandle(cmHandleID: cmHandleId, publicProperties: [:], dmiProperties: [:])]
+            def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: [:], dmiProperties: [:])]
         and: 'data node cannot be found'
             mockCpsDataService.getDataNode(*_) >> { throw new DataNodeNotFoundException(dataspaceName, anchorName, cmHandleXpath) }
         when: 'update data node leaves is called using correct parameters'
index 7873f39..e585825 100644 (file)
@@ -46,8 +46,8 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
     DmiDataOperations objectUnderTest
 
     def 'call get resource data for #expectedDatastoreInUrl from DMI #scenario.'() {
-        given: 'a persistence cm handle for #cmHandleId'
-            mockPersistenceCmHandleRetrieval(dmiProperties)
+        given: 'a cm handle for #cmHandleId'
+            mockYangModelCmHandleRetrieval(dmiProperties)
         and: 'a positive response from DMI service when it is called with the expected parameters'
             def responseFromDmi = new ResponseEntity<Object>(HttpStatus.OK)
             mockDmiRestClient.postOperationWithJsonData(
@@ -60,15 +60,15 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
         where: 'the following parameters are used'
             scenario             | dmiProperties        | dataStore               | options     || expectedJson                                                 | expectedDatastoreInUrl    | expectedOptionsInUrl
             'without properties' | []                   | PASSTHROUGH_OPERATIONAL | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{}}'               | 'passthrough-operational' | '&options=(a=1,b=2)'
-            'with properties'    | [dmiSampleProperty]  | PASSTHROUGH_OPERATIONAL | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | '&options=(a=1,b=2)'
-            'null options'       | [dmiSampleProperty]  | PASSTHROUGH_OPERATIONAL | null        || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | ''
-            'empty options'      | [dmiSampleProperty]  | PASSTHROUGH_OPERATIONAL | ''          || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | ''
+            'with properties'    | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | '&options=(a=1,b=2)'
+            'null options'       | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | null        || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | ''
+            'empty options'      | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | ''          || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | ''
             'datastore running'  | []                   | PASSTHROUGH_RUNNING     | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{}}'               | 'passthrough-running'     | '&options=(a=1,b=2)'
     }
 
     def 'Write data for pass-through:running datastore in DMI.'() {
-        given: 'a persistence cm handle for #cmHandleId'
-            mockPersistenceCmHandleRetrieval([dmiSampleProperty])
+        given: 'a cm handle for #cmHandleId'
+            mockYangModelCmHandleRetrieval([yangModelCmHandleProperty])
         and: 'a positive response from DMI service when it is called with the expected parameters'
             def expectedUrl = "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/data/ds" +
                 "/ncmp-datastore:passthrough-running?resourceIdentifier=${resourceIdentifier}"
index bd5fe6f..cd2cb71 100644 (file)
@@ -47,28 +47,28 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
     JsonObjectMapper spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
 
     def 'Retrieving module references.'() {
-        given: 'a persistence cm handle'
-            mockPersistenceCmHandleRetrieval([])
+        given: 'a cm handle'
+            mockYangModelCmHandleRetrieval([])
         and: 'a positive response from DMI service when it is called with the expected parameters'
             def moduleReferencesAsLisOfMaps = [[moduleName:'mod1',revision:'A'],[moduleName:'mod2',revision:'X']]
             def responseFromDmi = new ResponseEntity([schemas:moduleReferencesAsLisOfMaps], HttpStatus.OK)
             mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/modules",
                 '{"cmHandleProperties":{}}', [:]) >> responseFromDmi
         when: 'get module references is called'
-            def result = objectUnderTest.getModuleReferences(persistenceCmHandle)
+            def result = objectUnderTest.getModuleReferences(yangModelCmHandle)
         then: 'the result consists of expected module references'
             assert result == [new ModuleReference(moduleName:'mod1',revision:'A'), new ModuleReference(moduleName:'mod2',revision:'X')]
     }
 
     def 'Retrieving module references edge case: #scenario.'() {
-        given: 'a persistence cm handle'
-            mockPersistenceCmHandleRetrieval([])
+        given: 'a cm handle'
+            mockYangModelCmHandleRetrieval([])
         and: 'any response from DMI service when it is called with the expected parameters'
             // TODO (toine): production code ignores any error code from DMI, this should be improved in future
             def responseFromDmi = new ResponseEntity(bodyAsMap, HttpStatus.NO_CONTENT)
             mockDmiRestClient.postOperationWithJsonData(*_) >> responseFromDmi
         when: 'get module references is called'
-            def result = objectUnderTest.getModuleReferences(persistenceCmHandle)
+            def result = objectUnderTest.getModuleReferences(yangModelCmHandle)
         then: 'the result is empty'
             assert result == []
         where: 'the DMI response body has the following content'
@@ -80,25 +80,25 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
     }
 
     def 'Retrieving module references, DMI property handling:  #scenario.'() {
-        given: 'a persistence cm handle'
-            mockPersistenceCmHandleRetrieval(dmiProperties)
+        given: 'a cm handle'
+            mockYangModelCmHandleRetrieval(dmiProperties)
         and: 'a positive response from DMI service when it is called with tha expected parameters'
             def responseFromDmi = new ResponseEntity<String>(HttpStatus.OK)
             mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/modules",
                 '{"cmHandleProperties":' + expectedAdditionalPropertiesInRequest + '}', [:]) >> responseFromDmi
         when: 'a get module references is called'
-            def result = objectUnderTest.getModuleReferences(persistenceCmHandle)
+            def result = objectUnderTest.getModuleReferences(yangModelCmHandle)
         then: 'the result is the response from DMI service'
             assert result == []
         where: 'the following DMI properties are used'
             scenario               | dmiProperties       || expectedAdditionalPropertiesInRequest
-            'with properties'      | [dmiSampleProperty] || '{"prop1":"val1"}'
+            'with properties'      | [yangModelCmHandleProperty] || '{"prop1":"val1"}'
             'without properties'   | []                  || '{}'
     }
 
     def 'Retrieving yang resources.'() {
-        given: 'a persistence cm handle'
-            mockPersistenceCmHandleRetrieval([])
+        given: 'a cm handle'
+            mockYangModelCmHandleRetrieval([])
         and: 'a positive response from DMI service when it is called with the expected parameters'
             def responseFromDmi = new ResponseEntity([[moduleName: 'mod1', revision: 'A', yangSource: 'some yang source'],
                                                       [moduleName: 'mod2', revision: 'C', yangSource: 'other yang source']], HttpStatus.OK)
@@ -106,7 +106,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
             mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources",
                 '{"data":{"modules":[' + expectedModuleReferencesInRequest + ']},"cmHandleProperties":{}}', [:]) >> responseFromDmi
         when: 'get new yang resources from DMI service'
-            def result = objectUnderTest.getNewYangResourcesFromDmi(persistenceCmHandle, newModuleReferences)
+            def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences)
         then: 'the result has the 2 expected yang (re)sources (order is not guaranteed)'
             assert result.size() == 2
             assert result.get('mod1') == 'some yang source'
@@ -114,14 +114,14 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
     }
 
     def 'Retrieving yang resources, edge case: scenario.'() {
-        given: 'a persistence cm handle'
-            mockPersistenceCmHandleRetrieval([])
+        given: 'a cm handle'
+            mockYangModelCmHandleRetrieval([])
         and: 'a positive response from DMI service when it is called with tha expected parameters'
             // TODO (toine): production code ignores any error code from DMI, this should be improved in future
             def responseFromDmi = new ResponseEntity(responseFromDmiBody, HttpStatus.NO_CONTENT)
             mockDmiRestClient.postOperationWithJsonData(*_) >> responseFromDmi
         when: 'get new yang resources from DMI service'
-            def result = objectUnderTest.getNewYangResourcesFromDmi(persistenceCmHandle, newModuleReferences)
+            def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences)
         then: 'the result is empty'
             assert result == [:]
         where: 'the DMI response body has the following content'
@@ -131,40 +131,40 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
     }
 
     def 'Retrieving yang resources, DMI property handling #scenario.'() {
-        given: 'a persistence cm handle'
-            mockPersistenceCmHandleRetrieval(dmiProperties)
+        given: 'a cm handle'
+            mockYangModelCmHandleRetrieval(dmiProperties)
         and: 'a positive response from DMI service when it is called with the expected parameters'
             def responseFromDmi = new ResponseEntity<>([[moduleName: 'mod1', revision: 'A', yangSource: 'some yang source']], HttpStatus.OK)
             mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources",
             '{"data":{"modules":[' + expectedModuleReferencesInRequest + ']},"cmHandleProperties":'+expectedAdditionalPropertiesInRequest+'}',
             [:]) >> responseFromDmi
         when: 'get new yang resources from DMI service'
-            def result = objectUnderTest.getNewYangResourcesFromDmi(persistenceCmHandle, unknownModuleReferences)
+            def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, unknownModuleReferences)
         then: 'the result is the response from DMI service'
             assert result == [mod1:'some yang source']
         where: 'the following DMI properties are used'
             scenario                                | dmiProperties       | unknownModuleReferences || expectedAdditionalPropertiesInRequest | expectedModuleReferencesInRequest
-            'with module references and properties' | [dmiSampleProperty] | newModuleReferences     || '{"prop1":"val1"}'                    | '{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}'
-            'without module references'             | [dmiSampleProperty] | []                      || '{"prop1":"val1"}'                    | ''
+            'with module references and properties' | [yangModelCmHandleProperty] | newModuleReferences || '{"prop1":"val1"}' | '{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}'
+            'without module references'             | [yangModelCmHandleProperty] | []                  || '{"prop1":"val1"}' | ''
             'without properties'                    | []                  | newModuleReferences     || '{}'                                  | '{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}'
     }
 
     def 'Retrieving yang resources from DMI with null DMI properties.'() {
-        given: 'a persistence cm handle'
-            mockPersistenceCmHandleRetrieval(null)
+        given: 'a cm handle'
+            mockYangModelCmHandleRetrieval(null)
         when: 'a get new yang resources from DMI is called'
-            objectUnderTest.getNewYangResourcesFromDmi(persistenceCmHandle, [])
+            objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, [])
         then: 'a null pointer is thrown (we might need to address this later)'
             thrown(NullPointerException)
     }
 
     def 'Retrieving module references with Json processing exception.'() {
-        given: 'a persistence cm handle'
-            mockPersistenceCmHandleRetrieval([])
+        given: 'a cm handle'
+            mockYangModelCmHandleRetrieval([])
         and: 'a Json processing exception occurs'
             spiedJsonObjectMapper.asJsonString(_) >> {throw (new JsonProcessingException('parsing error'))}
         when: 'a DMI operation is executed'
-            objectUnderTest.getModuleReferences(persistenceCmHandle)
+            objectUnderTest.getModuleReferences(yangModelCmHandle)
         then: 'an ncmp exception is thrown'
             def exceptionThrown = thrown(JsonProcessingException)
         and: 'the message indicates a parsing error'
index 7b295f6..dd0d64d 100644 (file)
@@ -22,7 +22,7 @@ package org.onap.cps.ncmp.api.impl.operations
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import org.onap.cps.ncmp.api.impl.client.DmiRestClient
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
 import org.spockframework.spring.SpringBean
 import spock.lang.Shared
 import spock.lang.Specification
@@ -30,27 +30,27 @@ import spock.lang.Specification
 abstract class DmiOperationsBaseSpec extends Specification {
 
     @Shared
-    def dmiSampleProperty = new PersistenceCmHandle.Property('prop1', 'val1')
+    def yangModelCmHandleProperty = new YangModelCmHandle.Property('prop1', 'val1')
 
     @SpringBean
     DmiRestClient mockDmiRestClient = Mock()
 
     @SpringBean
-    PersistenceCmHandleRetriever mockCmHandlePropertiesRetriever = Mock()
+    YangModelCmHandleRetriever mockCmHandlePropertiesRetriever = Mock()
 
     @SpringBean
     ObjectMapper spyObjectMapper = Spy()
 
-    def persistenceCmHandle = new PersistenceCmHandle()
+    def yangModelCmHandle = new YangModelCmHandle()
     def static dmiServiceName = 'some service name'
     def static cmHandleId = 'some cm handle'
     def static resourceIdentifier = 'parent/child'
 
-    def mockPersistenceCmHandleRetrieval(dmiProperties) {
-        persistenceCmHandle.dmiDataServiceName = dmiServiceName
-        persistenceCmHandle.dmiServiceName = dmiServiceName
-        persistenceCmHandle.dmiProperties = dmiProperties
-        persistenceCmHandle.id = cmHandleId
-        mockCmHandlePropertiesRetriever.retrieveCmHandleDmiServiceNameAndDmiProperties(cmHandleId) >> persistenceCmHandle
+    def mockYangModelCmHandleRetrieval(dmiProperties) {
+        yangModelCmHandle.dmiDataServiceName = dmiServiceName
+        yangModelCmHandle.dmiServiceName = dmiServiceName
+        yangModelCmHandle.dmiProperties = dmiProperties
+        yangModelCmHandle.id = cmHandleId
+        mockCmHandlePropertiesRetriever.getDmiServiceNamesAndProperties(cmHandleId) >> yangModelCmHandle
     }
 }
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetrieverSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetrieverSpec.groovy
deleted file mode 100644 (file)
index c92234f..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- *  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.
- *  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.operations
-
-import org.onap.cps.api.CpsDataService
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle
-import spock.lang.Shared
-
-import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
-import org.onap.cps.spi.model.DataNode
-import spock.lang.Specification
-
-class PersistenceCmHandleRetrieverSpec extends Specification {
-
-    def mockCpsDataService = Mock(CpsDataService)
-
-    def objectUnderTest = new PersistenceCmHandleRetriever(mockCpsDataService)
-
-    def cmHandleId = 'some cm handle'
-    def leaves = ["dmi-service-name":"common service name","dmi-data-service-name":"data service name","dmi-model-service-name":"model service name"]
-    def xpath = "/dmi-registry/cm-handles[@id='some cm handle']"
-
-    @Shared
-    def childDataNodesForCmHandleProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/additional-properties[@name='name1']", leaves: ["name":"name1","value":"value1"]),
-                                               new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/public-properties[@name='name2']", leaves: ["name":"name2","value":"value2"])]
-
-    def "Retrieve CmHandle using datanode #scenario."() {
-        given: 'the cps data service returns a data node from the DMI registry'
-            def dataNode = new DataNode(childDataNodes:childDataNodes, leaves: leaves)
-            mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', xpath, INCLUDE_ALL_DESCENDANTS) >> dataNode
-        when: 'retrieving the persisted cm handle'
-            def result = objectUnderTest.retrieveCmHandleDmiServiceNameAndDmiProperties(cmHandleId)
-        then: 'the result has the correct id and service names'
-            result.id == cmHandleId
-            result.dmiServiceName == 'common service name'
-            result.dmiDataServiceName == 'data service name'
-            result.dmiModelServiceName == 'model service name'
-        and: 'the expected DMI properties'
-            result.dmiProperties == expectedCmHandleProperties
-        where: 'the following parameters are used'
-            scenario                 | childDataNodes                      || expectedCmHandleProperties
-            'without DMI properties' | []                                  || []
-            'with DMI properties'    | childDataNodesForCmHandleProperties || [new PersistenceCmHandle.Property("name1", "value1")]
-    }
-}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy
new file mode 100644 (file)
index 0000000..593a6ec
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  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.
+ *  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.operations
+
+import org.onap.cps.api.CpsDataService
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+import spock.lang.Shared
+
+import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
+import org.onap.cps.spi.model.DataNode
+import spock.lang.Specification
+
+class YangModelCmHandleRetrieverSpec extends Specification {
+
+    def mockCpsDataService = Mock(CpsDataService)
+
+    def objectUnderTest = new YangModelCmHandleRetriever(mockCpsDataService)
+
+    def cmHandleId = 'some cm handle'
+    def leaves = ["dmi-service-name":"common service name","dmi-data-service-name":"data service name","dmi-model-service-name":"model service name"]
+    def xpath = "/dmi-registry/cm-handles[@id='some cm handle']"
+
+    @Shared
+    def childDataNodesForCmHandleWithAllProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/additional-properties[@name='name1']", leaves: ["name":"name1", "value":"value1"]),
+                                                      new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/public-properties[@name='name2']", leaves: ["name":"name2","value":"value2"])]
+
+    @Shared
+    def childDataNodesForCmHandleWithDMIProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/additional-properties[@name='name1']", leaves: ["name":"name1", "value":"value1"])]
+
+    @Shared
+    def childDataNodesForCmHandleWithPublicProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/public-properties[@name='name2']", leaves: ["name":"name2","value":"value2"])]
+
+    def "Retrieve CmHandle using datanode with #scenario."() {
+        given: 'the cps data service returns a data node from the DMI registry'
+            def dataNode = new DataNode(childDataNodes:childDataNodes, leaves: leaves)
+            mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', xpath, INCLUDE_ALL_DESCENDANTS) >> dataNode
+        when: 'retrieving the yang modelled cm handle'
+            def result = objectUnderTest.getDmiServiceNamesAndProperties(cmHandleId)
+        then: 'the result has the correct id and service names'
+            result.id == cmHandleId
+            result.dmiServiceName == 'common service name'
+            result.dmiDataServiceName == 'data service name'
+            result.dmiModelServiceName == 'model service name'
+        and: 'the expected DMI properties'
+            result.dmiProperties == expectedDmiProperties
+            result.publicProperties == expectedPublicProperties
+        where: 'the following parameters are used'
+            scenario                    | childDataNodes                                || expectedDmiProperties                               || expectedPublicProperties
+            'no properties'             | []                                            || []                                                  || []
+            'DMI and public properties' | childDataNodesForCmHandleWithAllProperties    || [new YangModelCmHandle.Property("name1", "value1")] || [new YangModelCmHandle.Property("name2", "value2")]
+            'just DMI properties'       | childDataNodesForCmHandleWithDMIProperties    || [new YangModelCmHandle.Property("name1", "value1")] || []
+            'just public properties'    | childDataNodesForCmHandleWithPublicProperties || []                                                  || [new YangModelCmHandle.Property("name2", "value2")]
+    }
+}
 
 package org.onap.cps.ncmp.api.models
 
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
 import spock.lang.Specification
 
 import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.DATA
 import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.MODEL
 
-class PersistenceCmHandleSpec extends Specification {
+class YangModelCmHandleSpec extends Specification {
 
-    def 'Creating persistence cm handle from a cm handle.'() {
+    def 'Creating yang model cm handle from a service api cm handle.'() {
         given: 'a cm handle with properties'
-            def cmHandle = new CmHandle()
-            cmHandle.dmiProperties = [myDmiProperty:'value1']
-            cmHandle.publicProperties = [myPublicProperty:'value2']
-        when: 'it is converted to a persistence cm handle'
-            def objectUnderTest = PersistenceCmHandle.toPersistenceCmHandle('','','', cmHandle)
+            def ncmpServiceCmHandle = new NcmpServiceCmHandle()
+            ncmpServiceCmHandle.dmiProperties = [myDmiProperty:'value1']
+            ncmpServiceCmHandle.publicProperties = [myPublicProperty:'value2']
+        when: 'it is converted to a yang model cm handle'
+            def objectUnderTest = YangModelCmHandle.toYangModelCmHandle('','','', ncmpServiceCmHandle)
         then: 'the result has the right size'
             assert objectUnderTest.dmiProperties.size() == 1
         and: 'the DMI property in the result has the correct name and value'
@@ -45,8 +46,8 @@ class PersistenceCmHandleSpec extends Specification {
     }
 
     def 'Resolve DMI service name: #scenario and #requiredService service require.'() {
-        given: 'a Persistence CM Handle'
-            def objectUnderTest = PersistenceCmHandle.toPersistenceCmHandle(dmiServiceName, dmiDataServiceName, dmiModelServiceName, new CmHandle())
+        given: 'a yang model cm handle'
+            def objectUnderTest = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, dmiDataServiceName, dmiModelServiceName, new NcmpServiceCmHandle())
         expect:
             assert objectUnderTest.resolveDmiServiceName(requiredService) == expectedService
         where:
index ceb5dc1..9495b3d 100755 (executable)
@@ -63,30 +63,25 @@ public class CpsRestExceptionHandler {
     }
 
     @ExceptionHandler({ModelValidationException.class, DataValidationException.class, CpsAdminException.class,
-        CpsPathException.class})
-    public static ResponseEntity<Object> handleBadRequestExceptions(final CpsException exception) {
+        CpsPathException.class, ValidationException.class})
+    public static ResponseEntity<Object> handleBadRequestExceptions(final Exception exception) {
         return buildErrorResponse(HttpStatus.BAD_REQUEST, exception);
     }
 
-    @ExceptionHandler({ValidationException.class})
-    public static ResponseEntity<Object> handleBadRequestExceptions(final ValidationException validationException) {
-        return buildErrorResponse(HttpStatus.BAD_REQUEST, validationException);
-    }
-
     @ExceptionHandler({NotFoundInDataspaceException.class, DataNodeNotFoundException.class})
-    public static ResponseEntity<Object> handleNotFoundExceptions(final CpsException exception,
+    public static ResponseEntity<Object> handleNotFoundExceptions(final Exception exception,
         final HttpServletRequest request) {
         return buildErrorResponse(HttpMethod.GET.matches(request.getMethod())
             ? HttpStatus.NOT_FOUND : HttpStatus.BAD_REQUEST, exception);
     }
 
     @ExceptionHandler({DataInUseException.class, AlreadyDefinedException.class})
-    public static ResponseEntity<Object> handleDataInUseException(final CpsException exception) {
+    public static ResponseEntity<Object> handleDataInUseException(final Exception exception) {
         return buildErrorResponse(HttpStatus.CONFLICT, exception);
     }
 
     @ExceptionHandler({CpsException.class})
-    public static ResponseEntity<Object> handleAnyOtherCpsExceptions(final CpsException exception) {
+    public static ResponseEntity<Object> handleAnyOtherCpsExceptions(final Exception exception) {
         return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
     }
 
index 5021f77..dfad948 100644 (file)
@@ -34,15 +34,48 @@ ${auth}                   Basic Y3BzdXNlcjpjcHNyMGNrcyE=
 ${ncmpInventoryBasePath}  /ncmpInventory
 ${ncmpBasePath}           /ncmp
 ${dmiUrl}                 http://${DMI_HOST}:${DMI_PORT}
-${jsonData}               {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","createdCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Sci-Fi Book"},"publicCmHandleProperties":{"Contact":"storeemail@bookstore.com"}}],"updatedCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Romance Book"},"publicCmHandleProperties":{"Contact":"newemailforstore@bookstore.com"}}]}
+${jsonDataCreate}         {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","createdCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Sci-Fi Book"},"publicCmHandleProperties":{"Contact":"storeemail@bookstore.com"}}]}
+${jsonDataUpdate}         {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","updatedCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Romance Book"},"publicCmHandleProperties":{"Contact":"newemailforstore@bookstore.com"}}]}
 
 *** Test Cases ***
-Register node, update data node and sync modules.
+Register data node and sync modules.
     ${uri}=              Set Variable       ${ncmpInventoryBasePath}/v1/ch
     ${headers}=          Create Dictionary  Content-Type=application/json   Authorization=${auth}
-    ${response}=         POST On Session    CPS_URL   ${uri}   headers=${headers}   data=${jsonData}
+    ${response}=         POST On Session    CPS_URL   ${uri}   headers=${headers}   data=${jsonDataCreate}
     Should Be Equal As Strings              ${response.status_code}   204
 
+Get CM Handle details and confirm it has been registered.
+    ${uri}=              Set Variable       ${ncmpBasePath}/v1/ch/PNFDemo
+    ${headers}=          Create Dictionary  Authorization=${auth}
+    ${response}=         GET On Session     CPS_URL   ${uri}   headers=${headers}
+    ${responseJson}=     Set Variable       ${response.json()}
+    ${schemaCount}=      Get length         ${responseJson}
+    Should Be Equal As Strings              ${response.status_code}   200
+    IF    "${responseJson['cmHandle']}" == "PNFDemo"
+           FOR   ${item}   IN  @{responseJson['publicCmHandleProperties']}
+                   Should Be Equal As Strings              "${item['Contact']}"  "storeemail@bookstore.com"
+           END
+    END
+
+Update data node and sync modules.
+    ${uri}=              Set Variable       ${ncmpInventoryBasePath}/v1/ch
+    ${headers}=          Create Dictionary  Content-Type=application/json   Authorization=${auth}
+    ${response}=         POST On Session    CPS_URL   ${uri}   headers=${headers}   data=${jsonDataUpdate}
+    Should Be Equal As Strings              ${response.status_code}   204
+
+Get CM Handle details and confirm it has been updated.
+    ${uri}=              Set Variable       ${ncmpBasePath}/v1/ch/PNFDemo
+    ${headers}=          Create Dictionary  Authorization=${auth}
+    ${response}=         GET On Session     CPS_URL   ${uri}   headers=${headers}
+    ${responseJson}=     Set Variable       ${response.json()}
+    ${schemaCount}=      Get length         ${responseJson}
+    Should Be Equal As Strings              ${response.status_code}   200
+    IF    "${responseJson['cmHandle']}" == "PNFDemo"
+           FOR   ${item}   IN  @{responseJson['publicCmHandleProperties']}
+                   Should Be Equal As Strings              "${item['Contact']}"  "newemailforstore@bookstore.com"
+           END
+    END
+
 Get modules for registered data node
     ${uri}=              Set Variable       ${ncmpBasePath}/v1/ch/PNFDemo/modules
     ${headers}=          Create Dictionary  Authorization=${auth}
index 34a087b..154a441 100644 (file)
@@ -53,6 +53,16 @@ paths:
                 status: 403
                 message: Forbidden error message
                 details: Forbidden error details
+        "500":
+          description: Internal Server Error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 500
+                message: Internal Server Error
+                details: Internal Server Error occurred
 components:
   schemas:
     RestDmiPluginRegistration:
@@ -61,26 +71,39 @@ components:
         dmiPlugin:
           type: string
           example: my-dmi-plugin
+          default: ""
         dmiDataPlugin:
           type: string
           example: my-dmi-data-plugin
+          default: ""
         dmiModelPlugin:
           type: string
           example: my-dmi-model-plugin
+          default: ""
         createdCmHandles:
           type: array
           items:
-            $ref: '#/components/schemas/RestCmHandle'
+            $ref: '#/components/schemas/RestInputCmHandle'
         updatedCmHandles:
           type: array
+          example:
+            cmHandle: my-cm-handle
+            cmHandleProperties:
+              add-my-property: add-property
+              update-my-property: updated-property
+              delete-my-property: ~
+            publicCmHandleProperties:
+              add-my-property: add-property
+              update-my-property: updated-property
+              delete-my-property: ~
           items:
-            $ref: '#/components/schemas/RestCmHandle'
+            $ref: '#/components/schemas/RestInputCmHandle'
         removedCmHandles:
           type: array
           items:
             type: string
             example: "[\"my-cm-handle1\",\"my-cm-handle2\",\"my-cm-handle3\"]"
-    RestCmHandle:
+    RestInputCmHandle:
       required:
       - cmHandle
       type: object
index a3b9dc7..b7a6563 100644 (file)
@@ -4,73 +4,72 @@ info:
   description: NCMP to CPS Proxy API
   version: "1.0"
 servers:
-  - url: /ncmp
+- url: /ncmp
 paths:
   /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-operational:
     get:
       tags:
-        - network-cm-proxy
+      - network-cm-proxy
       summary: Get resource data from pass-through operational for cm handle
       description: Get resource data from pass-through operational for given cm handle
       operationId: getResourceDataOperationalForCmHandle
       parameters:
-        - name: cm-handle
-          in: path
-          description: "The identifier for a network function, network element, subnetwork\
+      - name: cm-handle
+        in: path
+        description: "The identifier for a network function, network element, subnetwork\
           \ or any other cm object by managed Network CM Proxy"
-          required: true
-          schema:
-            type: string
-        - name: resourceIdentifier
-          in: query
-          description: The format of resource identifier depend on the associated DMI
-            Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
-            it can really be anything.
-          required: true
-          allowReserved: true
-          schema:
-            type: string
-          examples:
-            sample1:
-              value:
-                resourceIdentifier: \parent\child
-            sample2:
-              value:
-                resourceIdentifier: "\\parent\\listElement[key=value]"
-            sample3:
-              value:
-                resourceIdentifier: "\\parent\\listElement[key=value]\\grandChild"
-            sample4:
-              value:
-                resourceIdentifier: "parent=1,child=abc"
-        - name: Accept
-          in: header
-          description: "Accept parameter for response, if accept parameter is null,\
+        required: true
+        schema:
+          type: string
+          example: my-cm-handle
+      - name: resourceIdentifier
+        in: query
+        description: The format of resource identifier depend on the associated DMI
+          Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+          it can really be anything.
+        required: true
+        allowReserved: true
+        schema:
+          type: string
+        examples:
+          sample 1:
+            value:
+              resourceIdentifier: \shops\bookstore
+          sample 2:
+            value:
+              resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+          sample 3:
+            value:
+              resourceIdentifier: "parent=shops,child=bookstore"
+      - name: Accept
+        in: header
+        description: "Accept parameter for response, if accept parameter is null,\
           \ that means client can accept any format."
-          required: false
-          schema:
-            type: string
-            enum:
-              - application/json
-              - application/yang-data+json
-        - name: options
-          in: query
-          description: "options parameter in query, it is mandatory to wrap key(s)=value(s)\
-          \ in parenthesis'()'."
-          required: false
-          allowReserved: true
-          schema:
-            type: string
-          examples:
-            sample1:
-              value:
-                options: "(key1=value1,key2=value2)"
-            sample2:
-              value:
-                options: "(key1=value1,key2=value1/value2)"
-            sample3:
-              value:
-                options: "(key1=10,key2=value2,key3=[val31;val32])"
+        required: false
+        schema:
+          type: string
+          enum:
+          - application/json
+          - application/yang-data+json
+      - name: options
+        in: query
+        description: "options parameter in query, it is mandatory to wrap key(s)=value(s)\
+          \ in parenthesis'()'. The format of options parameter depend on the associated\
+          \ DMI Plugin implementation."
+        required: false
+        allowReserved: true
+        schema:
+          type: string
+        examples:
+          sample 1:
+            value:
+              options: (depth=3)
+          sample 2:
+            value:
+              options: (fields=book)
+          sample 3:
+            value:
+              options: "(depth=2,fields=book/authors)"
       responses:
         "200":
           description: OK
@@ -78,95 +77,113 @@ paths:
             application/json:
               schema:
                 type: object
+              examples:
+                dataSampleResponse:
+                  $ref: '#/components/examples/dataSampleResponse'
         "400":
           description: Bad Request
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400 BAD_REQUEST
+                message: Bad request error message
+                details: Bad request error details
         "401":
           description: Unauthorized
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 401
+                message: Unauthorized error message
+                details: Unauthorized error details
         "403":
           description: Forbidden
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
-        "404":
-          description: The specified resource was not found
+              example:
+                status: 403
+                message: Forbidden error message
+                details: Forbidden error details
+        "500":
+          description: Internal Server Error
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 500
+                message: Internal Server Error
+                details: Internal Server Error occurred
   /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-running:
     get:
       tags:
-        - network-cm-proxy
+      - network-cm-proxy
       summary: Get resource data from pass-through running for cm handle
       description: Get resource data from pass-through running for given cm handle
       operationId: getResourceDataRunningForCmHandle
       parameters:
-        - name: cm-handle
-          in: path
-          description: "The identifier for a network function, network element, subnetwork\
+      - name: cm-handle
+        in: path
+        description: "The identifier for a network function, network element, subnetwork\
           \ or any other cm object by managed Network CM Proxy"
-          required: true
-          schema:
-            type: string
-        - name: resourceIdentifier
-          in: query
-          description: The format of resource identifier depend on the associated DMI
-            Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
-            it can really be anything.
-          required: true
-          allowReserved: true
-          schema:
-            type: string
-          examples:
-            sample1:
-              value:
-                resourceIdentifier: \parent\child
-            sample2:
-              value:
-                resourceIdentifier: "\\parent\\listElement[key=value]"
-            sample3:
-              value:
-                resourceIdentifier: "\\parent\\listElement[key=value]\\grandChild"
-            sample4:
-              value:
-                resourceIdentifier: "parent=1,child=abc"
-        - name: Accept
-          in: header
-          description: "Accept parameter for response, if accept parameter is null,\
+        required: true
+        schema:
+          type: string
+          example: my-cm-handle
+      - name: resourceIdentifier
+        in: query
+        description: The format of resource identifier depend on the associated DMI
+          Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+          it can really be anything.
+        required: true
+        allowReserved: true
+        schema:
+          type: string
+        examples:
+          sample 1:
+            value:
+              resourceIdentifier: \shops\bookstore
+          sample 2:
+            value:
+              resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+          sample 3:
+            value:
+              resourceIdentifier: "parent=shops,child=bookstore"
+      - name: Accept
+        in: header
+        description: "Accept parameter for response, if accept parameter is null,\
           \ that means client can accept any format."
-          required: false
-          schema:
-            type: string
-            enum:
-              - application/json
-              - application/yang-data+json
-        - name: options
-          in: query
-          description: "options parameter in query, it is mandatory to wrap key(s)=value(s)\
-          \ in parenthesis'()'."
-          required: false
-          allowReserved: true
-          schema:
-            type: string
-          examples:
-            sample1:
-              value:
-                options: "(key1=value1,key2=value2)"
-            sample2:
-              value:
-                options: "(key1=value1,key2=value1/value2)"
-            sample3:
-              value:
-                options: "(key1=10,key2=value2,key3=[val31;val32])"
+        required: false
+        schema:
+          type: string
+          enum:
+          - application/json
+          - application/yang-data+json
+      - name: options
+        in: query
+        description: "options parameter in query, it is mandatory to wrap key(s)=value(s)\
+          \ in parenthesis'()'. The format of options parameter depend on the associated\
+          \ DMI Plugin implementation."
+        required: false
+        allowReserved: true
+        schema:
+          type: string
+        examples:
+          sample 1:
+            value:
+              options: (depth=3)
+          sample 2:
+            value:
+              options: (fields=book)
+          sample 3:
+            value:
+              options: "(depth=2,fields=book/authors)"
       responses:
         "200":
           description: OK
@@ -174,82 +191,212 @@ paths:
             application/json:
               schema:
                 type: object
+              examples:
+                dataSampleResponse:
+                  $ref: '#/components/examples/dataSampleResponse'
         "400":
           description: Bad Request
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400 BAD_REQUEST
+                message: Bad request error message
+                details: Bad request error details
         "401":
           description: Unauthorized
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 401
+                message: Unauthorized error message
+                details: Unauthorized error details
         "403":
           description: Forbidden
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
-        "404":
-          description: The specified resource was not found
+              example:
+                status: 403
+                message: Forbidden error message
+                details: Forbidden error details
+        "500":
+          description: Internal Server Error
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 500
+                message: Internal Server Error
+                details: Internal Server Error occurred
+    put:
+      tags:
+      - network-cm-proxy
+      summary: Update resource data from pass-through running for a cm handle
+      description: Update resource data from pass-through running for the given cm
+        handle
+      operationId: updateResourceDataRunningForCmHandle
+      parameters:
+      - name: cm-handle
+        in: path
+        description: "The identifier for a network function, network element, subnetwork\
+          \ or any other cm object by managed Network CM Proxy"
+        required: true
+        schema:
+          type: string
+          example: my-cm-handle
+      - name: resourceIdentifier
+        in: query
+        description: The format of resource identifier depend on the associated DMI
+          Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+          it can really be anything.
+        required: true
+        allowReserved: true
+        schema:
+          type: string
+        examples:
+          sample 1:
+            value:
+              resourceIdentifier: \shops\bookstore
+          sample 2:
+            value:
+              resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+          sample 3:
+            value:
+              resourceIdentifier: "parent=shops,child=bookstore"
+      - name: Content-Type
+        in: header
+        description: "Content parameter for request, if content parameter is null,\
+          \ default value is application/json."
+        required: false
+        schema:
+          type: string
+          example: application/yang-data+json
+          default: application/json
+      requestBody:
+        content:
+          application/json:
+            schema:
+              type: object
+            examples:
+              dataSampleRequest:
+                $ref: '#/components/examples/dataSampleRequest'
+          application/yang-data+json:
+            schema:
+              type: object
+            examples:
+              dataSampleRequest:
+                $ref: '#/components/examples/dataSampleRequest'
+        required: true
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                type: object
+        "400":
+          description: Bad Request
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400 BAD_REQUEST
+                message: Bad request error message
+                details: Bad request error details
+        "401":
+          description: Unauthorized
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 401
+                message: Unauthorized error message
+                details: Unauthorized error details
+        "403":
+          description: Forbidden
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 403
+                message: Forbidden error message
+                details: Forbidden error details
+        "500":
+          description: Internal Server Error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 500
+                message: Internal Server Error
+                details: Internal Server Error occurred
     post:
       tags:
-        - network-cm-proxy
+      - network-cm-proxy
       summary: create resource data from pass-through running for cm handle
       description: create resource data from pass-through running for given cm handle
       operationId: createResourceDataRunningForCmHandle
       parameters:
-        - name: cm-handle
-          in: path
-          description: "The identifier for a network function, network element, subnetwork\
+      - name: cm-handle
+        in: path
+        description: "The identifier for a network function, network element, subnetwork\
           \ or any other cm object by managed Network CM Proxy"
-          required: true
-          schema:
-            type: string
-        - name: resourceIdentifier
-          in: query
-          description: The format of resource identifier depend on the associated DMI
-            Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
-            it can really be anything.
-          required: true
-          allowReserved: true
-          schema:
-            type: string
-          examples:
-            sample1:
-              value:
-                resourceIdentifier: \parent\child
-            sample2:
-              value:
-                resourceIdentifier: "\\parent\\listElement[key=value]"
-            sample3:
-              value:
-                resourceIdentifier: "\\parent\\listElement[key=value]\\grandChild"
-            sample4:
-              value:
-                resourceIdentifier: "parent=1,child=abc"
-        - name: Content-Type
-          in: header
-          description: "Content parameter for request, if content parameter is null,\
+        required: true
+        schema:
+          type: string
+          example: my-cm-handle
+      - name: resourceIdentifier
+        in: query
+        description: The format of resource identifier depend on the associated DMI
+          Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+          it can really be anything.
+        required: true
+        allowReserved: true
+        schema:
+          type: string
+        examples:
+          sample 1:
+            value:
+              resourceIdentifier: \shops\bookstore
+          sample 2:
+            value:
+              resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+          sample 3:
+            value:
+              resourceIdentifier: "parent=shops,child=bookstore"
+      - name: Content-Type
+        in: header
+        description: "Content parameter for request, if content parameter is null,\
           \ default value is application/json."
-          required: false
-          schema:
-            type: string
-            default: application/json
+        required: false
+        schema:
+          type: string
+          example: application/yang-data+json
+          default: application/json
       requestBody:
         content:
           application/json:
             schema:
-              type: string
+              type: object
+            examples:
+              dataSampleRequest:
+                $ref: '#/components/examples/dataSampleRequest'
           application/yang-data+json:
             schema:
-              type: string
+              type: object
+            examples:
+              dataSampleRequest:
+                $ref: '#/components/examples/dataSampleRequest'
         required: true
       responses:
         "201":
@@ -261,71 +408,437 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400 BAD_REQUEST
+                message: Bad request error message
+                details: Bad request error details
+        "401":
+          description: Unauthorized
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 401
+                message: Unauthorized error message
+                details: Unauthorized error details
+        "403":
+          description: Forbidden
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 403
+                message: Forbidden error message
+                details: Forbidden error details
+        "500":
+          description: Internal Server Error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 500
+                message: Internal Server Error
+                details: Internal Server Error occurred
+    delete:
+      tags:
+      - network-cm-proxy
+      summary: Delete resource data
+      description: Delete resource data from pass-through running for a given cm handle
+      operationId: deleteResourceDataRunningForCmHandle
+      parameters:
+      - name: cm-handle
+        in: path
+        description: "The identifier for a network function, network element, subnetwork\
+          \ or any other cm object by managed Network CM Proxy"
+        required: true
+        schema:
+          type: string
+          example: my-cm-handle
+      - name: resourceIdentifier
+        in: query
+        description: The format of resource identifier depend on the associated DMI
+          Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+          it can really be anything.
+        required: true
+        allowReserved: true
+        schema:
+          type: string
+        examples:
+          sample 1:
+            value:
+              resourceIdentifier: \shops\bookstore
+          sample 2:
+            value:
+              resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+          sample 3:
+            value:
+              resourceIdentifier: "parent=shops,child=bookstore"
+      - name: Content-Type
+        in: header
+        description: "Content parameter for request, if content parameter is null,\
+          \ default value is application/json."
+        required: false
+        schema:
+          type: string
+          example: application/yang-data+json
+          default: application/json
+      responses:
+        "204":
+          description: No Content
+          content: {}
+        "400":
+          description: Bad Request
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400 BAD_REQUEST
+                message: Bad request error message
+                details: Bad request error details
         "401":
           description: Unauthorized
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 401
+                message: Unauthorized error message
+                details: Unauthorized error details
         "403":
           description: Forbidden
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 403
+                message: Forbidden error message
+                details: Forbidden error details
         "404":
           description: The specified resource was not found
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400
+                message: Not found error message
+                details: Not found error details
+        "500":
+          description: Internal Server Error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 500
+                message: Internal Server Error
+                details: Internal Server Error occurred
+    patch:
+      tags:
+      - network-cm-proxy
+      summary: Patch resource data from pass-through running
+      description: Patch resource data from pass-through running for the given cm
+        handle
+      operationId: patchResourceDataRunningForCmHandle
+      parameters:
+      - name: cm-handle
+        in: path
+        description: "The identifier for a network function, network element, subnetwork\
+          \ or any other cm object by managed Network CM Proxy"
+        required: true
+        schema:
+          type: string
+          example: my-cm-handle
+      - name: resourceIdentifier
+        in: query
+        description: The format of resource identifier depend on the associated DMI
+          Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+          it can really be anything.
+        required: true
+        allowReserved: true
+        schema:
+          type: string
+        examples:
+          sample 1:
+            value:
+              resourceIdentifier: \shops\bookstore
+          sample 2:
+            value:
+              resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+          sample 3:
+            value:
+              resourceIdentifier: "parent=shops,child=bookstore"
+      - name: Content-Type
+        in: header
+        description: "Content parameter for request, if content parameter is null,\
+          \ default value is application/json."
+        required: false
+        schema:
+          type: string
+          example: application/yang-data+json
+          default: application/json
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              type: object
+            examples:
+              dataSampleRequest:
+                $ref: '#/components/examples/dataSamplePatchRequest'
+        required: true
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                type: object
+        "400":
+          description: Bad Request
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400 BAD_REQUEST
+                message: Bad request error message
+                details: Bad request error details
+        "401":
+          description: Unauthorized
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 401
+                message: Unauthorized error message
+                details: Unauthorized error details
+        "403":
+          description: Forbidden
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 403
+                message: Forbidden error message
+                details: Forbidden error details
+        "500":
+          description: Internal Server Error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 500
+                message: Internal Server Error
+                details: Internal Server Error occurred
   /v1/ch/{cm-handle}/modules:
     get:
       tags:
-        - network-cm-proxy
+      - network-cm-proxy
       summary: Fetch all module references (name and revision) for a given cm handle
       description: fetch all module references (name and revision) for a given cm
         handle
       operationId: getModuleReferencesByCmHandle
       parameters:
-        - name: cm-handle
-          in: path
-          description: "The identifier for a network function, network element, subnetwork\
+      - name: cm-handle
+        in: path
+        description: "The identifier for a network function, network element, subnetwork\
           \ or any other cm object by managed Network CM Proxy"
-          required: true
-          schema:
-            type: string
+        required: true
+        schema:
+          type: string
+          example: my-cm-handle
       responses:
         "200":
           description: OK
           content:
             application/json:
               schema:
-                type: object
+                type: array
+                items:
+                  $ref: '#/components/schemas/ModuleReference'
+        "400":
+          description: Bad Request
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400 BAD_REQUEST
+                message: Bad request error message
+                details: Bad request error details
+        "401":
+          description: Unauthorized
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 401
+                message: Unauthorized error message
+                details: Unauthorized error details
+        "403":
+          description: Forbidden
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 403
+                message: Forbidden error message
+                details: Forbidden error details
+        "500":
+          description: Internal Server Error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 500
+                message: Internal Server Error
+                details: Internal Server Error occurred
+  /v1/ch/searches:
+    post:
+      tags:
+      - network-cm-proxy
+      summary: Execute cm handle search using the available conditions
+      description: Execute cm handle searches using 'hasAllModules' condition to get
+        all cm handles for the given module names
+      operationId: executeCmHandleSearch
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/Conditions'
+        required: true
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/CmHandles'
+        "400":
+          description: Bad Request
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400 BAD_REQUEST
+                message: Bad request error message
+                details: Bad request error details
+        "401":
+          description: Unauthorized
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 401
+                message: Unauthorized error message
+                details: Unauthorized error details
+        "403":
+          description: Forbidden
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 403
+                message: Forbidden error message
+                details: Forbidden error details
+        "500":
+          description: Internal Server Error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 500
+                message: Internal Server Error
+                details: Internal Server Error occurred
+  /v1/ch/{cm-handle}:
+    get:
+      tags:
+      - network-cm-proxy
+      summary: Retrieve CM handle details
+      description: Retrieve CM handle details and properties by cm handle id
+      operationId: retrieveCmHandleDetailsById
+      parameters:
+      - name: cm-handle
+        in: path
+        description: "The identifier for a network function, network element, subnetwork\
+          \ or any other cm object by managed Network CM Proxy"
+        required: true
+        schema:
+          type: string
+          example: my-cm-handle
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/RestOutputCmHandle'
         "400":
           description: Bad Request
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400 BAD_REQUEST
+                message: Bad request error message
+                details: Bad request error details
         "401":
           description: Unauthorized
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 401
+                message: Unauthorized error message
+                details: Unauthorized error details
         "403":
           description: Forbidden
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 403
+                message: Forbidden error message
+                details: Forbidden error details
         "404":
           description: The specified resource was not found
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 400
+                message: Not found error message
+                details: Not found error details
+        "500":
+          description: Internal Server Error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorMessage'
+              example:
+                status: 500
+                message: Internal Server Error
+                details: Internal Server Error occurred
 components:
   schemas:
     ErrorMessage:
@@ -338,3 +851,147 @@ components:
           type: string
         details:
           type: string
+    ModuleReference:
+      title: Module reference details
+      type: object
+      properties:
+        moduleName:
+          type: string
+          example: my-module-name
+        revision:
+          type: string
+          example: my-module-revision
+    Conditions:
+      type: object
+      properties:
+        conditions:
+          $ref: '#/components/schemas/ConditionsData'
+    ConditionsData:
+      type: array
+      items:
+        $ref: '#/components/schemas/ConditionProperties'
+    ConditionProperties:
+      properties:
+        name:
+          type: string
+          example: hasAllModules
+        conditionParameters:
+          $ref: '#/components/schemas/ModuleNamesAsJsonArray'
+    ModuleNamesAsJsonArray:
+      type: array
+      items:
+        $ref: '#/components/schemas/ModuleNameAsJsonObject'
+    ModuleNameAsJsonObject:
+      properties:
+        moduleName:
+          type: string
+          example: my-module
+    CmHandles:
+      type: object
+      properties:
+        cmHandles:
+          $ref: '#/components/schemas/CmHandleProperties'
+    CmHandleProperties:
+      type: array
+      items:
+        $ref: '#/components/schemas/CmHandleProperty'
+    CmHandleProperty:
+      properties:
+        cmHandleId:
+          type: string
+          example: my-cm-handle-id
+    RestOutputCmHandle:
+      title: CM handle Details
+      type: object
+      properties:
+        cmHandle:
+          type: string
+          example: my-cm-handle1
+        publicCmHandleProperties:
+          $ref: '#/components/schemas/CmHandlePublicProperties'
+    CmHandlePublicProperties:
+      type: array
+      items:
+        type: object
+        additionalProperties:
+          type: string
+          example: Book Type
+  examples:
+    dataSampleResponse:
+      summary: Sample response
+      description: Sample response for selecting 'sample 1'.
+      value:
+        bookstore:
+          categories:
+          - code: "01"
+            books:
+            - authors:
+              - Iain M. Banks
+              - Ursula K. Le Guin
+            name: SciFi
+          - code: "02"
+            books:
+            - authors:
+              - Philip Pullman
+            name: kids
+    dataSampleRequest:
+      summary: Sample request
+      description: Sample request body
+      value:
+        test:bookstore:
+          bookstore-name: Chapters
+          categories:
+          - code: "01"
+            name: SciFi
+            books:
+            - authors:
+              - Iain M. Banks
+              - Ursula K. Le Guin
+          - code: "02"
+            name: kids
+            books:
+            - authors:
+              - Philip Pullman
+    dataSamplePatchRequest:
+      summary: Sample patch request
+      description: Sample patch request body
+      value:
+        ietf-restconf:yang-patch:
+          patch-id: patch-1
+          edit:
+          - edit-id: edit1
+            operation: merge
+            target: /
+            value:
+              test:bookstore:
+                bookstore-name: Chapters
+                categories:
+                - code: "01"
+                  name: Science
+                  books:
+                  - authors:
+                    - Author1
+                    - Author2
+                - code: "02"
+                  name: Arts
+                  books:
+                  - authors:
+                    - Author3
+          - edit-id: edit2
+            operation: merge
+            target: /
+            value:
+              test:bookstore:
+                bookstore-name: Novels
+                categories:
+                - code: "03"
+                  name: History
+                  books:
+                  - authors:
+                    - Iain M. Banks
+                    - Ursula K. Le Guin
+                - code: "04"
+                  name: Fiction
+                  books:
+                  - authors:
+                    - Philip Pullman
index ff8a988..0ca0547 100755 (executable)
@@ -29,9 +29,11 @@ Features
    - `CPS-559 <https://jira.onap.org/browse/CPS-559>`_  Define response objects (schemas) in cps-ncmp
    - `CPS-636 <https://jira.onap.org/browse/CPS-636>`_  Update operation for datastore pass through running
    - `CPS-638 <https://jira.onap.org/browse/CPS-638>`_  Delete operation for datastore pass through running
+   - `CPS-677 <https://jira.onap.org/browse/CPS-677>`_  Support 'public' Cm Handle Properties
    - `CPS-741 <https://jira.onap.org/browse/CPS-741>`_  Re sync after removing cm handles
    - `CPS-777 <https://jira.onap.org/browse/CPS-777>`_  Ensure all DMI operations use POST method
    - `CPS-780 <https://jira.onap.org/browse/CPS-780>`_  Add examples for parameters, request and response in openapi yaml for cps-core
+   - `CPS-817 <https://jira.onap.org/browse/CPS-817>`_  Create Endpoint For Get Cm Handles (incl. public properties) By Name
    - `CPS-837 <https://jira.onap.org/browse/CPS-837>`_  Add Remove and Update properties (DMI and Public) as part of CM Handle Registration update
 
 Bug Fixes
@@ -43,15 +45,19 @@ Bug Fixes
    - `CPS-841 <https://jira.onap.org/browse/CPS-841>`_ Upgrade log4j to 2.17.1 as recommended by ONAP SECCOM
    - `CPS-856 <https://jira.onap.org/browse/CPS-856>`_ Retry mechanism not working for concurrent CmHandle registration
    - `CPS-867 <https://jira.onap.org/browse/CPS-867>`_ Database port made configurable through env variable DB_PORT
+   - `CPS-886 <https://jira.onap.org/browse/CPS-886>`_ Fragment handling decreasing performance for large number of cmHandles
    - `CPS-887 <https://jira.onap.org/browse/CPS-887>`_ Increase performance of cmHandle registration for large number of schema sets in DB
    - `CPS-892 <https://jira.onap.org/browse/CPS-892>`_ Fixed the response code during CM-Handle Registration from 201 CREATED to 204 NO_CONTENT
+   - `CPS-893 <https://jira.onap.org/browse/CPS-893>`_ NCMP Java API depends on NCM-Rest-API (cyclic) through json properties on Java API
 
 Known Limitations, Issues and Workarounds
 -----------------------------------------
 
 *System Limitations*
 
-None
+Null can no longer be passed within the dmi plugin service names when registering a cm handle, as part of
+`CPS-837 <https://jira.onap.org/browse/CPS-837>`_ null is now used to indicate if a property should be removed as part
+of cm handle registration.
 
 *Known Vulnerabilities*
 
@@ -59,7 +65,8 @@ None
 
 *Workarounds*
 
-None
+Instead of passing null as a value within the dmi plugin service names, remove them from the request completely, or
+pass an empty string as the value if you do not want to include names for these values.
 
 Security Notes
 --------------