summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToine Siebelink <toine.siebelink@est.tech>2021-08-25 13:43:51 +0000
committerGerrit Code Review <gerrit@onap.org>2021-08-25 13:43:51 +0000
commit528022a0f33225f3eab6930ff27c3ab8d1638568 (patch)
tree87170d1b5354ad456ce8a37a04bffa6b3140e309
parentb8f72560c6f29c49ee80672072d6a168351ce00a (diff)
parent79e41e0794035ea8dd3ae3064f8d368b5345df95 (diff)
Merge "Write data for cm handle passthrough:running"
-rw-r--r--docs/openapi/components.yml17
-rw-r--r--docs/openapi/openapi.yml30
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java99
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java70
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java76
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java18
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java63
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy29
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy43
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy2
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy11
-rw-r--r--src/test/resources/WriteDataForCmHandle.json10
12 files changed, 317 insertions, 151 deletions
diff --git a/docs/openapi/components.yml b/docs/openapi/components.yml
index cb39fa4e..ba2a0ece 100644
--- a/docs/openapi/components.yml
+++ b/docs/openapi/components.yml
@@ -58,7 +58,7 @@ components:
namespace:
type: string
- OperationalRequest:
+ DataAccessReadRequest:
type: object
properties:
operation:
@@ -69,6 +69,21 @@ components:
additionalProperties:
type: string
+ DataAccessWriteRequest:
+ type: object
+ properties:
+ operation:
+ type: string
+ enum: [ create ]
+ dataType:
+ type: string
+ data:
+ type: object
+ cmHandleProperties:
+ type: object
+ additionalProperties:
+ type: string
+
responses:
NotFound:
description: The specified resource was not found
diff --git a/docs/openapi/openapi.yml b/docs/openapi/openapi.yml
index af285f4e..f169efd0 100644
--- a/docs/openapi/openapi.yml
+++ b/docs/openapi/openapi.yml
@@ -136,7 +136,7 @@ paths:
content:
application/json:
schema:
- $ref: 'components.yml#/components/schemas/OperationalRequest'
+ $ref: 'components.yml#/components/schemas/DataAccessReadRequest'
responses:
'200':
$ref: 'components.yml#/components/responses/Ok'
@@ -165,7 +165,7 @@ paths:
content:
application/json:
schema:
- $ref: 'components.yml#/components/schemas/OperationalRequest'
+ $ref: 'components.yml#/components/schemas/DataAccessReadRequest'
responses:
'200':
$ref: 'components.yml#/components/responses/Ok'
@@ -175,3 +175,29 @@ paths:
$ref: 'components.yml#/components/responses/Unauthorized'
'403':
$ref: 'components.yml#/components/responses/Forbidden'
+
+ post:
+ description: Write data for a cmHandle using passthrough-running
+ tags:
+ - dmi-plugin
+ summary: Write data for a cmHandle
+ operationId: writeDataByPassthroughRunningForCmHandle
+ parameters:
+ - $ref: 'components.yml#/components/parameters/cmHandleInPath'
+ - $ref: 'components.yml#/components/parameters/resourceIdentifierInPath'
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: 'components.yml#/components/schemas/DataAccessWriteRequest'
+ responses:
+ '200':
+ $ref: 'components.yml#/components/responses/Ok'
+ '400':
+ $ref: 'components.yml#/components/responses/BadRequest'
+ '401':
+ $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 79c11a4e..32651e4d 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
@@ -27,14 +27,16 @@ import javax.validation.Valid;
import javax.validation.constraints.Min;
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.ModuleReference;
import org.onap.cps.ncmp.dmi.model.ModuleRequestParent;
import org.onap.cps.ncmp.dmi.model.ModuleSet;
-import org.onap.cps.ncmp.dmi.model.OperationalRequest;
import org.onap.cps.ncmp.dmi.rest.api.DmiPluginApi;
import org.onap.cps.ncmp.dmi.rest.api.DmiPluginInternalApi;
import org.onap.cps.ncmp.dmi.service.DmiService;
import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -61,7 +63,7 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi {
@Override
public ResponseEntity<Object> retrieveModuleResources(@Valid final ModuleRequestParent moduleRequestParent,
- final String cmHandle) {
+ final String cmHandle) {
if (moduleRequestParent.getOperation().toString().equals("read")) {
final var moduleReferenceList = convertRestObjectToJavaApiObject(moduleRequestParent);
final var response = dmiService.getModuleResources(cmHandle, moduleReferenceList);
@@ -74,6 +76,25 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi {
}
/**
+ * Write data using passthrough for the given cmHandle.
+ *
+ * @param dataAccessWriteRequest pass through request
+ * @param cmHandle cmHandle
+ * @param resourceIdentifier resource identifier
+ * @return (@ code ResponseEntity) response entity
+ */
+ @Override
+ public ResponseEntity<Object> writeDataByPassthroughRunningForCmHandle(
+ final DataAccessWriteRequest dataAccessWriteRequest,
+ final String cmHandle, final String resourceIdentifier) {
+ final String response = dmiService.writeResourceDataPassthroughForCmHandle(cmHandle,
+ resourceIdentifier,
+ MediaType.APPLICATION_JSON_VALUE,
+ dataAccessWriteRequest.getData());
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ /**
* This method register given list of cm-handles to ncmp.
*
* @param cmHandles list of cm-handles
@@ -89,60 +110,58 @@ 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 depth and field
- * query parameters and returns response.
+ * This method fetches the resource for given cm handle using pass through operational. It filters the response on
+ * the basis of depth and field query parameters and returns response.
*
- * @param cmHandle cm handle identifier
- * @param resourceIdentifier resource identifier to fetch data
- * @param body operational body
- * @param accept accept header parameter
- * @param fields fields to filter the response data
- * @param depth depth parameter for the response
+ * @param cmHandle cm handle identifier
+ * @param resourceIdentifier resource identifier to fetch data
+ * @param dataAccessReadRequest data Access Read Request
+ * @param accept accept header parameter
+ * @param fields fields to filter the response data
+ * @param depth depth parameter for the response
* @return {@code ResponseEntity} response entity
*/
@Override
public ResponseEntity<Object> getResourceDataOperationalForCmHandle(final String cmHandle,
- final String resourceIdentifier,
- final @Valid OperationalRequest body,
- final String accept,
- final @Valid String fields,
- final @Min(1) @Valid Integer depth) {
+ final String resourceIdentifier,
+ final @Valid DataAccessReadRequest dataAccessReadRequest,
+ final String accept,
+ final @Valid String fields,
+ final @Min(1) @Valid Integer depth) {
final var modulesListAsJson = dmiService.getResourceDataOperationalForCmHandle(cmHandle,
- resourceIdentifier,
- accept,
- fields,
- depth,
- body.getCmHandleProperties());
+ resourceIdentifier,
+ accept,
+ fields,
+ depth,
+ dataAccessReadRequest.getCmHandleProperties());
return ResponseEntity.ok(modulesListAsJson);
}
/**
- * This method fetches the resource for given cm handle using pass
- * through running. It filters the response on the basis of depth and field
- * query parameters and returns response.
+ * This method fetches the resource for given cm handle using pass through running. It filters the response on the
+ * basis of depth and field query parameters and returns response.
*
- * @param cmHandle cm handle identifier
- * @param resourceIdentifier resource identifier to fetch data
- * @param body operational body
- * @param accept accept header parameter
- * @param fields fields to filter the response data
- * @param depth depth parameter for the response
+ * @param cmHandle cm handle identifier
+ * @param resourceIdentifier resource identifier to fetch data
+ * @param dataAccessReadRequest data Access Read Request
+ * @param accept accept header parameter
+ * @param fields fields to filter the response data
+ * @param depth depth parameter for the response
* @return {@code ResponseEntity} response entity
*/
@Override
public ResponseEntity<Object> getResourceDataPassthroughRunningForCmHandle(final String cmHandle,
- final String resourceIdentifier,
- final @Valid OperationalRequest body,
- final String accept,
- final @Valid String fields,
- final @Min(1) @Valid Integer depth) {
+ final String resourceIdentifier,
+ final @Valid DataAccessReadRequest dataAccessReadRequest,
+ final String accept,
+ final @Valid String fields,
+ final @Min(1) @Valid Integer depth) {
final var modulesListAsJson = dmiService.getResourceDataPassThroughRunningForCmHandle(cmHandle,
- resourceIdentifier,
- accept,
- fields,
- depth,
- body.getCmHandleProperties());
+ resourceIdentifier,
+ accept,
+ fields,
+ depth,
+ dataAccessReadRequest.getCmHandleProperties());
return ResponseEntity.ok(modulesListAsJson);
}
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 83301270..f1446084 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
@@ -42,8 +42,8 @@ public interface DmiService {
ModuleSet getModulesForCmHandle(String cmHandle) throws DmiException;
/**
- * This method used to register the given {@code CmHandles}
- * which contains list of {@code CmHandle} to cps repository.
+ * This method used to register the given {@code CmHandles} which contains list of {@code CmHandle} to cps
+ * repository.
*
* @param cmHandles list of cm-handles
*/
@@ -53,50 +53,58 @@ public interface DmiService {
* Get module resources for the given cm handle and modules.
*
* @param cmHandle cmHandle
- * @param modules a list of module data
+ * @param modules a list of module data
* @return returns all module resources
*/
String 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. Fields and depths query
- * parameter are used to filter the response from network resource.
+ * This method use to fetch the resource data from cm handle for datastore pass-through operational and resource
+ * Identifier. Fields and depths query parameter are used to filter the response from network resource.
*
- * @param cmHandle cm handle identifier
- * @param resourceIdentifier resource identifier
- * @param acceptParam accept header parameter
- * @param fieldsQuery fields query parameter
- * @param depthQuery depth query parameter
+ * @param cmHandle cm handle identifier
+ * @param resourceIdentifier resource identifier
+ * @param acceptParam accept header parameter
+ * @param fieldsQuery fields query parameter
+ * @param depthQuery depth query parameter
* @param cmHandlePropertyMap cm handle properties
- *
* @return {@code Object} response from network function
*/
Object getResourceDataOperationalForCmHandle(@NotNull String cmHandle,
- @NotNull String resourceIdentifier,
- String acceptParam,
- String fieldsQuery,
- Integer depthQuery,
- Map<String, String> cmHandlePropertyMap);
+ @NotNull String resourceIdentifier,
+ String acceptParam,
+ String fieldsQuery,
+ Integer depthQuery,
+ Map<String, String> cmHandlePropertyMap);
/**
- * This method use to fetch the resource data from cm handle
- * for datastore pass-through running and resource Identifier. Fields and depths query
- * parameter are used to filter the response from network resource.
+ * This method use to fetch the resource data from cm handle for datastore pass-through running and resource
+ * Identifier. Fields and depths query parameter are used to filter the response from network resource.
*
- * @param cmHandle cm handle identifier
- * @param resourceIdentifier resource identifier
- * @param acceptParam accept header parameter
- * @param fieldsQuery fields query parameter
- * @param depthQuery depth query parameter
+ * @param cmHandle cm handle identifier
+ * @param resourceIdentifier resource identifier
+ * @param acceptParam accept header parameter
+ * @param fieldsQuery fields query parameter
+ * @param depthQuery depth query parameter
* @param cmHandlePropertyMap cm handle properties
- *
* @return {@code Object} response from network function
*/
Object getResourceDataPassThroughRunningForCmHandle(@NotNull String cmHandle,
- @NotNull String resourceIdentifier,
- String acceptParam,
- String fieldsQuery,
- Integer depthQuery,
- Map<String, String> cmHandlePropertyMap);
+ @NotNull String resourceIdentifier,
+ String acceptParam,
+ String fieldsQuery,
+ Integer depthQuery,
+ Map<String, String> cmHandlePropertyMap);
+
+ /**
+ * Write resource data to sdnc using passthrough running.
+ *
+ * @param cmHandle cmHandle
+ * @param resourceIdentifier resource identifier
+ * @param dataType accept header parameter
+ * @param data request data
+ * @return response from sdnc
+ */
+ String writeResourceDataPassthroughForCmHandle(String cmHandle, String resourceIdentifier, String dataType,
+ Object data);
} \ No newline at end of file
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 62f93e63..a139f7be 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
@@ -69,8 +69,8 @@ public class DmiServiceImpl implements DmiService {
* @param objectMapper objectMapper
*/
public DmiServiceImpl(final DmiPluginProperties dmiPluginProperties,
- final NcmpRestClient ncmpRestClient,
- final SdncOperations sdncOperations, final ObjectMapper objectMapper) {
+ final NcmpRestClient ncmpRestClient,
+ final SdncOperations sdncOperations, final ObjectMapper objectMapper) {
this.dmiPluginProperties = dmiPluginProperties;
this.ncmpRestClient = ncmpRestClient;
this.objectMapper = objectMapper;
@@ -88,7 +88,7 @@ public class DmiServiceImpl implements DmiService {
return createModuleSchema(responseBody);
} else {
throw new DmiException("SDNC is not able to process request.",
- "response code : " + responseEntity.getStatusCode() + " message : " + responseEntity.getBody());
+ "response code : " + responseEntity.getStatusCode() + " message : " + responseEntity.getBody());
}
}
@@ -103,7 +103,7 @@ public class DmiServiceImpl implements DmiService {
} else {
log.error("SDNC did not return a module resource for the given cmHandle {}", cmHandle);
throw new ModuleResourceNotFoundException(cmHandle,
- "SDNC did not return a module resource for the given cmHandle.");
+ "SDNC did not return a module resource for the given cmHandle.");
}
}
return getModuleResponses.toJSONString();
@@ -126,7 +126,7 @@ public class DmiServiceImpl implements DmiService {
} catch (final JsonProcessingException e) {
log.error("Parsing error occurred while converting cm-handles to JSON {}", cmHandles);
throw new DmiException("Internal Server Error.",
- "Parsing error occurred while converting given cm-handles object list to JSON ");
+ "Parsing error occurred while converting given cm-handles object list to JSON ");
}
final ResponseEntity<String> responseEntity = ncmpRestClient.registerCmHandlesWithNcmp(cmHandlesJson);
if ((responseEntity.getStatusCode() != HttpStatus.CREATED)) {
@@ -166,44 +166,66 @@ public class DmiServiceImpl implements DmiService {
@Override
public Object getResourceDataOperationalForCmHandle(final @NotNull String cmHandle,
- final @NotNull String resourceIdentifier,
- final String acceptParam,
- final String fieldsQuery,
- final Integer depthQuery,
- final Map<String, String> cmHandlePropertyMap) {
+ final @NotNull String resourceIdentifier,
+ final String acceptParam,
+ final String fieldsQuery,
+ final Integer depthQuery,
+ 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,
- fieldsQuery,
- depthQuery,
- acceptParam,
+ resourceIdentifier,
+ fieldsQuery,
+ depthQuery,
+ acceptParam,
CONTENT_QUERY_PASSTHROUGH_OPERATIONAL);
return prepareAndSendResponse(responseEntity, cmHandle);
}
@Override
public Object getResourceDataPassThroughRunningForCmHandle(final @NotNull String cmHandle,
- final @NotNull String resourceIdentifier,
- final String acceptParam,
- final String fieldsQuery,
- final Integer depthQuery,
- final Map<String, String> cmHandlePropertyMap) {
+ final @NotNull String resourceIdentifier,
+ final String acceptParam,
+ final String fieldsQuery,
+ final Integer depthQuery,
+ 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,
- fieldsQuery,
- depthQuery,
- acceptParam,
- CONTENT_QUERY_PASSTHROUGH_RUNNING);
+ resourceIdentifier,
+ fieldsQuery,
+ depthQuery,
+ acceptParam,
+ CONTENT_QUERY_PASSTHROUGH_RUNNING);
return prepareAndSendResponse(responseEntity, cmHandle);
}
+ @Override
+ public String writeResourceDataPassthroughForCmHandle(final String cmHandle, final String resourceIdentifier,
+ final String dataType, final Object data) {
+ final String jsonData;
+ try {
+ jsonData = objectMapper.writeValueAsString(data);
+ } catch (final JsonProcessingException e) {
+ log.error("JSON exception occurred when processing pass through request data for the given cmHandle {}",
+ cmHandle);
+ throw new DmiException("Unable to process incoming JSON from the request body.",
+ "JSON exception occurred when writing data for the given cmHandle " + cmHandle, e);
+ }
+ final ResponseEntity<String> responseEntity =
+ sdncOperations.writeResourceDataPassthroughRunning(cmHandle, resourceIdentifier, dataType, jsonData);
+ if (responseEntity.getStatusCode() == HttpStatus.CREATED) {
+ return responseEntity.getBody();
+ } else {
+ throw new DmiException(cmHandle,
+ "response code : " + responseEntity.getStatusCode() + " message : " + responseEntity.getBody());
+ }
+ }
+
private String prepareAndSendResponse(final ResponseEntity<String> responseEntity, final String cmHandle) {
if (responseEntity.getStatusCode() == HttpStatus.OK) {
return responseEntity.getBody();
} else {
throw new ResourceDataNotFound(cmHandle,
- "response code : " + responseEntity.getStatusCode() + " message : " + responseEntity.getBody());
+ "response code : " + responseEntity.getStatusCode() + " message : " + responseEntity.getBody());
}
}
@@ -217,9 +239,9 @@ public class DmiServiceImpl implements DmiService {
moduleRequest = writer.writeValueAsString(ietfNetconfModuleReferences);
} catch (final JsonProcessingException e) {
log.error("JSON exception occurred when creating the module request for the given module reference {}",
- moduleReference.getName());
+ moduleReference.getName());
throw new DmiException("Unable to process JSON.",
- "JSON exception occurred when creating the module request.", e);
+ "JSON exception occurred when creating the module request.", e);
}
return moduleRequest;
}
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 499033d3..fe13a38d 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
@@ -23,7 +23,6 @@ package org.onap.cps.ncmp.dmi.service.client;
import org.onap.cps.ncmp.dmi.config.DmiConfiguration.SdncProperties;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@@ -43,7 +42,6 @@ public class SdncRestconfClient {
* restconf get operation on sdnc.
*
* @param getResourceUrl sdnc get url
- *
* @return the response entity
*/
public ResponseEntity<String> getOperation(final String getResourceUrl) {
@@ -54,8 +52,7 @@ public class SdncRestconfClient {
* Overloaded restconf get operation on sdnc with http headers.
*
* @param getResourceUrl sdnc get url
- * @param httpHeaders http headers
- *
+ * @param httpHeaders http headers
* @return the response entity
*/
public ResponseEntity<String> getOperation(final String getResourceUrl, final HttpHeaders httpHeaders) {
@@ -71,20 +68,15 @@ public class SdncRestconfClient {
*
* @param postResourceUrl sdnc post resource url
* @param jsonData json data
+ * @param httpHeaders HTTP headers
* @return the response entity
*/
public ResponseEntity<String> postOperationWithJsonData(final String postResourceUrl,
- final String jsonData) {
+ final String jsonData, final HttpHeaders httpHeaders) {
final var sdncBaseUrl = sdncProperties.getBaseUrl();
final var sdncRestconfUrl = sdncBaseUrl.concat(postResourceUrl);
- final var httpEntity = new HttpEntity<>(jsonData, configureHttpHeaders());
- return restTemplate.postForEntity(sdncRestconfUrl, httpEntity, String.class);
- }
-
- private HttpHeaders configureHttpHeaders() {
- final var httpHeaders = new HttpHeaders();
httpHeaders.setBasicAuth(sdncProperties.getAuthUsername(), sdncProperties.getAuthPassword());
- httpHeaders.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
- return httpHeaders;
+ final var httpEntity = new HttpEntity<>(jsonData, httpHeaders);
+ return restTemplate.postForEntity(sdncRestconfUrl, 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 ab9c7e1d..73503d23 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
@@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull;
import org.onap.cps.ncmp.dmi.config.DmiConfiguration.SdncProperties;
import org.onap.cps.ncmp.dmi.service.client.SdncRestconfClient;
import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
@@ -34,9 +35,9 @@ import org.springframework.stereotype.Component;
public class SdncOperations {
private static final String TOPOLOGY_URL_TEMPLATE_DATA =
- "/rests/data/network-topology:network-topology/topology={topologyId}";
+ "/rests/data/network-topology:network-topology/topology={topologyId}";
private static final String TOPOLOGY_URL_TEMPLATE_OPERATIONAL =
- "/rests/operations/network-topology:network-topology/topology={topologyId}";
+ "/rests/operations/network-topology:network-topology/topology={topologyId}";
private static final String MOUNT_URL_TEMPLATE = "/node={nodeId}/yang-ext:mount";
private static final String GET_SCHEMA_URL = "/ietf-netconf-monitoring:netconf-state/schemas";
private static final String GET_SCHEMA_SOURCES_URL = "/ietf-netconf-monitoring:get-schema";
@@ -56,7 +57,7 @@ public class SdncOperations {
this.sdncProperties = sdncProperties;
this.sdncRestconfClient = sdncRestconfClient;
topologyUrlOperational =
- TOPOLOGY_URL_TEMPLATE_OPERATIONAL.replace("{topologyId}", this.sdncProperties.getTopologyId());
+ TOPOLOGY_URL_TEMPLATE_OPERATIONAL.replace("{topologyId}", this.sdncProperties.getTopologyId());
topologyUrlData = TOPOLOGY_URL_TEMPLATE_DATA.replace("{topologyId}", this.sdncProperties.getTopologyId());
}
@@ -79,30 +80,32 @@ public class SdncOperations {
* @return response entity
*/
public ResponseEntity<String> getModuleResource(final String nodeId, final String moduleProperties) {
- final String getYangResourceUrl = prepareGetOperationSchemaUrl(nodeId);
- return sdncRestconfClient.postOperationWithJsonData(getYangResourceUrl, moduleProperties);
+ final var getYangResourceUrl = prepareGetOperationSchemaUrl(nodeId);
+ final var httpHeaders = new HttpHeaders();
+ httpHeaders.setContentType(MediaType.APPLICATION_JSON);
+ return sdncRestconfClient
+ .postOperationWithJsonData(getYangResourceUrl, moduleProperties, httpHeaders);
}
/**
- * This method fetches the resource data for given node identifier on given resource
- * using sdnc client.
+ * This method fetches the resource data for given node identifier on given resource using sdnc client.
*
- * @param nodeId network resource identifier
- * @param resourceId resource identifier
+ * @param nodeId network resource identifier
+ * @param resourceId resource identifier
* @param fieldsValue fields query
- * @param depthValue depth query
+ * @param depthValue depth query
* @param acceptParam accept parameter
* @return {@code ResponseEntity} response entity
*/
public ResponseEntity<String> getResouceDataForOperationalAndRunning(final String nodeId,
- final String resourceId,
- final String fieldsValue,
- final Integer depthValue,
- final String acceptParam,
+ final String resourceId,
+ final String fieldsValue,
+ final Integer depthValue,
+ final String acceptParam,
final String contentQuery) {
final String getResourceDataUrl = prepareResourceDataUrl(nodeId,
- resourceId,
- getQueryList(fieldsValue, depthValue, contentQuery));
+ resourceId,
+ getQueryList(fieldsValue, depthValue, contentQuery));
final HttpHeaders httpHeaders = new HttpHeaders();
if (!StringUtils.isEmpty(acceptParam)) {
httpHeaders.set(HttpHeaders.ACCEPT, acceptParam);
@@ -110,6 +113,23 @@ public class SdncOperations {
return sdncRestconfClient.getOperation(getResourceDataUrl, httpHeaders);
}
+ /**
+ * Write resource data using passthrough running.
+ *
+ * @param nodeId network resource identifier
+ * @param resourceId resource identifier
+ * @param contentType http content type
+ * @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);
+ final var httpHeaders = new HttpHeaders();
+ httpHeaders.setContentType(MediaType.parseMediaType(contentType));
+ return sdncRestconfClient.postOperationWithJsonData(getResourceDataUrl, requestData, httpHeaders);
+ }
+
@NotNull
private List<String> getQueryList(final String fieldsValue, final Integer depthValue, final String contentQuery) {
final List<String> queryList = new LinkedList<>();
@@ -131,6 +151,10 @@ public class SdncOperations {
return addResource(addTopologyDataUrlwithNode(nodeId), GET_SCHEMA_URL);
}
+ private String preparePassthroughRunningUrl(final String nodeId, final String resourceId) {
+ return addResource(addTopologyDataUrlwithNode(nodeId), "/" + resourceId);
+ }
+
private String prepareGetOperationSchemaUrl(final String nodeId) {
final var topologyMountUrl = topologyUrlOperational + MOUNT_URL_TEMPLATE;
final var topologyMountUrlWithNodeId = topologyMountUrl.replace("{nodeId}", nodeId);
@@ -139,8 +163,8 @@ public class SdncOperations {
@NotNull
private String prepareResourceDataUrl(final String nodeId,
- final String resourceId,
- final List<String> queryList) {
+ final String resourceId,
+ final List<String> queryList) {
return addQuery(addResource(addTopologyDataUrlwithNode(nodeId), resourceId), queryList);
}
@@ -152,7 +176,7 @@ public class SdncOperations {
return url.concat("/" + resourceId);
}
}
-
+
@NotNull
private String addQuery(final String url, final List<String> queryList) {
if (queryList.isEmpty()) {
@@ -173,5 +197,4 @@ public class SdncOperations {
final String topologyMountUrl = topologyUrlData + MOUNT_URL_TEMPLATE;
return topologyMountUrl.replace("{nodeId}", nodeId);
}
-
} \ No newline at end of file
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 b1528c71..e08870fd 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
@@ -26,7 +26,8 @@ import org.onap.cps.ncmp.dmi.TestUtils
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.model.DataAccessReadRequest
+import org.onap.cps.ncmp.dmi.model.DataAccessWriteRequest
import org.onap.cps.ncmp.dmi.model.ModuleReference
import org.onap.cps.ncmp.dmi.model.ModuleSchemaList
import org.onap.cps.ncmp.dmi.model.ModuleSchemaProperties
@@ -44,7 +45,6 @@ import org.springframework.http.MediaType
import org.springframework.test.web.servlet.MockMvc
import spock.lang.Specification
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
@@ -121,7 +121,7 @@ class DmiRestControllerSpec extends Specification {
def 'Register given list of cm handles.'() {
given: 'register cm handle url and cm handles json'
def registerCmhandlesPost = "${basePathV1}/inventory/cmHandles"
- def cmHandleJson = '{"cmHandles":["node1", "node2"]}'
+ def cmHandleJson = '{"cmHandles":["node1", "node2"]}'
when: 'post register cm handles api is invoked'
def response = mvc.perform(
post(registerCmhandlesPost)
@@ -161,12 +161,12 @@ class DmiRestControllerSpec extends Specification {
moduleReference2.name = 'nc-notifications'
moduleReference2.revision = '2008-07-14'
def moduleReferences = [moduleReference1, moduleReference2]
- mockDmiService.getModuleResources('some-cm-handle', moduleReferences ) >> '{some-json}'
+ mockDmiService.getModuleResources('some-cm-handle', moduleReferences) >> '{some-json}'
when: 'get module resource api is invoked'
def response = mvc.perform(post(getModulesEndpoint)
.contentType(MediaType.APPLICATION_JSON)
.content(jsonData)).andReturn().response
- then:'a OK status is returned'
+ then: 'a OK status is returned'
response.status == HttpStatus.OK.value()
and: 'the expected response is returned'
response.getContentAsString() == '{some-json}'
@@ -204,7 +204,24 @@ class DmiRestControllerSpec extends Specification {
'application/json',
'myfields',
5,
- ['prop1':'value1', 'prop2':'value2'])
+ ['prop1': 'value1', 'prop2': 'value2'])
+ }
+
+ def 'Write data using passthrough running for a cm handle.'() {
+ given: 'write data for cmHandle url and jsonData'
+ def writeDataforCmHandlePassthroughRunning = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-running/some-resourceIdentifier"
+ def jsonData = TestUtils.getResourceFileContent('WriteDataForCmHandle.json')
+ and: 'dmi service is called'
+ mockDmiService.writeResourceDataPassthroughForCmHandle('some-cmHandle', 'some-resourceIdentifier', 'application/json', ['some-data': 'some-value']) >> '{some-json}'
+ when: 'write cmHandle passthrough running post api is invoked with json data'
+ def response = mvc.perform(
+ post(writeDataforCmHandlePassthroughRunning).contentType(MediaType.APPLICATION_JSON)
+ .content(jsonData)
+ ).andReturn().response
+ then: 'response status is ok'
+ response.status == HttpStatus.OK.value()
+ and: 'the data in the request body is as expected'
+ response.getContentAsString() == '{some-json}'
}
def 'Get resource data for pass-through running from cm handle.'() {
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 31b60a7c..e3703020 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
@@ -68,7 +68,7 @@ class DmiServiceImplSpec extends Specification {
when: 'get modules for cm-handle is called'
def result = objectUnderTest.getModulesForCmHandle(cmHandle)
then: 'a dmi exception is thrown'
- thrown(DmiException)
+ thrown(DmiException)
}
def 'Call get modules for cm-handle and SDNC returns "bad request" status.'() {
@@ -149,8 +149,8 @@ class DmiServiceImplSpec extends Specification {
when: 'get module resources is invoked with the given cm handle and a module list'
def response = objectUnderTest.getModuleResources(cmHandle, moduleList)
then: 'then get modules resources called correctly'
- 1 * mockSdncOperations.getModuleResource(cmHandle,excpectedModulesJson1) >> new ResponseEntity<String>('response-body1', HttpStatus.OK)
- 1 * mockSdncOperations.getModuleResource(cmHandle,excpectedModulesJson2) >> new ResponseEntity<String>('response-body2', HttpStatus.OK)
+ 1 * mockSdncOperations.getModuleResource(cmHandle, excpectedModulesJson1) >> new ResponseEntity<String>('response-body1', HttpStatus.OK)
+ 1 * mockSdncOperations.getModuleResource(cmHandle, excpectedModulesJson2) >> new ResponseEntity<String>('response-body2', HttpStatus.OK)
and: 'the response equals to the expected response body'
response == '["response-body1","response-body2"]'
}
@@ -159,7 +159,7 @@ class DmiServiceImplSpec extends Specification {
given: 'get module schema is invoked and returns not found'
mockSdncOperations.getModuleResource(_ as String, _ as String) >> new ResponseEntity<String>('some-response-body', HttpStatus.BAD_REQUEST)
when: 'get module resources is invoked with the given cm handle and a module list'
- objectUnderTest.getModuleResources('some-cmHandle', [new ModuleReference()] as LinkedList<ModuleReference> )
+ objectUnderTest.getModuleResources('some-cmHandle', [new ModuleReference()] as LinkedList<ModuleReference>)
then: 'ModuleResourceNotFoundException is thrown'
thrown(ModuleResourceNotFoundException)
}
@@ -173,8 +173,7 @@ class DmiServiceImplSpec extends Specification {
def depthParam = 10
def contentQuery = 'content=all'
and: 'sdnc operation returns OK response'
- mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, fieldsParam,
- depthParam, acceptHeaderParam, contentQuery) >> new ResponseEntity<>('response json', HttpStatus.OK)
+ mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, fieldsParam, depthParam, acceptHeaderParam, contentQuery) >> new ResponseEntity<>('response json', HttpStatus.OK)
when: 'get resource data from cm handles service method invoked'
def response = objectUnderTest.getResourceDataOperationalForCmHandle(cmHandle,
resourceId, acceptHeaderParam,
@@ -191,8 +190,7 @@ class DmiServiceImplSpec extends Specification {
def fieldsParam = 'testFields'
def depthParam = 10
and: 'sdnc operation returns "NOT_FOUND" response'
- mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, fieldsParam,
- depthParam, acceptHeaderParam, _ as String) >> new ResponseEntity<>(HttpStatus.NOT_FOUND)
+ mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, fieldsParam, depthParam, acceptHeaderParam, _ as String) >> new ResponseEntity<>(HttpStatus.NOT_FOUND)
when: 'get resource data from cm handles service method invoked'
objectUnderTest.getResourceDataOperationalForCmHandle(cmHandle,
resourceId, acceptHeaderParam,
@@ -211,7 +209,7 @@ class DmiServiceImplSpec extends Specification {
def contentQuery = 'content=config'
and: 'sdnc operation returns OK response'
mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, fieldsParam,
- depthParam, acceptHeaderParam, contentQuery) >> new ResponseEntity<>('response json', HttpStatus.OK)
+ depthParam, acceptHeaderParam, contentQuery) >> new ResponseEntity<>('response json', HttpStatus.OK)
when: 'get resource data from cm handles service method invoked'
def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle(cmHandle,
resourceId, acceptHeaderParam,
@@ -219,4 +217,31 @@ class DmiServiceImplSpec extends Specification {
then: 'response have expected json'
response == 'response json'
}
+
+ def 'Write resource data using for passthrough running for the given cm handle.'() {
+ given: 'sdnc returns a created response'
+ mockSdncOperations.writeResourceDataPassthroughRunning(_, _, _, _) >> 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', '{some-data}')
+ then: 'response have expected json'
+ response == 'response json'
+ }
+
+ def 'Write resource data for passthrough running with a #scenario.'() {
+ given: 'sdnc returns a response for the write operation'
+ mockSdncOperations.writeResourceDataPassthroughRunning(_, _, _, _) >> new ResponseEntity<String>('response json', httpStatus)
+ and: 'the data provided in the request body is written as a string'
+ objectUnderTest.objectMapper = mockObjectMapper
+ mockObjectMapper.writeValueAsString(_) >> jsonString
+ when: 'write resource data for pass through method is invoked'
+ objectUnderTest.writeResourceDataPassthroughForCmHandle('some-cmHandle',
+ 'some-resourceIdentifier', 'some-dataType', new Object())
+ then: 'a dmi exception is thrown'
+ thrown(DmiException.class)
+ where: 'the following combinations are tested'
+ scenario | httpStatus | jsonString
+ '500 response from sdnc' | HttpStatus.INTERNAL_SERVER_ERROR | '{some-json-data}'
+ 'json processing exception ' | HttpStatus.OK | { throw new JsonProcessingException('some error.') }
+ }
} \ No newline at end of file
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 e2621e47..9a7ed180 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
@@ -57,7 +57,7 @@ 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)
+ def result = objectUnderTest.postOperationWithJsonData(getModuleResourceUrl, jsonData, new HttpHeaders())
then: 'the rest template is called with the correct uri and json in the body'
1 * mockRestTemplate.postForEntity({ it.toString() == 'http://some-uri/getModuleResourceUrl' },
{ it.body.contains(jsonData) }, String.class) >> mockResponseEntity
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 3557bc1b..c9d7d1b8 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
@@ -56,7 +56,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')
+ 1 * mockSdncRestClient.postOperationWithJsonData(expectedUrl, 'some-json-data', _ as HttpHeaders)
}
def 'Get resource data from node to SDNC.'() {
@@ -68,4 +68,13 @@ class SdncOperationsSpec extends Specification {
then: 'the get operation is executed with the correct URL'
1 * mockSdncRestClient.getOperation(expectedUrl, _ as HttpHeaders)
}
+
+ def 'Write resource data to SDNC.'() {
+ given: 'excpected 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','testData')
+ then: 'the post operation is executed with the correct URL'
+ 1 * mockSdncRestClient.postOperationWithJsonData(expectedUrl, _ as String, _ as HttpHeaders)
+ }
} \ No newline at end of file
diff --git a/src/test/resources/WriteDataForCmHandle.json b/src/test/resources/WriteDataForCmHandle.json
new file mode 100644
index 00000000..8eb19599
--- /dev/null
+++ b/src/test/resources/WriteDataForCmHandle.json
@@ -0,0 +1,10 @@
+{
+ "operation": "create",
+ "dataType": "application/json",
+ "data": {
+ "some-data": "some-value"
+ },
+ "cmHandleProperties": {
+ "some-property": "some-property-value"
+ }
+} \ No newline at end of file