Post impl for passthrough running (Ncmp impl.) 16/123416/8
authortragait <rahul.tyagi@est.tech>
Fri, 20 Aug 2021 14:45:58 +0000 (15:45 +0100)
committertragait <rahul.tyagi@est.tech>
Thu, 26 Aug 2021 11:50:30 +0000 (12:50 +0100)
Issue-ID: CPS-577
Signed-off-by: tragait <rahul.tyagi@est.tech>
Change-Id: Ic8983349cf88fb123feb95ce01ec6fdf670469f4

13 files changed:
cps-application/src/test/java/org/onap/cps/architecture/LayeredArchitectureTest.java
cps-ncmp-rest/docs/openapi/components.yaml
cps-ncmp-rest/docs/openapi/ncmproxy.yml
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
cps-ncmp-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/client/DmiRestClient.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java
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/client/DmiRestClientSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy

index 4228c0b..bc5ad18 100644 (file)
@@ -41,6 +41,7 @@ public class LayeredArchitectureTest {
     private static final String NCMP_SERVICE_PACKAGE = "org.onap.cps.ncmp.api..";
     private static final String SPI_REPOSITORY_PACKAGE = "org.onap.cps.spi.repository..";
     private static final String YANG_SCHEMA_PACKAGE = "org.onap.cps.yang..";
+    private static final String NOTIFICATION_PACKAGE = "org.onap.cps.notification..";
 
     @ArchTest
     static final ArchRule restControllerShouldOnlyDependOnRestController =
@@ -52,7 +53,7 @@ public class LayeredArchitectureTest {
         freeze(classes().that().resideInAPackage(API_SERVICE_PACKAGE)
             .or().resideInAPackage(SPI_SERVICE_PACKAGE).should().onlyHaveDependentClassesThat()
             .resideInAnyPackage(REST_CONTROLLER_PACKAGE, API_SERVICE_PACKAGE, SPI_SERVICE_PACKAGE, NCMP_REST_PACKAGE,
-                NCMP_SERVICE_PACKAGE, YANG_SCHEMA_PACKAGE));
+                NCMP_SERVICE_PACKAGE, YANG_SCHEMA_PACKAGE, NOTIFICATION_PACKAGE));
 
     @ArchTest
     static final ArchRule repositoryShouldOnlyBeDependedOnByServicesAndRepository =
index ca1c6ab..ffb8dde 100644 (file)
@@ -112,7 +112,7 @@ components:
       schema:
         type: string
     acceptParamInHeader:
-      name: accept
+      name: Accept
       in: header
       required: false
       description: Accept parameter for response, if accept parameter is null, that means client can accept any format.
@@ -134,6 +134,14 @@ components:
       schema:
         type: integer
         minimum: 1
+    contentParamInHeader:
+      name: Content-Type
+      in: header
+      required: false
+      description: Content parameter for request, if content parameter is null, default value is application/json.
+      schema:
+        type: string
+        default: application/json
 
 
   responses:
index b2e14d7..8eed9b3 100755 (executable)
@@ -249,5 +249,35 @@ resourceDataForPassthroughRunning:
         $ref: 'components.yaml#/components/responses/Unauthorized'
       403:
         $ref: 'components.yaml#/components/responses/Forbidden'
+      404:
+        $ref: 'components.yaml#/components/responses/NotFound'
+  post:
+    tags:
+      - 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:
+      - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
+      - $ref: 'components.yaml#/components/parameters/resourceIdentifierInPath'
+      - $ref: 'components.yaml#/components/parameters/contentParamInHeader'
+    requestBody:
+      required: true
+      content:
+        application/json:
+          schema:
+            type: object
+        application/yang-data+json:
+          schema:
+            type: object
+    responses:
+      201:
+        $ref: 'components.yaml#/components/responses/Created'
+      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'
\ No newline at end of file
index 587787e..d4e842a 100755 (executable)
@@ -200,6 +200,26 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
         return ResponseEntity.ok(responseObject);
     }
 
+    /**
+     * Create resource data in datastore pass through running
+     * for given cm-handle.
+     *
+     * @param cmHandle cm handle identifier
+     * @param resourceIdentifier resource identifier
+     * @param requestBody requestBody
+     * @param contentType content type of body
+     * @return {@code ResponseEntity} response from dmi plugi
+     */
+    @Override
+    public ResponseEntity<Void> createResourceDataRunningForCmHandle(final String cmHandle,
+                                                                     final String resourceIdentifier,
+                                                                     final Object requestBody,
+                                                                     final String contentType) {
+        networkCmProxyDataService.createResourceDataPassThroughRunningForCmHandle(cmHandle,
+                resourceIdentifier, requestBody, contentType);
+        return new ResponseEntity<>(HttpStatus.CREATED);
+    }
+
     private DmiPluginRegistration convertRestObjectToJavaApiObject(
         final RestDmiPluginRegistration restDmiPluginRegistration) {
         return objectMapper.convertValue(restDmiPluginRegistration, DmiPluginRegistration.class);
index a7fa309..1a2d3a2 100644 (file)
@@ -237,5 +237,22 @@ class NetworkCmProxyControllerSpec extends Specification {
         and: 'response contains valid object body'
             response.getContentAsString() == '{valid-json}'
     }
+
+    def 'Create Resource Data from pass-through running using POST.' () {
+        given: 'resource data url'
+            def getUrl = "$basePath/v1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
+                    "/testResourceIdentifier"
+        when: 'get data resource request is performed'
+            def response = mvc.perform(
+                    post(getUrl)
+                            .contentType(MediaType.APPLICATION_JSON_VALUE)
+                            .accept(MediaType.APPLICATION_JSON_VALUE).content('{"some-json":"value"}')
+            ).andReturn().response
+        then: 'ncmp service method to create resource called'
+            1 * mockNetworkCmProxyDataService.createResourceDataPassThroughRunningForCmHandle('testCmHandle',
+                    'testResourceIdentifier', ['some-json':'value'], 'application/json;charset=UTF-8')
+        and: 'resource is created'
+            response.status == HttpStatus.CREATED.value()
+    }
 }
 
