Support Update and Delete operations for DS Passtrough-Running in DMI Plugin 64/125664/10
authorDylanB95EST <dylan.byrne@est.tech>
Tue, 9 Nov 2021 13:54:35 +0000 (13:54 +0000)
committerDylanB95EST <dylan.byrne@est.tech>
Fri, 12 Nov 2021 15:24:27 +0000 (15:24 +0000)
-Add Update operation for Passthrough Running
-Use POST operatiosn for all methods as agrred
-refactor to simplify and beter reuse of common methods
-add delete operation for passthrough running

Issue-ID: CPS-637
Issue-ID: CPS-638
Change-Id: I441181f977dee2bc0be944662465d868595ea452
Signed-off-by: DylanB95EST <dylan.byrne@est.tech>
17 files changed:
docs/api/swagger/openapi.yaml
openapi/components.yml
openapi/openapi.yml
src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java
src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java
src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy
src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy
src/test/resources/createDataWithNormalChar.json [moved from src/test/resources/dataWithNormalChar.json with 100% similarity]
src/test/resources/createDataWithSpecialChar.json [moved from src/test/resources/dataWithSpecialChar.json with 100% similarity]
src/test/resources/deleteData.json [new file with mode: 0644]
src/test/resources/readData.json [new file with mode: 0644]
src/test/resources/updateData.json [new file with mode: 0644]

index 750091b..54676fe 100644 (file)
@@ -58,27 +58,34 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
-  /v1/inventory/cmHandles:
+  /v1/ch/{cmHandle}/moduleResources:
     post:
       tags:
-      - dmi-plugin-internal
-      summary: register given list of cm handles (internal use only)
-      description: register given list of cm handles (internal use only)
-      operationId: registerCmHandles
+      - dmi-plugin
+      summary: Retrieve module resources
+      description: Retrieve module resources for one or more modules
+      operationId: retrieveModuleResources
+      parameters:
+      - name: cmHandle
+        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
       requestBody:
-        description: list of cm handles
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/CmHandles'
+              $ref: '#/components/schemas/ModuleResourcesReadRequest'
         required: true
       responses:
-        "201":
-          description: Created
+        "200":
+          description: OK
           content:
-            text/plain:
+            application/json:
               schema:
-                type: string
+                $ref: '#/components/schemas/YangResources'
         "400":
           description: Bad Request
           content:
@@ -97,35 +104,27 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
-      x-api-audience: component-internal
-  /v1/ch/{cmHandle}/moduleResources:
+  /v1/inventory/cmHandles:
     post:
       tags:
-      - dmi-plugin
-      summary: Retrieve module resources
-      description: Retrieve module resources for one or more modules
-      operationId: retrieveModuleResources
-      parameters:
-      - name: cmHandle
-        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
+      - dmi-plugin-internal
+      summary: register given list of cm handles (internal use only)
+      description: register given list of cm handles (internal use only)
+      operationId: registerCmHandles
       requestBody:
+        description: list of cm handles
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/ModuleResourcesReadRequest'
+              $ref: '#/components/schemas/CmHandles'
         required: true
       responses:
-        "200":
-          description: OK
+        "201":
+          description: Created
           content:
-            application/json:
+            text/plain:
               schema:
-                $ref: '#/components/schemas/YangResources'
+                type: string
         "400":
           description: Bad Request
           content:
@@ -144,13 +143,15 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
+      x-api-audience: component-internal
   /v1/ch/{cmHandle}/data/ds/ncmp-datastore:passthrough-operational:
-    put:
+    post:
       tags:
       - dmi-plugin
       summary: Get resource data from passthrough-operational for cm handle
-      description: Get resource data from passthrough-operational for cm handle
-      operationId: getResourceDataOperationalForCmHandle
+      description: Get resource data from passthrough-operational for cm handle. Will
+        support read operations only.
+      operationId: dataAccessPassthroughOperational
       parameters:
       - name: cmHandle
         in: path
@@ -198,7 +199,7 @@ paths:
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/DataAccessReadRequest'
+              $ref: '#/components/schemas/DataAccessRequest'
       responses:
         "200":
           description: OK
@@ -225,12 +226,15 @@ paths:
               schema:
                 $ref: '#/components/schemas/ErrorMessage'
   /v1/ch/{cmHandle}/data/ds/ncmp-datastore:passthrough-running:
-    put:
+    post:
       tags:
       - dmi-plugin
-      summary: Get resource data from passthrough-running for cm handle
-      description: Get resource data from passthrough-running for cm handle
-      operationId: getResourceDataPassthroughRunningForCmHandle
+      summary: Get, Create or Update request for data passthrough-running for a cm-handle
+      description: Post request to Get, Create or to Update resource data for a cm-handle.
+        Since all requests need to include additional information in a request body
+        HTTP Post is used for all use cases and the actual operation is defined in
+        the request body instead.
+      operationId: dataAccessPassthroughRunning
       parameters:
       - name: cmHandle
         in: path
@@ -273,64 +277,11 @@ paths:
           sample3:
             value:
               options: (key1=10,key2=value2,key3=[val31,val32])
-      requestBody:
-        description: Operational body
-        content:
-          application/json:
-            schema:
-              $ref: '#/components/schemas/DataAccessReadRequest'
-      responses:
-        "200":
-          description: OK
-          content:
-            application/json:
-              schema:
-                type: object
-        "400":
-          description: Bad Request
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ErrorMessage'
-        "401":
-          description: Unauthorized
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ErrorMessage'
-        "403":
-          description: Forbidden
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ErrorMessage'
-    post:
-      tags:
-      - dmi-plugin
-      summary: Write data for a cmHandle
-      description: Write data for a cmHandle using passthrough-running
-      operationId: writeDataByPassthroughRunningForCmHandle
-      parameters:
-      - name: cmHandle
-        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: Resource identifier to get/set the resource data
-        required: true
-        allowReserved: true
-        schema:
-          type: string
       requestBody:
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/DataAccessWriteRequest'
-        required: true
+              $ref: '#/components/schemas/DataAccessRequest'
       responses:
         "201":
           description: Created
@@ -388,13 +339,6 @@ components:
           type: string
         details:
           type: string
-    CmHandles:
-      type: object
-      properties:
-        cmHandles:
-          type: array
-          items:
-            type: string
     ModuleResourcesReadRequest:
       type: object
       properties:
@@ -417,22 +361,23 @@ components:
           type: string
         revision:
           $ref: '#/components/schemas/revision'
-    DataAccessReadRequest:
+    CmHandles:
       type: object
       properties:
-        operation:
-          type: string
-          enum:
-          - read
-        cmHandleProperties:
-          $ref: '#/components/schemas/cmHandleProperties'
-    DataAccessWriteRequest:
+        cmHandles:
+          type: array
+          items:
+            type: string
+    DataAccessRequest:
       type: object
       properties:
         operation:
           type: string
           enum:
+          - read
           - create
+          - update
+          - delete
         dataType:
           type: string
         data:
index 30e5987..cdf4c1c 100644 (file)
@@ -73,21 +73,12 @@ components:
         revision:
           $ref: '#/components/schemas/revision'
 
-    DataAccessReadRequest:
+    DataAccessRequest:
       type: object
       properties:
         operation:
           type: string
