summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToine Siebelink <toine.siebelink@est.tech>2021-11-12 15:38:55 +0000
committerGerrit Code Review <gerrit@onap.org>2021-11-12 15:38:55 +0000
commit69662af73d817fa0bbf9d07f1a965594ca5bcef9 (patch)
tree572b802caf6ff200104cd4e1b4f87e75f83bed38
parent02ee56be9d2ceaac2e8aa9069aecb3f44b5164c7 (diff)
parent5fe0daebb1360bd5d4c525125cdb0d6250583ff4 (diff)
Merge "Support Update and Delete operations for DS Passtrough-Running in DMI Plugin"
-rw-r--r--docs/api/swagger/openapi.yaml159
-rw-r--r--openapi/components.yml13
-rw-r--r--openapi/openapi.yml77
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java124
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java47
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java37
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java38
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java45
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy118
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy60
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy17
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy24
-rw-r--r--src/test/resources/createDataWithNormalChar.json (renamed from src/test/resources/dataWithNormalChar.json)0
-rw-r--r--src/test/resources/createDataWithSpecialChar.json (renamed from src/test/resources/dataWithSpecialChar.json)0
-rw-r--r--src/test/resources/deleteData.json8
-rw-r--r--src/test/resources/readData.json8
-rw-r--r--src/test/resources/updateData.json8
17 files changed, 398 insertions, 385 deletions
diff --git a/docs/api/swagger/openapi.yaml b/docs/api/swagger/openapi.yaml
index 750091b4..54676fe5 100644
--- a/docs/api/swagger/openapi.yaml
+++ b/docs/api/swagger/openapi.yaml
@@ -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
@@ -274,63 +278,10 @@ paths:
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:
diff --git a/openapi/components.yml b/openapi/components.yml
index 30e5987f..cdf4c1c0 100644
--- a/openapi/components.yml
+++ b/openapi/components.yml
@@ -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:
diff --git a/openapi/openapi.yml b/openapi/openapi.yml
index 0f43f9a5..5c095a7a 100644
--- a/openapi/openapi.yml
+++ b/openapi/openapi.yml
@@ -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'
-
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java b/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
index b17280ae..97848c3e 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
@@ -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;
@@ -74,25 +73,6 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi {
}
/**
- * 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.
*
* @param cmHandles list of cm-handles
@@ -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(
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
index c6910399..0f3fcc0c 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
@@ -21,18 +21,23 @@
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);
}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
index 10ae1cf8..99127e66 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
@@ -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 {
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java b/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java
index b8e33dfc..cf7b4599 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java
@@ -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
+}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java b/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java
index 43e2a5e6..ced9b061 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java
@@ -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;
+ }
+
+}
diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
index 1446a5aa..221603c2 100644
--- a/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
+++ b/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
@@ -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 a 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'
diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
index d5353754..a463a344 100644
--- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
+++ b/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
@@ -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)
diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy
index 2184c7e7..8a3170b4 100644
--- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy
+++ b/src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy
@@ -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.'() {
diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy
index 2ce870ab..5079ada7 100644
--- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy
+++ b/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy
@@ -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/dataWithNormalChar.json b/src/test/resources/createDataWithNormalChar.json
index 31cdf1c5..31cdf1c5 100644
--- a/src/test/resources/dataWithNormalChar.json
+++ b/src/test/resources/createDataWithNormalChar.json
diff --git a/src/test/resources/dataWithSpecialChar.json b/src/test/resources/createDataWithSpecialChar.json
index 1e7622ee..1e7622ee 100644
--- a/src/test/resources/dataWithSpecialChar.json
+++ b/src/test/resources/createDataWithSpecialChar.json
diff --git a/src/test/resources/deleteData.json b/src/test/resources/deleteData.json
new file mode 100644
index 00000000..2233fa01
--- /dev/null
+++ b/src/test/resources/deleteData.json
@@ -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
index 00000000..9f2b154f
--- /dev/null
+++ b/src/test/resources/readData.json
@@ -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
index 00000000..7cbf4f0c
--- /dev/null
+++ b/src/test/resources/updateData.json
@@ -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