index 3e715e5..03d70c1 100644 (file)
@@ -130,14 +130,28 @@ public interface NetworkCmProxyDataService {
      *
      * @param cmHandle cm handle
      * @param resourceIdentifier resource identifier
-     * @param accept accept param
+     * @param acceptParam accept param
      * @param fields fields query
      * @param depth depth query
      * @return {@code Object} resource data
      */
     Object getResourceDataPassThroughRunningForCmHandle(@NotNull String cmHandle,
                                                         @NotNull String resourceIdentifier,
-                                                        String accept,
+                                                        String acceptParam,
                                                         String fields,
                                                         Integer depth);
+
+    /**
+     * Create resource data for data store pass-through running
+     * using dmi for given cm-handle.
+     *
+     * @param cmHandle cm handle
+     * @param resourceIdentifier resource identifier
+     * @param requestBody request body to create resource
+     * @param contentType content type in body
+     */
+    void createResourceDataPassThroughRunningForCmHandle(@NotNull String cmHandle,
+                                                         @NotNull String resourceIdentifier,
+                                                         @NotNull Object requestBody,
+                                                         String contentType);
 }
index b5a5914..11477ab 100755 (executable)
@@ -53,7 +53,6 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
-
 @Slf4j
 @Service
 public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService {
@@ -66,6 +65,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
 
     private static final OffsetDateTime NO_TIMESTAMP = null;
 
+    private static  final String NCMP_DMI_SERVICE_NAME = "dmi-service-name";
+
     private CpsDataService cpsDataService;
 
     private ObjectMapper objectMapper;
@@ -76,14 +77,13 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
 
     /**
      * Constructor Injection for Dependencies.
-     *
-     * @param dmiOperations   dmi operation
-     * @param cpsDataService  Data Service Interface
+     * @param dmiOperations DMI operation
+     * @param cpsDataService Data Service Interface
      * @param cpsQueryService Query Service Interface
-     * @param objectMapper    Object Mapper
+     * @param objectMapper Object Mapper
      */
     public NetworkCmProxyDataServiceImpl(final DmiOperations dmiOperations, final CpsDataService cpsDataService,
-        final CpsQueryService cpsQueryService, final ObjectMapper objectMapper) {
+                                         final CpsQueryService cpsQueryService, final ObjectMapper objectMapper) {
         this.dmiOperations = dmiOperations;
         this.cpsDataService = cpsDataService;
         this.cpsQueryService = cpsQueryService;
@@ -96,13 +96,13 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
 
     @Override
     public DataNode getDataNode(final String cmHandle, final String xpath,
-        final FetchDescendantsOption fetchDescendantsOption) {
+                                final FetchDescendantsOption fetchDescendantsOption) {
         return cpsDataService.getDataNode(getDataspaceName(), cmHandle, xpath, fetchDescendantsOption);
     }
 
     @Override
     public Collection<DataNode> queryDataNodes(final String cmHandle, final String cpsPath,
-        final FetchDescendantsOption fetchDescendantsOption) {
+                                               final FetchDescendantsOption fetchDescendantsOption) {
         return cpsQueryService.queryDataNodes(getDataspaceName(), cmHandle, cpsPath, fetchDescendantsOption);
     }
 
@@ -143,149 +143,132 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         }
     }
 