-          enum: [ read ]
-        cmHandleProperties:
-          $ref: '#/components/schemas/cmHandleProperties'
-
-    DataAccessWriteRequest:
-      type: object
-      properties:
-        operation:
-          type: string
-          enum: [ create ]
+          enum: [ read, create, update, delete ]
         dataType:
           type: string
         data:
index 0f43f9a..5c095a7 100644 (file)
@@ -74,31 +74,6 @@ paths:
         '403':
           $ref: 'components.yml#/components/responses/Forbidden'
 
-  /v1/inventory/cmHandles:
-    post:
-      tags:
-        - dmi-plugin-internal
-      summary: register given list of cm handles (internal use only)
-      description: register given list of cm handles (internal use only)
-      x-api-audience: component-internal
-      operationId: registerCmHandles
-      requestBody:
-        description: list of cm handles
-        content:
-          application/json:
-            schema:
-                $ref: 'components.yml#/components/schemas/CmHandles'
-        required: true
-      responses:
-        '201':
-          $ref: 'components.yml#/components/responses/Created'
-        '400':
-          $ref: 'components.yml#/components/responses/BadRequest'
-        '401':
-          $ref: 'components.yml#/components/responses/Unauthorized'
-        '403':
-          $ref: 'components.yml#/components/responses/Forbidden'
-
   /v1/ch/{cmHandle}/moduleResources:
     post:
       description: Retrieve module resources for one or more modules
@@ -128,27 +103,24 @@ paths:
         '403':
           $ref: 'components.yml#/components/responses/Forbidden'
 
-  /v1/ch/{cmHandle}/data/ds/ncmp-datastore:passthrough-operational:
-    put:
+  /v1/inventory/cmHandles:
+    post:
       tags:
-        - dmi-plugin
-      summary: Get resource data from passthrough-operational for cm handle
-      description: Get resource data from passthrough-operational for cm handle
-      operationId: getResourceDataOperationalForCmHandle
-      parameters:
-        - $ref: 'components.yml#/components/parameters/cmHandleInPath'
-        - $ref: 'components.yml#/components/parameters/resourceIdentifierInQuery'
-        - $ref: 'components.yml#/components/parameters/acceptParamInHeader'
-        - $ref: 'components.yml#/components/parameters/optionsParamInQuery'
+        - dmi-plugin-internal
+      summary: register given list of cm handles (internal use only)
+      description: register given list of cm handles (internal use only)
+      x-api-audience: component-internal
+      operationId: registerCmHandles
       requestBody:
-        description: Operational body
+        description: list of cm handles
         content:
           application/json:
             schema:
-              $ref: 'components.yml#/components/schemas/DataAccessReadRequest'
+                $ref: 'components.yml#/components/schemas/CmHandles'
+        required: true
       responses:
-        '200':
-          $ref: 'components.yml#/components/responses/Ok'
+        '201':
+          $ref: 'components.yml#/components/responses/Created'
         '400':
           $ref: 'components.yml#/components/responses/BadRequest'
         '401':
@@ -156,13 +128,13 @@ paths:
         '403':
           $ref: 'components.yml#/components/responses/Forbidden'
 
-  /v1/ch/{cmHandle}/data/ds/ncmp-datastore:passthrough-running:
-    put:
+  /v1/ch/{cmHandle}/data/ds/ncmp-datastore:passthrough-operational:
+    post:
       tags:
         - dmi-plugin
-      summary: Get resource data from passthrough-running for cm handle
-      description: Get resource data from passthrough-running for cm handle
-      operationId: getResourceDataPassthroughRunningForCmHandle
+      summary: Get resource data from passthrough-operational for cm handle
+      description: Get resource data from passthrough-operational for cm handle. Will support read operations only.
+      operationId: dataAccessPassthroughOperational
       parameters:
         - $ref: 'components.yml#/components/parameters/cmHandleInPath'
         - $ref: 'components.yml#/components/parameters/resourceIdentifierInQuery'
@@ -173,7 +145,7 @@ paths:
         content:
           application/json:
             schema:
-              $ref: 'components.yml#/components/schemas/DataAccessReadRequest'
+              $ref: 'components.yml#/components/schemas/DataAccessRequest'
       responses:
         '200':
           $ref: 'components.yml#/components/responses/Ok'
@@ -184,21 +156,23 @@ paths:
         '403':
           $ref: 'components.yml#/components/responses/Forbidden'
 
+  /v1/ch/{cmHandle}/data/ds/ncmp-datastore:passthrough-running:
     post:
-      description: Write data for a cmHandle using passthrough-running
       tags:
         - dmi-plugin
-      summary: Write data for a cmHandle
-      operationId: writeDataByPassthroughRunningForCmHandle
+      summary: Get, Create or Update request for data passthrough-running for a cm-handle
+      description: Post request to Get, Create or to Update resource data for a cm-handle. Since all requests need to include additional information in a request body HTTP Post is used for all use cases and the actual operation is defined in the request body instead.
+      operationId: dataAccessPassthroughRunning
       parameters:
         - $ref: 'components.yml#/components/parameters/cmHandleInPath'
         - $ref: 'components.yml#/components/parameters/resourceIdentifierInQuery'
+        - $ref: 'components.yml#/components/parameters/acceptParamInHeader'
+        - $ref: 'components.yml#/components/parameters/optionsParamInQuery'
       requestBody:
-        required: true
         content:
           application/json:
             schema:
-              $ref: 'components.yml#/components/schemas/DataAccessWriteRequest'
+              $ref: 'components.yml#/components/schemas/DataAccessRequest'
       responses:
         '201':
           $ref: 'components.yml#/components/responses/Created'
@@ -208,4 +182,3 @@ paths:
           $ref: 'components.yml#/components/responses/Unauthorized'
         '403':
           $ref: 'components.yml#/components/responses/Forbidden'
-
index b17280a..97848c3 100644 (file)
@@ -26,8 +26,7 @@ import java.util.List;
 import javax.validation.Valid;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.ncmp.dmi.model.CmHandles;
-import org.onap.cps.ncmp.dmi.model.DataAccessReadRequest;
-import org.onap.cps.ncmp.dmi.model.DataAccessWriteRequest;
+import org.onap.cps.ncmp.dmi.model.DataAccessRequest;
 import org.onap.cps.ncmp.dmi.model.ModuleReferencesRequest;
 import org.onap.cps.ncmp.dmi.model.ModuleResourcesReadRequest;
 import org.onap.cps.ncmp.dmi.model.ModuleSet;
@@ -73,25 +72,6 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi {
         return new ResponseEntity<>(yangResources, HttpStatus.OK);
     }
 
-    /**
-     * Write data using passthrough for the given cmHandle.
-     *
-     * @param dataAccessWriteRequest pass through request
-     * @param resourceIdentifier     resource identifier
-     * @param cmHandle               cmHandle
-     * @return (@ code ResponseEntity) response entity
-     */
-    @Override
-    public ResponseEntity<String> writeDataByPassthroughRunningForCmHandle(
-        final DataAccessWriteRequest dataAccessWriteRequest,
-        final String resourceIdentifier, final String cmHandle) {
-        final String response = dmiService.writeResourceDataPassthroughForCmHandle(cmHandle,
-            resourceIdentifier,
-            MediaType.APPLICATION_JSON_VALUE,
-            dataAccessWriteRequest.getData());
-        return new ResponseEntity<>(response, HttpStatus.CREATED);
-    }
-
     /**
      * This method register given list of cm-handles to ncmp.
      *
@@ -109,52 +89,84 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi {
 
     /**
      * This method fetches the resource for given cm handle using pass through operational. It filters the response on
-     * the basis of options query parameters and returns response.
+     * the basis of options query parameters and returns response. Does not support write operations.
      *
      * @param resourceIdentifier    resource identifier to fetch data
      * @param cmHandle              cm handle identifier
-     * @param dataAccessReadRequest data Access Read Request
+     * @param dataAccessRequest     data Access Request
      * @param acceptParamInHeader   accept header parameter
      * @param optionsParamInQuery   options query parameter
      * @return {@code ResponseEntity} response entity
      */
     @Override