-    private void parseAndCreateCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) {
-        try {
-            final List<PersistenceCmHandle> createdPersistenceCmHandles =
-                new LinkedList<>();
-            for (final CmHandle cmHandle : dmiPluginRegistration.getCreatedCmHandles()) {
-                createdPersistenceCmHandles.add(toPersistenceCmHandle(dmiPluginRegistration, cmHandle));
-            }
-            final PersistenceCmHandlesList persistenceCmHandlesList = new PersistenceCmHandlesList();
-            persistenceCmHandlesList.setCmHandles(createdPersistenceCmHandles);
-            final String cmHandleJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList);
-            cpsDataService.saveListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, "/dmi-registry",
-                cmHandleJsonData, NO_TIMESTAMP);
-        } catch (final JsonProcessingException e) {
-            log.error("Parsing error occurred while converting Object to JSON for Dmi Registry.");
-            throw new DataValidationException(
-                "Parsing error occurred while processing DMI Plugin Registration" + dmiPluginRegistration, e
-                .getMessage(), e);
-        }
-    }
-
-    private void parseAndUpdateCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) {
-        try {
-            final List<PersistenceCmHandle> updatedPersistenceCmHandles =
-                new LinkedList<>();
-            for (final CmHandle cmHandle : dmiPluginRegistration.getUpdatedCmHandles()) {
-                updatedPersistenceCmHandles.add(toPersistenceCmHandle(dmiPluginRegistration, cmHandle));
-            }
-            final PersistenceCmHandlesList persistenceCmHandlesList = new PersistenceCmHandlesList();
-            persistenceCmHandlesList.setCmHandles(updatedPersistenceCmHandles);
-            final String cmHandlesJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList);
-            cpsDataService.updateNodeLeavesAndExistingDescendantLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
-                "/dmi-registry", cmHandlesJsonData, NO_TIMESTAMP);
-        } catch (final JsonProcessingException e) {
-            log.error("Parsing error occurred while converting Object to JSON Dmi Registry.");
-            throw new DataValidationException(
-                "Parsing error occurred while processing DMI Plugin Registration" + dmiPluginRegistration, e
-                .getMessage(), e);
-        }
-    }
-
-    private void parseAndRemoveCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) {
-        for (final String cmHandle: dmiPluginRegistration.getRemovedCmHandles()) {
-            try {
-                cpsDataService.deleteListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
-                    "/dmi-registry/cm-handles[@id='" + cmHandle + "']", NO_TIMESTAMP);
-            } catch (final DataNodeNotFoundException e) {
-                log.warn("Datanode {} not deleted message {}", cmHandle, e.getMessage());
-            }
-        }
-    }
-
     @Override
     public Object getResourceDataOperationalForCmHandle(final @NotNull String cmHandle,
-        final @NotNull String resourceIdentifier,
-        final String acceptParam,
-        final String fieldsQueryParam,
-        final Integer depthQueryParam) {
-
-        final var dataNode = fetchDataNodeFromDmiRegistryForCmHandle(cmHandle);
-        final var dmiServiceName = String.valueOf(dataNode.getLeaves().get("dmi-service-name"));
-        final Collection<DataNode> additionalPropsList = dataNode.getChildDataNodes();
-        final var jsonBody = prepareOperationBody(GenericRequestBody.OperationEnum.READ, additionalPropsList);
-        final ResponseEntity<Object> response = dmiOperations.getResouceDataOperationalFromDmi(dmiServiceName,
-            cmHandle,
-            resourceIdentifier,
-            fieldsQueryParam,
-            depthQueryParam,
-            acceptParam,
-            jsonBody);
+                                                        final @NotNull String resourceIdentifier,
+                                                        final String acceptParam,
+                                                        final String fieldsQueryParam,
+                                                        final Integer depthQueryParam) {
+
+        final var cmHandleDataNode = fetchDataNodeFromDmiRegistryForCmHandle(cmHandle);
+        final var dmiServiceName = String.valueOf(cmHandleDataNode.getLeaves().get(NCMP_DMI_SERVICE_NAME));
+        final String dmiRequestBody = getGenericRequestBody(cmHandleDataNode);
+        final ResponseEntity<Object> response = dmiOperations.getResourceDataOperationalFromDmi(dmiServiceName,
+                cmHandle,
+                resourceIdentifier,
+                fieldsQueryParam,
+                depthQueryParam,
+                acceptParam,
+                dmiRequestBody);
         return handleResponse(response);
     }
 
     @Override
     public Object getResourceDataPassThroughRunningForCmHandle(final @NotNull String cmHandle,
-        final @NotNull String resourceIdentifier,
-        final String accept,
-        final String fields,
-        final Integer depth) {
+                                                               final @NotNull String resourceIdentifier,
+                                                               final String acceptParam,
+                                                               final String fields,
+                                                               final Integer depth) {
         final var cmHandleDataNode = fetchDataNodeFromDmiRegistryForCmHandle(cmHandle);
-        final var dmiServiceName = String.valueOf(cmHandleDataNode.getLeaves().get("dmi-service-name"));
-        final Collection<DataNode> additionalPropsList = cmHandleDataNode.getChildDataNodes();
-        final var dmiRequesBody = prepareOperationBody(GenericRequestBody.OperationEnum.READ, additionalPropsList);
-        final ResponseEntity<Object> response = dmiOperations.getResouceDataPassThroughRunningFromDmi(dmiServiceName,
-            cmHandle,
-            resourceIdentifier,
-            fields,
-            depth,
-            accept,
-            dmiRequesBody);
+        final var dmiServiceName = String.valueOf(cmHandleDataNode.getLeaves().get(NCMP_DMI_SERVICE_NAME));
+        final String dmiRequestBody = getGenericRequestBody(cmHandleDataNode);
+        final ResponseEntity<Object> response = dmiOperations.getResourceDataPassThroughRunningFromDmi(dmiServiceName,
+                cmHandle,
+                resourceIdentifier,
+                fields,
+                depth,
+                acceptParam,
+                dmiRequestBody);
         return handleResponse(response);
     }
 
+    @Override
+    public void createResourceDataPassThroughRunningForCmHandle(final @NotNull String cmHandle,
+                                                                final @NotNull String resourceIdentifier,
+                                                                final @NotNull Object requestBody,
+                                                                final String contentType) {
+        final var cmHandleDataNode = fetchDataNodeFromDmiRegistryForCmHandle(cmHandle);
+        final var dmiServiceName = String.valueOf(cmHandleDataNode.getLeaves().get(NCMP_DMI_SERVICE_NAME));
+        final Collection<DataNode> cmHandlePropertiesList = cmHandleDataNode.getChildDataNodes();
+        final Map<String, String> cmHandlePropertiesMap = getCmHandlePropertiesAsMap(cmHandlePropertiesList);
+        final var dmiRequestBodyObject = GenericRequestBody.builder()
+                .operation(GenericRequestBody.OperationEnum.CREATE)
+                .dataType(contentType)
+                .data(requestBody)
+                .cmHandleProperties(cmHandlePropertiesMap)
+                .build();
+        final var dmiRequestBody = prepareOperationBody(dmiRequestBodyObject);
+        final ResponseEntity<Void> responseEntity = dmiOperations
+                .createResourceDataPassThroughRunningFromDmi(dmiServiceName,
+                        cmHandle,
+                        resourceIdentifier,
+                        dmiRequestBody);
+        handleResponseForPost(responseEntity);
+    }
+
     private DataNode fetchDataNodeFromDmiRegistryForCmHandle(final String cmHandle) {
         final String xpathForDmiRegistryToFetchCmHandle = "/dmi-registry/cm-handles[@id='" + cmHandle + "']";
         final var dataNode = cpsDataService.getDataNode(NCMP_DATASPACE_NAME,
-            NCMP_DMI_REGISTRY_ANCHOR,
-            xpathForDmiRegistryToFetchCmHandle,
-            FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
+                NCMP_DMI_REGISTRY_ANCHOR,
+                xpathForDmiRegistryToFetchCmHandle,
+                FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
         return dataNode;
     }
 
-    private String prepareOperationBody(final GenericRequestBody.OperationEnum operation,
-        final Collection<DataNode> additionalPropertyList) {
-        final var requestBody = new GenericRequestBody();
-        final Map<String, String> additionalPropertyMap = getAdditionalPropertiesMap(additionalPropertyList);
-        requestBody.setOperation(GenericRequestBody.OperationEnum.READ);
-        requestBody.setCmHandleProperties(additionalPropertyMap);
+    private String prepareOperationBody(final GenericRequestBody requestBodyObject) {
         try {
-            final var requestJson = objectMapper.writeValueAsString(requestBody);
-            return requestJson;
+            return objectMapper.writeValueAsString(requestBodyObject);
         } catch (final JsonProcessingException je) {
             log.error("Parsing error occurred while converting Object to JSON.");
             throw new NcmpException("Parsing error occurred while converting given object to JSON.",
-                je.getMessage());
+                    je.getMessage());
         }
     }
 
-    private Map<String, String> getAdditionalPropertiesMap(final Collection<DataNode> additionalPropertyList) {
-        if (additionalPropertyList == null || additionalPropertyList.size() == 0) {
+    private Map<String, String> getCmHandlePropertiesAsMap(final Collection<DataNode> cmHandlePropertiesList) {
+        if (cmHandlePropertiesList == null || cmHandlePropertiesList.size() == 0) {
             return null;
         }
-        final Map<String, String> additionalPropertyMap = new LinkedHashMap<>();
-        for (final var node : additionalPropertyList) {
-            additionalPropertyMap.put(String.valueOf(node.getLeaves().get("name")),
-                String.valueOf(node.getLeaves().get("value")));
+        final Map<String, String> cmHandlePropertiesMap = new LinkedHashMap<>();
+        for (final var node: cmHandlePropertiesList) {
+            cmHandlePropertiesMap.put(String.valueOf(node.getLeaves().get("name")),
+                    String.valueOf(node.getLeaves().get("value")));
         }
-        return additionalPropertyMap;
+        return cmHandlePropertiesMap;
     }
 
-    private Object handleResponse(final ResponseEntity<Object> responseEntity) {
+    private Object handleResponse(final @NotNull ResponseEntity<Object> responseEntity) {
         if (responseEntity.getStatusCode() == HttpStatus.OK) {
             return responseEntity.getBody();
         } else {
             throw new NcmpException("Not able to get resource data.",
-                "DMI status code: " + responseEntity.getStatusCodeValue()
-                    + ", DMI response body: " + responseEntity.getBody());
+                    "DMI status code: " + responseEntity.getStatusCodeValue()
+                            + ", DMI response body: " + responseEntity.getBody());
+        }
+    }
+
+    private void handleResponseForPost(final @NotNull ResponseEntity<Void> responseEntity) {
+        if (responseEntity.getStatusCode() != HttpStatus.CREATED) {
+            throw new NcmpException("Not able to create resource data.",
+                    "DMI status code: " + responseEntity.getStatusCodeValue()
+                            + ", DMI response body: " + responseEntity.getBody());
         }
     }
 
-    private PersistenceCmHandle toPersistenceCmHandle(final DmiPluginRegistration dmiPluginRegistration,
-        final CmHandle cmHandle) {
+    private String getGenericRequestBody(final DataNode cmHandleDataNode) {
+        final Collection<DataNode> cmHandlePropertiesList = cmHandleDataNode.getChildDataNodes();
+        final Map<String, String> cmHandlePropertiesMap = getCmHandlePropertiesAsMap(cmHandlePropertiesList);
+        final var requetBodyObject = GenericRequestBody.builder()
+                .operation(GenericRequestBody.OperationEnum.READ)
+                .cmHandleProperties(cmHandlePropertiesMap)
+                .build();
+        return prepareOperationBody(requetBodyObject);
+    }
+
+    private PersistenceCmHandle toPersistenceCmHandle(final String dmiPluginService,
+                                                      final CmHandle cmHandle) {
         final PersistenceCmHandle persistenceCmHandle = new PersistenceCmHandle();
-        persistenceCmHandle.setDmiServiceName(dmiPluginRegistration.getDmiPlugin());
+        persistenceCmHandle.setDmiServiceName(dmiPluginService);
         persistenceCmHandle.setId(cmHandle.getCmHandleID());
         if (cmHandle.getCmHandleProperties() == null) {
             persistenceCmHandle.setAdditionalProperties(Collections.EMPTY_MAP);
@@ -295,4 +278,54 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         return persistenceCmHandle;
     }
 
+    private void parseAndCreateCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) {
+        try {
+            final List<PersistenceCmHandle> createdPersistenceCmHandles =
+                    new LinkedList<>();
+            for (final CmHandle cmHandle: dmiPluginRegistration.getCreatedCmHandles()) {
+                createdPersistenceCmHandles.add(toPersistenceCmHandle(dmiPluginRegistration.getDmiPlugin(), cmHandle));
+            }
+            final PersistenceCmHandlesList persistenceCmHandlesList = new PersistenceCmHandlesList();
+            persistenceCmHandlesList.setCmHandles(createdPersistenceCmHandles);
+            final String cmHandleJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList);
+            cpsDataService.saveListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, "/dmi-registry",
+                    cmHandleJsonData, NO_TIMESTAMP);
+        } catch (final JsonProcessingException e) {
+            log.error("Parsing error occurred while converting Object to JSON for DMI Registry.");
+            throw new DataValidationException(
+                    "Parsing error occurred while processing DMI Plugin Registration" + dmiPluginRegistration, e
+                    .getMessage(), e);
+        }
+    }
+
+    private void parseAndUpdateCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) {
+        try {
+            final List<PersistenceCmHandle> updatedPersistenceCmHandles =
+                    new LinkedList<>();
+            for (final CmHandle cmHandle: dmiPluginRegistration.getUpdatedCmHandles()) {
+                updatedPersistenceCmHandles.add(toPersistenceCmHandle(dmiPluginRegistration.getDmiPlugin(), cmHandle));
+            }
+            final PersistenceCmHandlesList persistenceCmHandlesList = new PersistenceCmHandlesList();
+            persistenceCmHandlesList.setCmHandles(updatedPersistenceCmHandles);
+            final String cmHandlesJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList);
+            cpsDataService.updateNodeLeavesAndExistingDescendantLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
+                    "/dmi-registry", cmHandlesJsonData, NO_TIMESTAMP);
+        } catch (final JsonProcessingException e) {
+            log.error("Parsing error occurred while converting Object to JSON DMI Registry.");
+            throw new DataValidationException(
+                    "Parsing error occurred while processing DMI Plugin Registration" + dmiPluginRegistration, e
+                    .getMessage(), e);
+        }
+    }
+
+    private void parseAndRemoveCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) {
+        for (final String cmHandle: dmiPluginRegistration.getRemovedCmHandles()) {
+            try {
+                cpsDataService.deleteListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
+                        "/dmi-registry/cm-handles[@id='" + cmHandle + "']", NO_TIMESTAMP);
+            } catch (final DataNodeNotFoundException e) {
+                log.warn("Datanode {} not deleted message {}", cmHandle, e.getMessage());
+            }
+        }
+    }
 }