-    public ResponseEntity<Object> getResourceDataOperationalForCmHandle(final String resourceIdentifier,
-        final String cmHandle,
-        final @Valid DataAccessReadRequest dataAccessReadRequest,
-        final String acceptParamInHeader,
-        final @Valid String optionsParamInQuery) {
-        final var modulesListAsJson = dmiService.getResourceDataOperationalForCmHandle(cmHandle,
-            resourceIdentifier,
-            acceptParamInHeader,
-            optionsParamInQuery,
-            dataAccessReadRequest.getCmHandleProperties());
-        return ResponseEntity.ok(modulesListAsJson);
+    public ResponseEntity<Object> dataAccessPassthroughOperational(final String resourceIdentifier,
+                                                                   final String cmHandle,
+                                                                   final @Valid DataAccessRequest
+                                                                                dataAccessRequest,
+                                                                   final String acceptParamInHeader,
+                                                                   final @Valid String optionsParamInQuery) {
+        if (isReadOperation(dataAccessRequest)) {
+            final String resourceDataAsJson = dmiService.getResourceData(cmHandle,
+                resourceIdentifier,
+                acceptParamInHeader,
+                optionsParamInQuery,
+                DmiService.RESTCONF_CONTENT_PASSTHROUGH_OPERATIONAL_QUERY_PARAM);
+            return ResponseEntity.ok(resourceDataAsJson);
+        }
+        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
     }
 
-    /**
-     * This method fetches the resource for given cm handle using pass through running. It filters the response on the
-     * basis of options query parameters and returns response.
-     *
-     * @param resourceIdentifier    resource identifier to fetch data
-     * @param cmHandle              cm handle identifier
-     * @param dataAccessReadRequest data Access Read Request
-     * @param acceptParamInHeader   accept header parameter
-     * @param optionsParamInQuery   options query parameter
-     * @return {@code ResponseEntity} response entity
-     */
     @Override
-    public ResponseEntity<Object> getResourceDataPassthroughRunningForCmHandle(final String resourceIdentifier,
-        final String cmHandle,
-        final @Valid DataAccessReadRequest dataAccessReadRequest,
-        final String acceptParamInHeader,
-        final @Valid String optionsParamInQuery) {
-        final var modulesListAsJson = dmiService.getResourceDataPassThroughRunningForCmHandle(cmHandle,
-            resourceIdentifier,
-            acceptParamInHeader,
-            optionsParamInQuery,
-            dataAccessReadRequest.getCmHandleProperties());
-        return ResponseEntity.ok(modulesListAsJson);
+    public ResponseEntity<String> dataAccessPassthroughRunning(final String resourceIdentifier,
+                                                               final String cmHandle,
+                                                               final @Valid DataAccessRequest
+                                                                       dataAccessRequest,
+                                                               final String acceptParamInHeader,
+                                                               final @Valid String optionsParamInQuery) {
+        final String sdncResponse;
+        if (isReadOperation(dataAccessRequest)) {
+            sdncResponse = dmiService.getResourceData(cmHandle,
+                resourceIdentifier,
+                acceptParamInHeader,
+                optionsParamInQuery,
+                DmiService.RESTCONF_CONTENT_PASSTHROUGH_RUNNING_QUERY_PARAM);
+        } else {
+            sdncResponse = dmiService.writeData(
+                dataAccessRequest.getOperation(),
+                cmHandle,
+                resourceIdentifier,
+                MediaType.APPLICATION_JSON_VALUE,
+                dataAccessRequest.getData());
+        }
+        return new ResponseEntity<>(sdncResponse, getHttpStatus(dataAccessRequest));
+    }
+
+    private boolean isReadOperation(final @Valid DataAccessRequest dataAccessRequest) {
+        return dataAccessRequest.getOperation() == null
+            || dataAccessRequest.getOperation().equals(DataAccessRequest.OperationEnum.READ);
+    }
+
+    private HttpStatus getHttpStatus(final DataAccessRequest dataAccessRequest) {
+        final HttpStatus httpStatus;
+        if (dataAccessRequest.getOperation() == null) {
+            httpStatus = HttpStatus.OK;
+        } else {
+            switch (dataAccessRequest.getOperation()) {
+                case CREATE:
+                    httpStatus = HttpStatus.CREATED;
+                    break;
+                case READ:
+                case UPDATE:
+                    httpStatus = HttpStatus.OK;
+                    break;
+                case DELETE:
+                    httpStatus = HttpStatus.NO_CONTENT;
+                    break;
+                default:
+                    httpStatus = HttpStatus.BAD_REQUEST;
+            }
+        }
+        return httpStatus;
     }
 
     private List<ModuleReference> convertRestObjectToJavaApiObject(
index c691039..0f3fcc0 100644 (file)
 package org.onap.cps.ncmp.dmi.service;
 
 import java.util.List;
-import java.util.Map;
 import javax.validation.constraints.NotNull;
 import org.onap.cps.ncmp.dmi.exception.DmiException;
+import org.onap.cps.ncmp.dmi.model.DataAccessRequest;
 import org.onap.cps.ncmp.dmi.model.ModuleSet;
 import org.onap.cps.ncmp.dmi.model.YangResources;
 import org.onap.cps.ncmp.dmi.service.model.ModuleReference;
 
+
+
 /**
  * Interface for handling Dmi plugin Data.
  */
 public interface DmiService {
 
+    String RESTCONF_CONTENT_PASSTHROUGH_OPERATIONAL_QUERY_PARAM = "content=all";
+    String RESTCONF_CONTENT_PASSTHROUGH_RUNNING_QUERY_PARAM = "content=config";
+
     /**
      * This method fetches all modules for given Cm Handle.
      *
@@ -60,41 +65,24 @@ public interface DmiService {
     YangResources getModuleResources(String cmHandle, List<ModuleReference> modules);
 
     /**
-     * This method use to fetch the resource data from cm handle for datastore pass-through operational and resource
-     * Identifier. Options query parameter are used to filter the response from network resource.
-     *
-     * @param cmHandle            cm handle identifier
-     * @param resourceIdentifier  resource identifier
-     * @param acceptParamInHeader accept header parameter
-     * @param optionsParamInQuery options query parameter
-     * @param cmHandlePropertyMap cm handle properties
-     * @return {@code Object} response from network function
-     */
-    Object getResourceDataOperationalForCmHandle(@NotNull String cmHandle,
-        @NotNull String resourceIdentifier,
-        String acceptParamInHeader,
-        String optionsParamInQuery,
-        Map<String, String> cmHandlePropertyMap);
-
-    /**
-     * This method use to fetch the resource data from cm handle for datastore pass-through running and resource
+     * This method use to fetch the resource data from cm handle for the given datastore and resource
      * Identifier. Options query parameter are used to filter the response from network resource.
      *
-     * @param cmHandle            cm handle identifier
-     * @param resourceIdentifier  resource identifier
-     * @param acceptParamInHeader accept header parameter
-     * @param optionsParamInQuery options query parameter
-     * @param cmHandlePropertyMap cm handle properties
+     * @param cmHandle                  cm handle identifier
+     * @param resourceIdentifier        resource identifier
+     * @param acceptParamInHeader       accept header parameter
+     * @param optionsParamInQuery       options query parameter
+     * @param restconfContentQueryParam restconf content i.e. datastore to use
      * @return {@code Object} response from network function
      */
-    Object getResourceDataPassThroughRunningForCmHandle(@NotNull String cmHandle,
+    String getResourceData(@NotNull String cmHandle,
         @NotNull String resourceIdentifier,
         String acceptParamInHeader,
         String optionsParamInQuery,
-        Map<String, String> cmHandlePropertyMap);
+        String restconfContentQueryParam);
 
     /**
-     * Write resource data to sdnc using passthrough running.
+     * Write resource data to sdnc (will default to 'content=config', does not need to be specified).
      *
      * @param cmHandle           cmHandle
      * @param resourceIdentifier resource identifier
@@ -102,6 +90,7 @@ public interface DmiService {
      * @param data               request data
      * @return response from sdnc
      */
-    String writeResourceDataPassthroughForCmHandle(String cmHandle, String resourceIdentifier, String dataType,
-        String data);
+    String writeData(DataAccessRequest.OperationEnum operation, String cmHandle,
+                     String resourceIdentifier, String dataType,
+                     String data);
 }
index 10ae1cf..99127e6 100644 (file)
@@ -29,8 +29,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
-import javax.validation.constraints.NotNull;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.ncmp.dmi.config.DmiPluginConfig.DmiPluginProperties;
 import org.onap.cps.ncmp.dmi.exception.CmHandleRegistrationException;
@@ -38,6 +36,7 @@ import org.onap.cps.ncmp.dmi.exception.DmiException;
 import org.onap.cps.ncmp.dmi.exception.ModuleResourceNotFoundException;
 import org.onap.cps.ncmp.dmi.exception.ModulesNotFoundException;
 import org.onap.cps.ncmp.dmi.exception.ResourceDataNotFound;
+import org.onap.cps.ncmp.dmi.model.DataAccessRequest;
 import org.onap.cps.ncmp.dmi.model.ModuleSet;
 import org.onap.cps.ncmp.dmi.model.ModuleSetSchemas;
 import org.onap.cps.ncmp.dmi.model.YangResource;
@@ -60,8 +59,6 @@ public class DmiServiceImpl implements DmiService {
     private NcmpRestClient ncmpRestClient;
     private ObjectMapper objectMapper;
     private DmiPluginProperties dmiPluginProperties;
-    private static final String RESTCONF_CONTENT_PASSTHROUGH_OPERATIONAL_QUERY_PARAM = "content=all";
-    private static final String REST_CONF_CONTENT_PASSTHROUGH_RUNNING_QUERY_PARAM = "content=config";
     private static final String RESPONSE_CODE = "response code : ";
     private static final String MESSAGE = " message : ";
     private static final String IETF_NETCONF_MONITORING_OUTPUT = "ietf-netconf-monitoring:output";
@@ -151,40 +148,26 @@ public class DmiServiceImpl implements DmiService {
     }
 
     @Override
-    public Object getResourceDataOperationalForCmHandle(final @NotNull String cmHandle,
-        final @NotNull String resourceIdentifier,
+    public String getResourceData(final String cmHandle,
+        final String resourceIdentifier,
         final String acceptParamInHeader,
         final String optionsParamInQuery,
-        final Map<String, String> cmHandlePropertyMap) {
-        // not using cmHandlePropertyMap of onap dmi impl , other dmi impl might use this.
+        final String restconfContentQueryParam) {
         final ResponseEntity<String> responseEntity = sdncOperations.getResouceDataForOperationalAndRunning(cmHandle,
             resourceIdentifier,
             optionsParamInQuery,
             acceptParamInHeader,
-            RESTCONF_CONTENT_PASSTHROUGH_OPERATIONAL_QUERY_PARAM);
+            restconfContentQueryParam);
         return prepareAndSendResponse(responseEntity, cmHandle);
     }
 
     @Override
-    public Object getResourceDataPassThroughRunningForCmHandle(final @NotNull String cmHandle,
-        final @NotNull String resourceIdentifier,
-        final String acceptParamInHeader,
-        final String optionsParamInQuery,
-        final Map<String, String> cmHandlePropertyMap) {
-        // not using cmHandlePropertyMap of onap dmi impl , other dmi impl might use this.
-        final ResponseEntity<String> responseEntity = sdncOperations.getResouceDataForOperationalAndRunning(cmHandle,
-            resourceIdentifier,
-            optionsParamInQuery,
-            acceptParamInHeader,
-            REST_CONF_CONTENT_PASSTHROUGH_RUNNING_QUERY_PARAM);
-        return prepareAndSendResponse(responseEntity, cmHandle);
-    }
-
-    @Override
-    public String writeResourceDataPassthroughForCmHandle(final String cmHandle, final String resourceIdentifier,
-        final String dataType, final String data) {
+    public String writeData(final DataAccessRequest.OperationEnum operation,
+                            final String cmHandle,
+                            final String resourceIdentifier,
+                            final String dataType, final String data) {
         final ResponseEntity<String> responseEntity =
-            sdncOperations.writeResourceDataPassthroughRunning(cmHandle, resourceIdentifier, dataType, data);
+            sdncOperations.writeData(operation, cmHandle, resourceIdentifier, dataType, data);
         if (responseEntity.getStatusCode().is2xxSuccessful()) {
             return responseEntity.getBody();
         } else {
index b8e33df..cf7b459 100644 (file)
@@ -57,28 +57,30 @@ public class SdncRestconfClient {
      * @return the response entity
      */
     public ResponseEntity<String> getOperation(final String getResourceUrl, final HttpHeaders httpHeaders) {
-        final String sdncBaseUrl = sdncProperties.getBaseUrl();
-        final String sdncRestconfUrl = sdncBaseUrl.concat(getResourceUrl);
-        httpHeaders.setBasicAuth(sdncProperties.getAuthUsername(), sdncProperties.getAuthPassword());
-        final var httpEntity = new HttpEntity<>(httpHeaders);
-        return restTemplate.exchange(sdncRestconfUrl,
-                HttpMethod.GET, httpEntity, String.class);
+        return  httpOperationWithJsonData(HttpMethod.GET, getResourceUrl, null, httpHeaders);
     }
 
     /**
-     * restconf post operation on sdnc.
+     * restconf http operations on sdnc.
      *
-     * @param postResourceUrl sdnc post resource url
-     * @param jsonData        json data
-     * @param httpHeaders     HTTP headers
-     * @return the response entity
+     * @param httpMethod HTTP Method
+     * @param resourceUrl sdnc resource url
+     * @param jsonData json data
+     * @param httpHeaders HTTP Headers
+     * @return response entity
      */
-    public ResponseEntity<String> postOperationWithJsonData(final String postResourceUrl,
-        final String jsonData, final HttpHeaders httpHeaders) {
-        final var sdncBaseUrl = sdncProperties.getBaseUrl();
-        final var sdncRestconfUrl = sdncBaseUrl.concat(postResourceUrl);
+    public ResponseEntity<String> httpOperationWithJsonData(final HttpMethod httpMethod, final String resourceUrl,
+                                                             final String jsonData,
+                                                             final HttpHeaders httpHeaders) {
+        final String sdncBaseUrl = sdncProperties.getBaseUrl();
+        final String sdncRestconfUrl = sdncBaseUrl.concat(resourceUrl);
         httpHeaders.setBasicAuth(sdncProperties.getAuthUsername(), sdncProperties.getAuthPassword());
-        final var httpEntity = new HttpEntity<>(jsonData, httpHeaders);
-        return restTemplate.exchange(sdncRestconfUrl, HttpMethod.POST, httpEntity, String.class);
+        final HttpEntity<String> httpEntity;
+        if (jsonData == null) {
+            httpEntity = new HttpEntity<>(httpHeaders);
+        } else {
+            httpEntity = new HttpEntity<>(jsonData, httpHeaders);
+        }
+        return restTemplate.exchange(sdncRestconfUrl, httpMethod, httpEntity, String.class);
     }
-}
\ No newline at end of file
+}
index 43e2a5e..ced9b06 100644 (file)
@@ -35,9 +35,11 @@ import java.util.List;
 import org.apache.groovy.parser.antlr4.util.StringUtils;
 import org.onap.cps.ncmp.dmi.config.DmiConfiguration.SdncProperties;
 import org.onap.cps.ncmp.dmi.exception.SdncException;
+import org.onap.cps.ncmp.dmi.model.DataAccessRequest;
 import org.onap.cps.ncmp.dmi.service.client.SdncRestconfClient;
 import org.onap.cps.ncmp.dmi.service.model.ModuleSchema;
 import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
@@ -110,8 +112,8 @@ public class SdncOperations {
         final var getYangResourceUrl = prepareGetOperationSchemaUrl(nodeId);
         final var httpHeaders = new HttpHeaders();
         httpHeaders.setContentType(MediaType.APPLICATION_JSON);
-        return sdncRestconfClient
-            .postOperationWithJsonData(getYangResourceUrl, moduleProperties, httpHeaders);
+        return sdncRestconfClient.httpOperationWithJsonData(
+            HttpMethod.POST, getYangResourceUrl, moduleProperties, httpHeaders);
     }
 
     /**
@@ -140,7 +142,7 @@ public class SdncOperations {
     }
 
     /**
-     * Write resource data using passthrough running.
+     * Write resource data.
      *
      * @param nodeId      network resource identifier
      * @param resourceId  resource identifier
@@ -148,12 +150,16 @@ public class SdncOperations {
      * @param requestData request data
      * @return {@code ResponseEntity} response entity
      */
-    public ResponseEntity<String> writeResourceDataPassthroughRunning(final String nodeId,
-        final String resourceId, final String contentType, final String requestData) {
-        final var getResourceDataUrl = preparePassthroughRunningUrl(nodeId, resourceId);
+    public ResponseEntity<String> writeData(final DataAccessRequest.OperationEnum operation,
+                                            final String nodeId,
+                                            final String resourceId,
+                                            final String contentType,
+                                            final String requestData) {
+        final var getResourceDataUrl = prepareWriteUrl(nodeId, resourceId);
         final var httpHeaders = new HttpHeaders();
         httpHeaders.setContentType(MediaType.parseMediaType(contentType));
-        return sdncRestconfClient.postOperationWithJsonData(getResourceDataUrl, requestData, httpHeaders);
+        final HttpMethod httpMethod = getHttpMethod(operation);
+        return sdncRestconfClient.httpOperationWithJsonData(httpMethod, getResourceDataUrl, requestData, httpHeaders);
     }
 
     private List<String> buildQueryParamList(final String optionsParamInQuery, final String restconfContentQueryParam) {
@@ -179,7 +185,7 @@ public class SdncOperations {
         return addResource(addTopologyDataUrlwithNode(nodeId), GET_SCHEMA_URL);
     }
 
-    private String preparePassthroughRunningUrl(final String nodeId, final String resourceId) {
+    private String prepareWriteUrl(final String nodeId, final String resourceId) {
         return addResource(addTopologyDataUrlwithNode(nodeId), "/" + resourceId);
     }
 
@@ -233,4 +239,25 @@ public class SdncOperations {
         }
     }
 
-}
\ No newline at end of file
+    private HttpMethod getHttpMethod(final DataAccessRequest.OperationEnum operation) {
+        HttpMethod httpMethod = null;
+        switch (operation) {
+            case READ:
+                httpMethod = HttpMethod.GET;
+                break;
+            case CREATE:
+                httpMethod = HttpMethod.POST;
+                break;
+            case UPDATE:
+                httpMethod = HttpMethod.PUT;
+                break;
+            case DELETE:
+                httpMethod = HttpMethod.DELETE;
+                break;
+            default:
+                //unreachable code but checkstyle made me do this!
+        }
+        return httpMethod;
+    }
+
+}
index 1446a5a..221603c 100644 (file)
@@ -43,8 +43,15 @@ import org.springframework.security.test.context.support.WithMockUser
 import org.springframework.test.web.servlet.MockMvc
 import spock.lang.Specification
 
+import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.DELETE
+import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.READ
+import static org.springframework.http.HttpStatus.BAD_REQUEST
+import static org.springframework.http.HttpStatus.NO_CONTENT
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
+import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.CREATE
+import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.UPDATE
+import static org.springframework.http.HttpStatus.CREATED
+import static org.springframework.http.HttpStatus.OK
 
 @WebMvcTest(DmiRestController)
 @WithMockUser
@@ -60,7 +67,7 @@ class DmiRestControllerSpec extends Specification {
     @Value('${rest.api.dmi-base-path}/v1')
     def basePathV1
 
-    def 'Get all modules for given cm handle.'() {
+    def 'Get all modules.'() {
         given: 'REST endpoint for getting all modules'
             def getModuleUrl = "$basePathV1/ch/node1/modules"
         and: 'get modules for cm-handle returns a json'
@@ -77,12 +84,12 @@ class DmiRestControllerSpec extends Specification {
                     .contentType(MediaType.APPLICATION_JSON).content(json))
                     .andReturn().response
         then: 'status is OK'
-            response.status == HttpStatus.OK.value()
+            response.status == OK.value()
         and: 'the response content matches the result from the DMI service'
             response.getContentAsString() == '{"schemas":[{"moduleName":"some-moduleName","revision":"some-revision","namespace":"some-namespace"}]}'
     }
 
-    def 'Get all modules for given cm handle with exception handling of #scenario.'() {
+    def 'Get all modules with exception handling of #scenario.'() {
         given: 'REST endpoint for getting all modules'
             def getModuleUrl = "$basePathV1/ch/node1/modules"
         and: 'given request body and get modules for cm-handle throws #exceptionClass'
@@ -101,20 +108,20 @@ class DmiRestControllerSpec extends Specification {
             'any other runtime exception'  |  RuntimeException.class         || HttpStatus.INTERNAL_SERVER_ERROR.value()
     }
 
-    def 'Register given list of cm handles.'() {
+    def 'Register given list.'() {
         given: 'register cm handle url and cm handles json'
             def registerCmhandlesPost = "${basePathV1}/inventory/cmHandles"
             def cmHandleJson = '{"cmHandles":["node1", "node2"]}'
-        when: 'post register cm handles api is invoked'
+        when: 'register cm handles api is invoked with POST'
             def response = mvc.perform(
                     post(registerCmhandlesPost)
                             .contentType(MediaType.APPLICATION_JSON)
                             .content(cmHandleJson)
             ).andReturn().response
-        then: 'register cm handles in dmi service is called once'
+        then: 'register cm handles in dmi service is invoked with correct parameters'
             1 * mockDmiService.registerCmHandles(_ as List<String>)
         and: 'response status is created'
-            response.status == HttpStatus.CREATED.value()
+            response.status == CREATED.value()
     }
 
     def 'register cm handles called with empty content.'() {
@@ -127,7 +134,7 @@ class DmiRestControllerSpec extends Specification {
                             .content(emptyJson)
             ).andReturn().response
         then: 'response status is "bad request"'
-            response.status == HttpStatus.BAD_REQUEST.value()
+            response.status == BAD_REQUEST.value()
         and: 'dmi service is not called'
             0 * mockDmiService.registerCmHandles(_)
     }
@@ -149,7 +156,7 @@ class DmiRestControllerSpec extends Specification {
                     .contentType(MediaType.APPLICATION_JSON)
                     .content(jsonData)).andReturn().response
         then: 'a OK status is returned'
-            response.status == HttpStatus.OK.value()
+            response.status == OK.value()
         and: 'the expected response is returned'
             response.getContentAsString() == '[{"yangSource":"\\"some-data\\"","moduleName":"NAME","revision":"REVISION"}]'
     }
@@ -168,68 +175,105 @@ class DmiRestControllerSpec extends Specification {
             response.status == HttpStatus.NOT_FOUND.value()
     }
 
-    def 'Get resource data for pass-through operational from cm handle.'() {
+    def 'Get resource data for pass-through operational.'() {
         given: 'Get resource data url'
             def getResourceDataForCmHandleUrl = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-operational" +
                     "?resourceIdentifier=parent/child&options=(fields=myfields,depth=5)"
             def json = '{"cmHandleProperties" : { "prop1" : "value1", "prop2" : "value2"}}'
-        when: 'get resource data PUT api is invoked'
+        when: 'get resource data POST api is invoked'
             def response = mvc.perform(
-                    put(getResourceDataForCmHandleUrl).contentType(MediaType.APPLICATION_JSON)
+                    post(getResourceDataForCmHandleUrl).contentType(MediaType.APPLICATION_JSON)
                             .accept(MediaType.APPLICATION_JSON).content(json)
             ).andReturn().response
         then: 'response status is ok'
-            response.status == HttpStatus.OK.value()
-        and: 'dmi service called with get resource data for cm handle'
-            1 * mockDmiService.getResourceDataOperationalForCmHandle('some-cmHandle',
+            response.status == OK.value()
+        and: 'dmi service called with get resource data'
+            1 * mockDmiService.getResourceData('some-cmHandle',
                     'parent/child',
                     'application/json',
                     '(fields=myfields,depth=5)',
-                    ['prop1': 'value1', 'prop2': 'value2'])
+                    'content=all')
     }
 
-    def 'Write data using passthrough running for a cm handle using #scenario.'() {
-        given: 'write data for cmHandle url and jsonData'
-            def writeDataforCmHandlePassthroughRunning = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-running" +
+    def 'Get resource data for pass-through operational with bad request.'() {
+        given: 'Get resource data url'
+            def getResourceDataForCmHandleUrl = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-operational" +
+                "?resourceIdentifier=parent/child&options=(fields=myfields,depth=5)"
+            def jsonData = TestUtils.getResourceFileContent('createDataWithNormalChar.json')
+        when: 'get resource data POST api is invoked'
+            def response = mvc.perform(
+                post(getResourceDataForCmHandleUrl).contentType(MediaType.APPLICATION_JSON)
+                    .accept(MediaType.APPLICATION_JSON).content(jsonData)
+            ).andReturn().response
+        then: 'response status is bad request'
+            response.status == BAD_REQUEST.value()
+        and: 'dmi service is not invoked'
+            0 * mockDmiService.getResourceData(*_)
+    }
+
+    def 'write data with #scenario operation using passthrough running.'() {
+        given: 'write data for passthrough running url and jsonData'
+            def writeDataForPassthroughRunning = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-running" +
                     "?resourceIdentifier=some-resourceIdentifier"
             def jsonData = TestUtils.getResourceFileContent(requestBodyFile)
         and: 'dmi service is called'
-            mockDmiService.writeResourceDataPassthroughForCmHandle('some-cmHandle',
+            mockDmiService.writeData(operationEnum, 'some-cmHandle',
                     'some-resourceIdentifier', 'application/json',
-                    expectedRequestData) >> '{some-json}'
-        when: 'write cmHandle passthrough running post api is invoked with json data'
+                    'normal request body' ) >> '{some-json}'
+        when: 'write data for passthrough running post api is invoked with json data'
             def response = mvc.perform(
-                    post(writeDataforCmHandlePassthroughRunning).contentType(MediaType.APPLICATION_JSON)
+                    post(writeDataForPassthroughRunning).contentType(MediaType.APPLICATION_JSON)
                             .content(jsonData)
             ).andReturn().response
-       then: 'response status is 201 CREATED'
-            response.status == HttpStatus.CREATED.value()
+       then: 'response status is #expectedResponseStatus'
+            response.status == expectedResponseStatus
         and: 'the data in the request body is as expected'
-            response.getContentAsString() == '{some-json}'
+            response.getContentAsString() == expectedJsonResponse
         where: 'given request body and data'
-            scenario                  | requestBodyFile           || expectedRequestData
-            'data with normal chars'  | 'dataWithNormalChar.json' || 'normal request body'
-            'data with special chars' | 'dataWithSpecialChar.json'|| 'data with quote \" and new line \n'
+            scenario   | requestBodyFile                 | operationEnum                                  || expectedResponseStatus | expectedJsonResponse
+            'Create'   | 'createDataWithNormalChar.json' | CREATE                                         || CREATED.value()        | '{some-json}'
+            'Update'   | 'updateData.json'               | UPDATE                                         || OK.value()             | '{some-json}'
+            'Delete'   | 'deleteData.json'               | DELETE                                         || NO_CONTENT.value()     | '{some-json}'
+            'Read'     | 'readData.json'                 | READ                                           || OK.value()             | ''
     }
 
-    def 'Get resource data for pass-through running from cm handle with #scenario value in resource identifier param.'() {
+    def 'Create data using passthrough for special characters.'(){
+         given: 'create data for cmHandle url and JsonData'
+            def writeDataForCmHandlePassthroughRunning = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-running" +
+             "?resourceIdentifier=some-resourceIdentifier"
+            def jsonData = TestUtils.getResourceFileContent('createDataWithSpecialChar.json')
+         and: 'dmi service is called'
+            mockDmiService.writeData(CREATE, 'some-cmHandle', 'some-resourceIdentifier', 'application/json',
+                'data with quote \" and new line \n') >> '{some-json}'
+         when: 'create cmHandle passthrough running post api is invoked with json data with special chars'
+            def response = mvc.perform(
+                post(writeDataForCmHandlePassthroughRunning).contentType(MediaType.APPLICATION_JSON).content(jsonData)
+            ).andReturn().response
+         then: 'response status is CREATED'
+            response.status == CREATED.value()
+         and: 'the data in the request body is as expected'
+            response.getContentAsString() == '{some-json}'
+    }
+
+
+    def 'Get resource data for pass-through running with #scenario value in resource identifier param.'() {
         given: 'Get resource data url'
             def getResourceDataForCmHandleUrl = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-running" +
                     "?resourceIdentifier="+resourceIdentifier+"&options=(fields=myfields,depth=5)"
             def json = '{"cmHandleProperties" : { "prop1" : "value1", "prop2" : "value2"}}'
-        when: 'get resource data PUT api is invoked'
+        when: 'get resource data POST api is invoked'
             def response = mvc.perform(
-                    put(getResourceDataForCmHandleUrl).contentType(MediaType.APPLICATION_JSON)
+                    post(getResourceDataForCmHandleUrl).contentType(MediaType.APPLICATION_JSON)
                             .accept(MediaType.APPLICATION_JSON).content(json)
             ).andReturn().response
         then: 'response status is ok'
-            response.status == HttpStatus.OK.value()
-        and: 'dmi service called with get resource data for cm handle'
-            1 * mockDmiService.getResourceDataPassThroughRunningForCmHandle('some-cmHandle',
+            response.status == OK.value()
+        and: 'dmi service called with get resource data for cm handle'
+            1 * mockDmiService.getResourceData('some-cmHandle',
                     resourceIdentifier,
                     'application/json',
                     '(fields=myfields,depth=5)',
-                    ['prop1':'value1', 'prop2':'value2'])
+                    'content=config')
         where: 'tokens are used in the resource identifier parameter'
             scenario                       | resourceIdentifier
             '/'                            | 'id/with/slashes'
index d535375..a463a34 100644 (file)
@@ -40,6 +40,9 @@ import org.springframework.http.HttpStatus
 import org.springframework.http.ResponseEntity
 import spock.lang.Specification
 
+import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.CREATE
+import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.UPDATE
+
 class DmiServiceImplSpec extends Specification {
 
 
@@ -191,8 +194,8 @@ class DmiServiceImplSpec extends Specification {
             thrownException.cause == jsonProcessingException
     }
 
-    def 'Get resource data for pass through operational from cm handle.'() {
-        given: 'cm-handle, pass through parameter, resourceId, accept header, fields, depth'
+    def 'Get resource data for passthrough operational.'() {
+        given: 'cm-handle, passthrough parameter, resourceId, accept header, fields, depth'
             def cmHandle = 'testCmHandle'
             def resourceId = 'testResourceId'
             def acceptHeaderParam = 'testAcceptParam'
@@ -201,31 +204,32 @@ class DmiServiceImplSpec extends Specification {
         and: 'sdnc operation returns OK response'
             mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, optionsParam, acceptHeaderParam, contentQuery) >> new ResponseEntity<>('response json', HttpStatus.OK)
         when: 'get resource data from cm handles service method invoked'
-            def response = objectUnderTest.getResourceDataOperationalForCmHandle(cmHandle,
+            def response = objectUnderTest.getResourceData(cmHandle,
                 resourceId, acceptHeaderParam,
-                optionsParam, null)
+                optionsParam, contentQuery)
         then: 'response have expected json'
             response == 'response json'
     }
 
-    def 'Get resource data from cm handle with exception.'() {
-        given: 'cm-handle, pass through parameter, resourceId, accept header, fields, depth'
+    def 'Get resource data with not found exception.'() {
+        given: 'cm-handle, passthrough parameter, resourceId, accept header, fields, depth, query param'
             def cmHandle = 'testCmHandle'
             def resourceId = 'testResourceId'
             def acceptHeaderParam = 'testAcceptParam'
             def optionsParam = '(fields=x/y/z,depth=10,test=abc)'
+            def restConfQueryParam = 'content=config'
         and: 'sdnc operation returns "NOT_FOUND" response'
             mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, optionsParam, acceptHeaderParam, _ as String) >> new ResponseEntity<>(HttpStatus.NOT_FOUND)
         when: 'get resource data from cm handles service method invoked'
-            objectUnderTest.getResourceDataOperationalForCmHandle(cmHandle,
+            objectUnderTest.getResourceData(cmHandle,
                 resourceId, acceptHeaderParam,
-                optionsParam, null)
+                optionsParam, restConfQueryParam)
         then: 'resource data not found'
             thrown(ResourceDataNotFound.class)
     }
 
-    def 'Get resource data for pass through running from cm handle.'() {
-        given: 'cm-handle, pass through parameter, resourceId, accept header, fields, depth'
+    def 'Get resource data for passthrough running.'() {
+        given: 'cm-handle, passthrough parameter, resourceId, accept header, fields, depth'
             def cmHandle = 'testCmHandle'
             def resourceId = 'testResourceId'
             def acceptHeaderParam = 'testAcceptParam'
@@ -235,47 +239,43 @@ class DmiServiceImplSpec extends Specification {
             mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, optionsParam,
                 acceptHeaderParam, contentQuery) >> new ResponseEntity<>('response json', HttpStatus.OK)
         when: 'get resource data from cm handles service method invoked'
-            def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle(cmHandle,
+            def response = objectUnderTest.getResourceData(cmHandle,
                 resourceId, acceptHeaderParam,
-                optionsParam, null)
+                optionsParam, contentQuery)
         then: 'response have expected json'
             response == 'response json'
     }
 
-    def 'Write resource data for passthrough running for the given cm handle with a #scenario from sdnc.'() {
+    def 'Write resource data for passthrough running with a #scenario from sdnc.'() {
         given: 'sdnc returns a response with #scenario'
-            mockSdncOperations.writeResourceDataPassthroughRunning(_, _, _, _) >> new ResponseEntity<String>('response json', httpResponse)
+            mockSdncOperations.writeData(operationEnum, _, _, _, _) >> new ResponseEntity<String>('response json', httpResponse)
         when: 'write resource data for cm handle method invoked'
-            def response = objectUnderTest.writeResourceDataPassthroughForCmHandle('some-cmHandle',
+            def response = objectUnderTest.writeData(operationEnum,'some-cmHandle',
                 'some-resourceIdentifier', 'some-dataType', '{some-data}')
         then: 'the response contains the expected json data from sdnc'
             response == 'response json'
         where: 'the following values are used'
-            scenario               | httpResponse
-            '200 OK response'      | HttpStatus.OK
-            '201 CREATED response' | HttpStatus.CREATED
+            scenario                              | httpResponse       | operationEnum
+            '200 OK with an update operation'     | HttpStatus.OK      | UPDATE
+            '201 CREATED with a create operation' | HttpStatus.CREATED | CREATE
     }
 
-    def 'Write resource data using for passthrough running for the given cm handle with #scenario.'() {
+    def 'Write resource data with special characters.'() {
         given: 'sdnc returns a created response'
-            mockSdncOperations.writeResourceDataPassthroughRunning('some-cmHandle',
-                'some-resourceIdentifier', 'some-dataType', requestBody) >> new ResponseEntity<String>('response json', HttpStatus.CREATED)
+            mockSdncOperations.writeData(CREATE, 'some-cmHandle',
+                'some-resourceIdentifier', 'some-dataType', 'data with quote " and \n new line') >> new ResponseEntity<String>('response json', HttpStatus.CREATED)
         when: 'write resource data from cm handles service method invoked'
-            def response = objectUnderTest.writeResourceDataPassthroughForCmHandle('some-cmHandle',
-                'some-resourceIdentifier', 'some-dataType', requestBody)
+            def response = objectUnderTest.writeData(CREATE, 'some-cmHandle',
+                'some-resourceIdentifier', 'some-dataType', 'data with quote " and \n new line')
         then: 'response have expected json'
             response == 'response json'
-        where: 'given request body'
-            scenario                           | requestBody
-            'data contains normal char'        | 'normal char string'
-            'data contains quote and new line' | 'data with quote " and \n new line'
     }
 
     def 'Write resource data for passthrough running with a 500 response from sdnc.'() {
         given: 'sdnc returns a 500 response for the write operation'
-            mockSdncOperations.writeResourceDataPassthroughRunning(_, _, _, _) >> new ResponseEntity<String>('response json', HttpStatus.INTERNAL_SERVER_ERROR)
-        when: 'write resource data for pass through method is invoked'
-            objectUnderTest.writeResourceDataPassthroughForCmHandle('some-cmHandle',
+            mockSdncOperations.writeData(CREATE, _, _, _, _) >> new ResponseEntity<String>('response json', HttpStatus.INTERNAL_SERVER_ERROR)
+        when: 'write resource data for passthrough method is invoked'
+            objectUnderTest.writeData(CREATE, 'some-cmHandle',
                 'some-resourceIdentifier', 'some-dataType', _ as String)
         then: 'a dmi exception is thrown'
             thrown(DmiException.class)
index 2184c7e..8a3170b 100644 (file)
@@ -28,6 +28,11 @@ import org.springframework.http.ResponseEntity
 import org.springframework.web.client.RestTemplate
 import spock.lang.Specification
 
+import static org.springframework.http.HttpMethod.GET
+import static org.springframework.http.HttpMethod.POST
+import static org.springframework.http.HttpMethod.DELETE
+import static org.springframework.http.HttpMethod.PUT
+
 class SdncRestconfClientSpec extends Specification {
 
     def mockSdncProperties = Mock(DmiConfiguration.SdncProperties)
@@ -49,7 +54,7 @@ class SdncRestconfClientSpec extends Specification {
             result == mockResponseEntity
     }
 
-    def 'SDNC POST operation called.'() {
+    def 'SDNC #scenario operation called.'() {
         given: 'json data'
             def jsonData = 'some-json'
         and: 'a url for get module resources'
@@ -59,12 +64,18 @@ class SdncRestconfClientSpec extends Specification {
         and: 'the rest template returns a valid response entity'
             def mockResponseEntity = Mock(ResponseEntity)
         when: 'get module resources is invoked'
-            def result = objectUnderTest.postOperationWithJsonData(getModuleResourceUrl, jsonData, new HttpHeaders())
+            def result = objectUnderTest.httpOperationWithJsonData(expectedHttpMethod, getModuleResourceUrl, jsonData, new HttpHeaders())
         then: 'the rest template is called with the correct uri and json in the body'
             1 * mockRestTemplate.exchange({ it.toString() == 'http://some-uri/getModuleResourceUrl' },
-                    HttpMethod.POST, { it.body.contains(jsonData) }, String.class) >> mockResponseEntity
+                    expectedHttpMethod, { it.body.contains(jsonData) }, String.class) >> mockResponseEntity
         and: 'the output of the method is the same as the output from the test template'
             result == mockResponseEntity
+        where: 'the following values are used'
+            scenario || expectedHttpMethod
+            'POST'   || POST
+            'PUT'    || PUT
+            'GET'    || GET
+            'DELETE' || DELETE
     }
 
     def 'SDNC GET operation with header.'() {
index 2ce870a..5079ada 100644 (file)
@@ -29,11 +29,17 @@ import org.spockframework.spring.SpringBean
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.test.context.SpringBootTest
 import org.springframework.http.HttpHeaders
+import org.springframework.http.HttpMethod
 import org.springframework.http.HttpStatus
 import org.springframework.http.ResponseEntity
 import org.springframework.test.context.ContextConfiguration
 import spock.lang.Specification
 
+import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.CREATE
+import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.DELETE
+import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.UPDATE
+import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.READ
+
 @SpringBootTest
 @ContextConfiguration(classes = [DmiConfiguration.SdncProperties, SdncOperations])
 class SdncOperationsSpec extends Specification {
@@ -106,7 +112,7 @@ class SdncOperationsSpec extends Specification {
         when: 'get module resources is called with the expected parameters'
             objectUnderTest.getModuleResource(nodeId, 'some-json-data')
         then: 'the SDNC Rest client is invoked with the correct URL and json data'
-            1 * mockSdncRestClient.postOperationWithJsonData(expectedUrl, 'some-json-data', _ as HttpHeaders)
+            1 * mockSdncRestClient.httpOperationWithJsonData(HttpMethod.POST, expectedUrl, 'some-json-data', _ as HttpHeaders)
     }
 
     def 'Get resource data from node to SDNC.'() {
@@ -119,13 +125,19 @@ class SdncOperationsSpec extends Specification {
             1 * mockSdncRestClient.getOperation(expectedUrl, _ as HttpHeaders)
     }
 
-    def 'Write resource data to SDNC.'() {
+    def 'Write resource data with #scenario operation to SDNC.'() {
         given: 'expected url, topology-id, sdncOperation object'
             def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/testResourceId'
-        when: 'write resource data for pass through running is called'
-            objectUnderTest.writeResourceDataPassthroughRunning('node1', 'testResourceId', 'application/json', 'requestData')
-        then: 'the post operation is executed with the correct URL and data'
-            1 * mockSdncRestClient.postOperationWithJsonData(expectedUrl, 'requestData', _ as HttpHeaders)
+        when: 'write resource data for passthrough running is called'
+            objectUnderTest.writeData(operationEnum, 'node1', 'testResourceId', 'application/json', 'requestData')
+        then: 'the #expectedHttpMethod operation is executed with the correct URL and data'
+            1 * mockSdncRestClient.httpOperationWithJsonData(expectedHttpMethod, expectedUrl, 'requestData', _ as HttpHeaders)
+        where: 'the following values are used'
+            scenario  | operationEnum  || expectedHttpMethod
+            'Create'  | CREATE         || HttpMethod.POST
+            'Update'  | UPDATE         || HttpMethod.PUT
+            'Read'    | READ           || HttpMethod.GET
+            'Delete'  | DELETE         || HttpMethod.DELETE
     }
 
     def 'build query param list for SDNC where options contains a #scenario'() {
diff --git a/src/test/resources/deleteData.json b/src/test/resources/deleteData.json
new file mode 100644 (file)
index 0000000..2233fa0
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "operation": "delete",
+  "dataType": "application/json",
+  "data": "normal request body",
+  "cmHandleProperties": {
+    "some-property": "some-property-value"
+  }
+}
\ No newline at end of file
diff --git a/src/test/resources/readData.json b/src/test/resources/readData.json
new file mode 100644 (file)
index 0000000..9f2b154
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "operation": "read",
+  "dataType": "application/json",
+  "data": "normal request body",
+  "cmHandleProperties": {
+    "some-property": "some-property-value"
+  }
+}
\ No newline at end of file
diff --git a/src/test/resources/updateData.json b/src/test/resources/updateData.json
new file mode 100644 (file)
index 0000000..7cbf4f0
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "operation": "update",
+  "dataType": "application/json",
+  "data": "normal request body",
+  "cmHandleProperties": {
+    "some-property": "some-property-value"
+  }
+}
\ No newline at end of file