index 3e4f03d..cc4e2c7 100644 (file)
@@ -24,6 +24,7 @@ import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration.DmiProperties;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestTemplate;
@@ -45,8 +46,15 @@ public class DmiRestClient {
         return restTemplate.exchange(dmiResourceUrl, HttpMethod.PUT, httpEntity, Object.class);
     }
 
+    public ResponseEntity<Void> postOperationWithJsonData(final String dmiResourceUrl,
+                                                            final String jsonData, final HttpHeaders headers) {
+        final var httpEntity = new HttpEntity<>(jsonData, configureHttpHeaders(headers));
+        return restTemplate.postForEntity(dmiResourceUrl, httpEntity, Void.class);
+    }
+
     private HttpHeaders configureHttpHeaders(final HttpHeaders httpHeaders) {
         httpHeaders.setBasicAuth(dmiProperties.getAuthUsername(), dmiProperties.getAuthPassword());
+        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
         return httpHeaders;
     }
 }
\ No newline at end of file
index 2b13d16..63c4d49 100644 (file)
@@ -32,26 +32,27 @@ import org.springframework.stereotype.Component;
 public class DmiOperations {
 
     @Getter
-    public enum PassThroughEnum {
-        OPERATIONAL("/ncmp-datastore:passthrough-operational/"),
-        RUNNING("/ncmp-datastore:passthrough-running/");
+    public enum DataStoreEnum {
+        PASSTHROUGH_OPERATIONAL("ncmp-datastore:passthrough-operational"),
+        PASSTHROUGH_RUNNING("ncmp-datastore:passthrough-running");
         private String value;
 
-        PassThroughEnum(final String value) {
+        DataStoreEnum(final String value) {
             this.value = value;
         }
 
         @Override
         @JsonValue
         public String toString() {
-            return String.valueOf(value);
+            return value;
         }
     }
 
     private DmiRestClient dmiRestClient;
+    private static final String DMI_BASE_PATH = "/dmi/api";
     private static final String PARENT_CM_HANDLE_URI =
             "/v1/ch/{cmHandle}/data/ds";
-    private final int indexCmHandleInUri;
+    private static final String URL_SEPARATOR = "/";
 
     /**
      * Constructor for {@code DmiOperations}. This method also manipulates url properties.
@@ -60,7 +61,6 @@ public class DmiOperations {
      */
     public DmiOperations(final DmiRestClient dmiRestClient) {
         this.dmiRestClient = dmiRestClient;
-        indexCmHandleInUri = PARENT_CM_HANDLE_URI.indexOf("{cmHandle}");
     }
 
     /**
@@ -76,17 +76,17 @@ public class DmiOperations {
      * @param jsonBody json body for put operation
      * @return {@code ResponseEntity} response entity
      */
-    public ResponseEntity<Object> getResouceDataOperationalFromDmi(final String dmiBasePath,
-                                                                   final String cmHandle,
-                                                                   final String resourceId,
-                                                                   final String fieldsQuery,
-                                                                   final Integer depthQuery,
-                                                                   final String acceptParam,
-                                                                   final String jsonBody) {
-        final var builder = getDmiResourceDataUrl(dmiBasePath, cmHandle, resourceId,
-                fieldsQuery, depthQuery, PassThroughEnum.OPERATIONAL);
+    public ResponseEntity<Object> getResourceDataOperationalFromDmi(final String dmiBasePath,
+                                                                    final String cmHandle,
+                                                                    final String resourceId,
+                                                                    final String fieldsQuery,
+                                                                    final Integer depthQuery,
+                                                                    final String acceptParam,
+                                                                    final String jsonBody) {
+        final var dmiResourceDataUrl = getDmiResourceDataUrl(dmiBasePath, cmHandle, resourceId,
+                fieldsQuery, depthQuery, DataStoreEnum.PASSTHROUGH_OPERATIONAL);
         final var httpHeaders = prepareHeader(acceptParam);
-        return dmiRestClient.putOperationWithJsonData(builder.toString(), jsonBody, httpHeaders);
+        return dmiRestClient.putOperationWithJsonData(dmiResourceDataUrl, jsonBody, httpHeaders);
     }
 
     /**
@@ -102,46 +102,78 @@ public class DmiOperations {
      * @param jsonBody json body for put operation
      * @return {@code ResponseEntity} response entity
      */
-    public ResponseEntity<Object> getResouceDataPassThroughRunningFromDmi(final String dmiBasePath,
-                                                                   final String cmHandle,
-                                                                   final String resourceId,
-                                                                   final String fieldsQuery,
-                                                                   final Integer depthQuery,
-                                                                   final String acceptParam,
-                                                                   final String jsonBody) {
-        final var builder = getDmiResourceDataUrl(dmiBasePath, cmHandle, resourceId,
-                fieldsQuery, depthQuery, PassThroughEnum.RUNNING);
+    public ResponseEntity<Object> getResourceDataPassThroughRunningFromDmi(final String dmiBasePath,
+                                                                           final String cmHandle,
+                                                                           final String resourceId,
+                                                                           final String fieldsQuery,
+                                                                           final Integer depthQuery,
+                                                                           final String acceptParam,
+                                                                           final String jsonBody) {
+        final var dmiResourceDataUrl = getDmiResourceDataUrl(dmiBasePath, cmHandle, resourceId,
+                fieldsQuery, depthQuery, DataStoreEnum.PASSTHROUGH_RUNNING);
         final var httpHeaders = prepareHeader(acceptParam);
-        return dmiRestClient.putOperationWithJsonData(builder.toString(), jsonBody, httpHeaders);
+        return dmiRestClient.putOperationWithJsonData(dmiResourceDataUrl, jsonBody, httpHeaders);
+    }
+
+    /**
+     * This method creates the resource data from pass-through running data store for given cm handle
+     * identifier on given resource using dmi client.
+     *
+     * @param dmiBasePath dmi base path
+     * @param cmHandle network resource identifier
+     * @param resourceId resource identifier
+     * @param jsonBody json body for put operation
+     * @return {@code ResponseEntity} response entity
+     */
+    public ResponseEntity<Void> createResourceDataPassThroughRunningFromDmi(final String dmiBasePath,
+                                                                            final String cmHandle,
+                                                                            final String resourceId,
+                                                                            final String jsonBody) {
+        final var stringBuilder = getStringBuilderForPassThroughRunningUrl(dmiBasePath,
+                cmHandle, resourceId, DataStoreEnum.PASSTHROUGH_RUNNING);
+        return dmiRestClient.postOperationWithJsonData(stringBuilder.toString(), jsonBody, new HttpHeaders());
     }
 
     @NotNull
-    private StringBuilder getDmiResourceDataUrl(final String dmiBasePath,
+    private String getDmiResourceDataUrl(final String dmiBasePath,
                                                 final String cmHandle,
                                                 final String resourceId,
                                                 final String fieldsQuery,
                                                 final Integer depthQuery,
-                                       final PassThroughEnum passThrough) {
-        final var builder =  new StringBuilder(PARENT_CM_HANDLE_URI.replace("{cmHandle}", cmHandle));
-        builder.append(passThrough.getValue());
-        builder.insert(builder.length(), resourceId);
-        appendFieldsAndDepth(fieldsQuery, depthQuery, builder);
-        builder.insert(0, dmiBasePath);
-        return builder;
+                                                final DataStoreEnum dataStoreEnum) {
+        final var stringBuilder = getStringBuilderForPassThroughRunningUrl(dmiBasePath,
+                cmHandle, resourceId, dataStoreEnum);
+        appendFieldsAndDepth(stringBuilder, fieldsQuery, depthQuery);
+        return stringBuilder.toString();
+    }
+
+    @NotNull
+    private StringBuilder getStringBuilderForPassThroughRunningUrl(final String dmiServiceName,
+                                                                   final String cmHandle,
+                                                                   final String resourceId,
+                                                                   final DataStoreEnum dataStoreEnum) {
+        final var stringBuilder =  new StringBuilder(dmiServiceName);
+        stringBuilder.append(DMI_BASE_PATH);
+        stringBuilder.append(PARENT_CM_HANDLE_URI.replace("{cmHandle}", cmHandle));
+        stringBuilder.append(URL_SEPARATOR + dataStoreEnum.getValue());
+        stringBuilder.insert(stringBuilder.length(), URL_SEPARATOR + resourceId);
+        return stringBuilder;
     }
 
-    private void appendFieldsAndDepth(final String fieldsQuery, final Integer depthQuery, final StringBuilder builder) {
+    private void appendFieldsAndDepth(final StringBuilder stringBuilder,
+                                      final String fieldsQuery,
+                                      final Integer depthQuery) {
         final var doesFieldExists = (fieldsQuery != null && !fieldsQuery.isEmpty());
         if (doesFieldExists) {
-            builder.append("?").append("fields=").append(fieldsQuery);
+            stringBuilder.append("?").append("fields=").append(fieldsQuery);
         }
         if (depthQuery != null) {
-            if (!doesFieldExists) {
-                builder.append("?");
+            if (doesFieldExists) {
+                stringBuilder.append("&");
             } else {
-                builder.append("&");
+                stringBuilder.append("?");
             }
-            builder.append("depth=").append(depthQuery);
+            stringBuilder.append("depth=").append(depthQuery);
         }
     }
 
index 5b82c51..9ed78de 100644 (file)
@@ -24,15 +24,16 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonInclude.Include;
 import com.fasterxml.jackson.annotation.JsonValue;
 import java.util.Map;
+import lombok.Builder;
 import lombok.Getter;
-import lombok.Setter;
 
-@Getter
-@Setter
 @JsonInclude(Include.NON_NULL)
+@Getter
+@Builder
 public class GenericRequestBody   {
     public enum OperationEnum {
-        READ("read");
+        READ("read"),
+        CREATE("create");
         private String value;
 
         OperationEnum(final String value) {
@@ -48,6 +49,6 @@ public class GenericRequestBody   {
 
     private OperationEnum operation;
     private String dataType;
-    private String data;
+    private Object data;
     private Map<String, String> cmHandleProperties;
 }
index 45fa0af..8a32ad5 100644 (file)
@@ -51,6 +51,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
 
     def cmHandle = 'some handle'
     def noTimestamp = null
+    def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
 
     def expectedDataspaceName = 'NFP-Operational'
     def 'Query data nodes by cps path with #fetchDescendantsOption.'() {
@@ -159,14 +160,8 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
     }
 
     def 'Get resource data for pass-through operational from dmi.'() {
-        given: 'xpath'
-            def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
-        and: 'data node'
-            def dataNode = new DataNode()
-            dataNode.leaves = ['dmi-service-name':'testDmiService']
-            def childDataNode = new DataNode()
-            childDataNode.leaves = ['name':'testName','value':'testValue']
-            dataNode.childDataNodes = [childDataNode]
+        given: 'data node representing cmHandle and its properties'
+            def cmHandleDataNode = prepareCmHandleDataNode()
         when: 'get resource data is called'
             def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
             'testResourceId',
@@ -175,9 +170,9 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
             5)
         then: 'cps data service is being called once to get data node'
             1 * mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
-                    xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
         and: 'dmi operation is being called to get resource data'
-            1 * mockDmiOperations.getResouceDataOperationalFromDmi('testDmiService',
+            1 * mockDmiOperations.getResourceDataOperationalFromDmi('testDmiService',
                     'testCmHandle',
                     'testResourceId',
                     'testFieldQuery',
@@ -188,17 +183,13 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
         and: 'dmi returns ok response'
             response == 'result-json'
     }
+
     def 'Get resource data for pass-through operational from dmi threw parsing exception.'() {
-        given: 'xpath'
-            def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
-        and: 'data node'
-            def dataNode = new DataNode()
-            dataNode.leaves = ['dmi-service-name':'testDmiService']
-            def childDataNode = new DataNode()
-            childDataNode.leaves = ['name':'testName','value':'testValue']
-            dataNode.childDataNodes = [childDataNode]
+        given: 'data node representing cmHandle and its properties'
+            def cmHandleDataNode = prepareCmHandleDataNode()
+        and: 'cps data service returns valid cmHandle data node'
             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
-                    xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
         and: 'objectMapper not able to parse object'
             def mockObjectMapper = Mock(ObjectMapper)
             objectUnderTest.objectMapper = mockObjectMapper
@@ -212,19 +203,15 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
         then: 'exception is thrown'
             thrown(NcmpException.class)
     }
+
     def 'Get resource data for pass-through operational from dmi return NOK response.'() {
-        given: 'xpath'
-            def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
-        and: 'data node'
-            def dataNode = new DataNode()
-            dataNode.leaves = ['dmi-service-name':'testDmiService']
-            def childDataNode = new DataNode()
-            childDataNode.leaves = ['name':'testName','value':'testValue']
-            dataNode.childDataNodes = [childDataNode]
+        given: 'data node representing cmHandle and its properties'
+            def cmHandleDataNode = prepareCmHandleDataNode()
+        and: 'cps data service returns valid cmHandle data node'
             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
-                    xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
         and: 'dmi returns NOK response'
-            mockDmiOperations.getResouceDataOperationalFromDmi('testDmiService',
+            mockDmiOperations.getResourceDataOperationalFromDmi('testDmiService',
                     'testCmHandle',
                     'testResourceId',
                     'testFieldQuery',
@@ -241,20 +228,15 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
         then: 'exception is thrown'
             thrown(NcmpException.class)
     }
+
     def 'Get resource data for pass-through running from dmi.'() {
-        given: 'xpath'
-            def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
-        and: 'data node representing cmhandle and its properties'
-            def dataNode = new DataNode()
-            dataNode.leaves = ['dmi-service-name':'testDmiService']
-            def childDataNode = new DataNode()
-            childDataNode.leaves = ['name':'testName','value':'testValue']
-            dataNode.childDataNodes = [childDataNode]
+        given: 'data node representing cmHandle and its properties'
+            def cmHandleDataNode = prepareCmHandleDataNode()
         and: 'cpsDataService returns valid dataNode'
             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
-                    xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
         and: 'dmi returns valid response and data'
-            mockDmiOperations.getResouceDataPassThroughRunningFromDmi('testDmiService',
+            mockDmiOperations.getResourceDataPassThroughRunningFromDmi('testDmiService',
                     'testCmHandle',
                     'testResourceId',
                     'testFieldQuery',
@@ -270,18 +252,13 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
         then: 'get resource data returns expected response'
             response == '{result-json}'
     }
+
     def 'Get resource data for pass-through running from dmi threw parsing exception.'() {
-        given: 'xpath'
-            def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
-        and: 'data node representing cmhandle and its properties'
-            def dataNode = new DataNode()
-            dataNode.leaves = ['dmi-service-name':'testDmiService']
-            def childDataNode = new DataNode()
-            childDataNode.leaves = ['name':'testName','value':'testValue']
-            dataNode.childDataNodes = [childDataNode]
+        given: 'data node representing cmHandle and its properties'
+            def cmHandleDataNode = prepareCmHandleDataNode()
         and: 'cpsDataService returns valid dataNode'
             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
-                    xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
         and: 'objectMapper not able to parse object'
             def mockObjectMapper = Mock(ObjectMapper)
             objectUnderTest.objectMapper = mockObjectMapper
@@ -295,20 +272,15 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
         then: 'exception is thrown'
             thrown(NcmpException.class)
     }
+
     def 'Get resource data for pass-through running from dmi return NOK response.'() {
-        given: 'xpath'
-            def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
-        and: 'data node representing cmhandle and its properties'
-            def dataNode = new DataNode()
-            dataNode.leaves = ['dmi-service-name':'testDmiService']
-            def childDataNode = new DataNode()
-            childDataNode.leaves = ['name':'testName','value':'testValue']
-            dataNode.childDataNodes = [childDataNode]
+        given: 'data node representing cmHandle and its properties'
+            def cmHandleDataNode = prepareCmHandleDataNode()
         and: 'cpsDataService returns valid dataNode'
             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
-                    xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
         and: 'dmi returns NOK response'
-            mockDmiOperations.getResouceDataPassThroughRunningFromDmi('testDmiService',
+            mockDmiOperations.getResourceDataPassThroughRunningFromDmi('testDmiService',
                     'testCmHandle',
                     'testResourceId',
                     'testFieldQuery',
@@ -325,4 +297,48 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
         then: 'exception is thrown'
             thrown(NcmpException.class)
     }
+
+    def 'Write resource data for pass-through running from dmi using POST.'() {
+        given: 'data node representing cmHandle and its properties'
+            def cmHandleDataNode = prepareCmHandleDataNode()
+        and: 'cpsDataService returns valid dataNode'
+            mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
+        when: 'get resource data is called'
+            objectUnderTest.createResourceDataPassThroughRunningForCmHandle('testCmHandle',
+                    'testResourceId',
+                    '{some-json}', 'application/json')
+        then: 'dmi called with correct data'
+            1 * mockDmiOperations.createResourceDataPassThroughRunningFromDmi('testDmiService',
+                'testCmHandle',
+                'testResourceId',
+                '{"operation":"create","dataType":"application/json","data":"{some-json}","cmHandleProperties":{"testName":"testValue"}}')
+                >> { new ResponseEntity<>(HttpStatus.CREATED) }
+    }
+
+    def 'Write resource data for pass-through running from dmi using POST "not found" response (from DMI).'() {
+        given: 'data node representing cmHandle and its properties'
+            def cmHandleDataNode = prepareCmHandleDataNode()
+        and: 'cpsDataService returns valid dataNode'
+            mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
+        and: 'dmi throws exception'
+            1 * mockDmiOperations.createResourceDataPassThroughRunningFromDmi(_ as String, _ as String, _ as String, _ as String)
+                    >> { new ResponseEntity<>(HttpStatus.NOT_FOUND) }
+        when: 'get resource data is called'
+            objectUnderTest.createResourceDataPassThroughRunningForCmHandle('testCmHandle',
+                    'testResourceId',
+                    '{some-json}', 'application/json')
+        then: 'exception is thrown'
+            thrown(NcmpException.class)
+    }
+
+    private DataNode prepareCmHandleDataNode() {
+        def cmHandleDataNode = new DataNode()
+        cmHandleDataNode.leaves = ['dmi-service-name': 'testDmiService']
+        def cmHandlePropertyDataNode = new DataNode()
+        cmHandlePropertyDataNode.leaves = ['name': 'testName', 'value': 'testValue']
+        cmHandleDataNode.childDataNodes = [cmHandlePropertyDataNode]
+        cmHandleDataNode
+    }
 }
index 98bbe87..879c73c 100644 (file)
@@ -35,7 +35,7 @@ class DmiRestClientSpec extends Specification {
     def objectUnderTest = new DmiRestClient(mockRestTemplate, mockDmiProperties)
 
     def 'DMI PUT operation.'() {
-        given: 'a get url'
+        given: 'a PUT url'
             def getResourceDataUrl = 'http://some-uri/getResourceDataUrl'
         and: 'dmi properties'
             setupTestConfigurationData()
@@ -48,6 +48,20 @@ class DmiRestClientSpec extends Specification {
             result == mockResponseEntity
     }
 
+    def 'DMI POST operation.'() {
+        given: 'a POST url'
+            def getResourceDataUrl = 'http://some-uri/createResourceDataUrl'
+        and: 'dmi properties'
+            setupTestConfigurationData()
+        and: 'the rest template returns a valid response entity'
+            def mockResponseEntity = Mock(ResponseEntity)
+            mockRestTemplate.postForEntity(getResourceDataUrl, _ as HttpEntity, Void.class) >> mockResponseEntity
+        when: 'POST operation is invoked'
+            def result = objectUnderTest.postOperationWithJsonData(getResourceDataUrl, 'json-data', new HttpHeaders())
+        then: 'the output of the method is equal to the output from the test template'
+            result == mockResponseEntity
+    }
+
     def setupTestConfigurationData() {
         mockDmiProperties.authUsername >> 'some-username'
         mockDmiProperties.authPassword >> 'some-password'
index ceb3569..c2a135e 100644 (file)
@@ -22,7 +22,6 @@ package org.onap.cps.ncmp.api.impl.operation
 
 import org.onap.cps.ncmp.api.impl.client.DmiRestClient
 import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration
-import org.onap.cps.ncmp.api.impl.operation.DmiOperations
 import org.spockframework.spring.SpringBean
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.test.context.SpringBootTest
@@ -40,12 +39,12 @@ class DmiOperationsSpec extends Specification {
     @Autowired
     DmiOperations objectUnderTest = new DmiOperations(mockDmiRestClient)
 
-    def 'call get resource data for pass-through:operational datastore from dmi.'() {
+    def 'call get resource data for pass-through:operational datastore from DMI.'() {
         given: 'expected url'
-            def expectedUrl = 'testDmiBasePath/v1/ch/testCmhandle/data/ds' +
+            def expectedUrl = 'testDmiBasePath/dmi/api/v1/ch/testCmhandle/data/ds' +
                     '/ncmp-datastore:passthrough-operational/testResourceId?fields=testFieldsQuery&depth=10'
-        when: 'get resource data is called to dmi'
-            objectUnderTest.getResouceDataOperationalFromDmi('testDmiBasePath',
+        when: 'get resource data is called to DMI'
+            objectUnderTest.getResourceDataOperationalFromDmi('testDmiBasePath',
                     'testCmhandle',
                     'testResourceId',
                     'testFieldsQuery',
@@ -55,12 +54,12 @@ class DmiOperationsSpec extends Specification {
         then: 'the put operation is executed with the correct URL'
             1 * mockDmiRestClient.putOperationWithJsonData(expectedUrl, 'testJsonbody', _ as HttpHeaders)
     }
-    def 'call get resource data for pass-through:running datastore from dmi.'() {
+    def 'call get resource data for pass-through:running datastore from DMI.'() {
         given: 'expected url'
-            def expectedUrl = 'testDmiBasePath/v1/ch/testCmhandle/data/ds' +
+            def expectedUrl = 'testDmiBasePath/dmi/api/v1/ch/testCmhandle/data/ds' +
                     '/ncmp-datastore:passthrough-running/testResourceId?fields=testFieldsQuery&depth=10'
-        when: 'get resource data is called to dmi'
-            objectUnderTest.getResouceDataPassThroughRunningFromDmi('testDmiBasePath',
+        when: 'get resource data is called to DMI'
+            objectUnderTest.getResourceDataPassThroughRunningFromDmi('testDmiBasePath',
                     'testCmhandle',
                     'testResourceId',
                     'testFieldsQuery',
@@ -70,4 +69,16 @@ class DmiOperationsSpec extends Specification {
         then: 'the put operation is executed with the correct URL'
             1 * mockDmiRestClient.putOperationWithJsonData(expectedUrl, 'testJsonbody', _ as HttpHeaders)
     }
+    def 'call create resource data for pass-through:running datastore from DMI.'() {
+        given: 'expected url'
+            def expectedUrl = 'testDmiBasePath/dmi/api/v1/ch/testCmhandle/data/ds' +
+                    '/ncmp-datastore:passthrough-running/testResourceId'
+        when: 'get resource data is called to DMI'
+            objectUnderTest.createResourceDataPassThroughRunningFromDmi('testDmiBasePath',
+                    'testCmhandle',
+                    'testResourceId',
+                    'testJsonbody')
+        then: 'the put operation is executed with the correct URL'
+            1 * mockDmiRestClient.postOperationWithJsonData(expectedUrl, 'testJsonbody', _ as HttpHeaders)
+    }
 }
\ No newline at end of file