summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortragait <rahul.tyagi@est.tech>2021-08-06 17:01:31 +0100
committertragait <rahul.tyagi@est.tech>2021-08-17 13:55:12 +0100
commite398be5923a47650b109512c795244cdc2b5eb10 (patch)
tree4d12aa2f7d18785825f4c5b1e9073a68505cf30b
parent3139ece993c68ce7e40d166acdd5d9572a3a8a1e (diff)
implement passthough operational for dmi
Issue-ID: CPS-486 Signed-off-by: tragait <rahul.tyagi@est.tech> Change-Id: Icf48fa93ea1f0d8a27d2e7e1ab0cfd6096a765ec
-rw-r--r--docs/openapi/components.yml11
-rw-r--r--docs/openapi/openapi.yml50
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/exception/ResourceDataNotFound.java38
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java34
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java25
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java46
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java20
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java102
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy25
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy42
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy15
-rw-r--r--src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy13
12 files changed, 391 insertions, 30 deletions
diff --git a/docs/openapi/components.yml b/docs/openapi/components.yml
index c67dad69..05f1ac06 100644
--- a/docs/openapi/components.yml
+++ b/docs/openapi/components.yml
@@ -43,6 +43,17 @@ components:
type: string
example: system-001
+ OperationalRequest:
+ type: object
+ properties:
+ operation:
+ type: string
+ enum: [ read ]
+ 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 f261c0da..a4a238c4 100644
--- a/docs/openapi/openapi.yml
+++ b/docs/openapi/openapi.yml
@@ -123,3 +123,53 @@ paths:
$ref: 'components.yml#/components/responses/Unauthorized'
'403':
$ref: 'components.yml#/components/responses/Forbidden'
+
+ /v1/ch/{cmHandle}/data/ds/ncmp-datastore:passthrough-operational/{resourceIdentifier}:
+ put:
+ tags:
+ - dmi-plugin
+ summary: Get resource data for cm handle
+ description: Get resource data for given cm handle
+ operationId: getResourceDataOperationalForCmHandle
+ parameters:
+ - $ref: 'components.yml#/components/parameters/cmHandleInPath'
+ - name: resourceIdentifier
+ in: path
+ description: Resource identifier to fetch the resource data
+ required: true
+ schema:
+ type: string
+ - name: accept
+ in: header
+ description: Accept parameter for response, if accept parameter is null, that means client can accept any format.
+ schema:
+ type: string
+ enum: [ application/json, application/yang-data+json ]
+ - name: fields
+ in: query
+ description: Fields parameter to filter resource
+ required: false
+ schema:
+ type: string
+ - name: depth
+ in: query
+ description: Depth parameter for response
+ required: false
+ schema:
+ type: integer
+ minimum: 1
+ requestBody:
+ description: Operational body
+ content:
+ application/json:
+ schema:
+ $ref: 'components.yml#/components/schemas/OperationalRequest'
+ 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/exception/ResourceDataNotFound.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/ResourceDataNotFound.java
new file mode 100644
index 00000000..dbef3477
--- /dev/null
+++ b/src/main/java/org/onap/cps/ncmp/dmi/exception/ResourceDataNotFound.java
@@ -0,0 +1,38 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.dmi.exception;
+
+public class ResourceDataNotFound extends DmiException {
+
+ private static final long serialVersionUID = 881438585188332404L;
+
+ private static final String ERROR_MESSAGE = "Resource data not found for the given cmHandles: ";
+
+ /**
+ * Constructor.
+ *
+ * @param cmHandle cmHandle identifier
+ * @param details the error details
+ */
+ public ResourceDataNotFound(final String cmHandle, final String details) {
+ super(ERROR_MESSAGE + cmHandle, details);
+ }
+}
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 5725f094..969e08d3 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
@@ -28,6 +28,7 @@ import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.dmi.model.CmHandles;
import org.onap.cps.ncmp.dmi.model.ModuleReference;
import org.onap.cps.ncmp.dmi.model.ModuleRequestParent;
+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;
@@ -59,7 +60,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);
@@ -86,8 +87,37 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi {
return new ResponseEntity<>("cm-handle registered successfully.", HttpStatus.CREATED);
}
+ /**
+ * This method fetches the resource for given cm handle using pass
+ * through option. 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
+ * @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 @Valid Integer depth) {
+ final var modulesListAsJson = dmiService.getResourceDataOperationalForCmHandle(cmHandle,
+ resourceIdentifier,
+ accept,
+ fields,
+ depth,
+ body.getCmHandleProperties());
+ return ResponseEntity.ok(modulesListAsJson);
+ }
+
private List<ModuleReference> convertRestObjectToJavaApiObject(final ModuleRequestParent moduleRequestParent) {
return objectMapper
.convertValue(moduleRequestParent.getData().getModules(), new TypeReference<List<ModuleReference>>() {});
}
-}
+} \ No newline at end of file
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 aeff3dc6..528eb641 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,6 +21,8 @@
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.ModuleReference;
@@ -54,4 +56,25 @@ public interface DmiService {
* @return returns all module resources
*/
String getModuleResources(String cmHandle, List<ModuleReference> modules);
-}
+
+ /**
+ * This method use to fetch the resource data from cm handle
+ * for given datasource and 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 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);
+} \ 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 bf0689ca..32c8526c 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
@@ -25,20 +25,22 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONArray;
import org.apache.groovy.parser.antlr4.util.StringUtils;
+import org.jetbrains.annotations.NotNull;
import org.onap.cps.ncmp.dmi.config.DmiPluginConfig.DmiPluginProperties;
import org.onap.cps.ncmp.dmi.exception.CmHandleRegistrationException;
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.CmHandleOperation;
import org.onap.cps.ncmp.dmi.model.CreatedCmHandle;
import org.onap.cps.ncmp.dmi.model.ModuleReference;
import org.onap.cps.ncmp.dmi.service.client.NcmpRestClient;
import org.onap.cps.ncmp.dmi.service.operation.SdncOperations;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
@@ -60,10 +62,9 @@ public class DmiServiceImpl implements DmiService {
* @param sdncOperations sdncOperations
* @param objectMapper objectMapper
*/
- @Autowired
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;
@@ -82,7 +83,7 @@ public class DmiServiceImpl implements DmiService {
return 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());
}
}
@@ -97,7 +98,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();
@@ -120,7 +121,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)) {
@@ -128,6 +129,31 @@ 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) {
+ // not using cmHandlePropertyMap of onap dmi impl , other dmi impl might use this.
+ final ResponseEntity<String> responseEntity = sdncOperations.getResouceDataForOperational(cmHandle,
+ resourceIdentifier,
+ fieldsQuery,
+ depthQuery,
+ acceptParam);
+ return prepareAndSendResponse(responseEntity, cmHandle);
+ }
+
+ 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());
+ }
+ }
+
private String createModuleRequest(final ModuleReference moduleReference) {
final var ietfNetconfModuleReferences = new LinkedHashMap<>();
ietfNetconfModuleReferences.put("ietf-netconf-monitoring:identifier", moduleReference.getName());
@@ -138,10 +164,10 @@ 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;
}
-}
+} \ No newline at end of file
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 adac5e64..499033d3 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
@@ -43,12 +43,26 @@ public class SdncRestconfClient {
* restconf get operation on sdnc.
*
* @param getResourceUrl sdnc get url
+ *
* @return the response entity
*/
public ResponseEntity<String> getOperation(final String getResourceUrl) {
+ return getOperation(getResourceUrl, new HttpHeaders());
+ }
+
+ /**
+ * Overloaded restconf get operation on sdnc with http headers.
+ *
+ * @param getResourceUrl sdnc get url
+ * @param httpHeaders http headers
+ *
+ * @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);
- final var httpEntity = new HttpEntity<>(configureHttpHeaders());
+ httpHeaders.setBasicAuth(sdncProperties.getAuthUsername(), sdncProperties.getAuthPassword());
+ final var httpEntity = new HttpEntity<>(httpHeaders);
return restTemplate.getForEntity(sdncRestconfUrl, String.class, httpEntity);
}
@@ -60,7 +74,7 @@ public class SdncRestconfClient {
* @return the response entity
*/
public ResponseEntity<String> postOperationWithJsonData(final String postResourceUrl,
- final String jsonData) {
+ final String jsonData) {
final var sdncBaseUrl = sdncProperties.getBaseUrl();
final var sdncRestconfUrl = sdncBaseUrl.concat(postResourceUrl);
final var httpEntity = new HttpEntity<>(jsonData, configureHttpHeaders());
@@ -73,4 +87,4 @@ public class SdncRestconfClient {
httpHeaders.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
return httpHeaders;
}
-}
+} \ 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 0d1c3438..358da590 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
@@ -20,19 +20,23 @@
package org.onap.cps.ncmp.dmi.service.operation;
+import java.util.LinkedList;
+import java.util.List;
+import org.apache.groovy.parser.antlr4.util.StringUtils;
+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.ResponseEntity;
import org.springframework.stereotype.Component;
@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";
@@ -52,7 +56,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,11 +83,52 @@ public class SdncOperations {
return sdncRestconfClient.postOperationWithJsonData(getYangResourceUrl, moduleProperties);
}
+ /**
+ * 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 fieldsValue fields query
+ * @param depthValue depth query
+ * @param acceptParam accept parameter
+ * @return {@code ResponseEntity} response entity
+ */
+ public ResponseEntity<String> getResouceDataForOperational(final String nodeId,
+ final String resourceId,
+ final String fieldsValue,
+ final Integer depthValue,
+ final String acceptParam) {
+ final String getResourceDataUrl = prepareResourceDataUrl(nodeId,
+ resourceId,
+ getQueryList(fieldsValue, depthValue, "content=all"));
+ final HttpHeaders httpHeaders = new HttpHeaders();
+ if (!StringUtils.isEmpty(acceptParam)) {
+ httpHeaders.set(HttpHeaders.ACCEPT, acceptParam);
+ }
+ return sdncRestconfClient.getOperation(getResourceDataUrl, httpHeaders);
+ }
+
+ @NotNull
+ private List<String> getQueryList(final String fieldsValue, final Integer depthValue, final String contentQuery) {
+ final List<String> queryList = new LinkedList<>();
+ if (!StringUtils.isEmpty(fieldsValue)) {
+ queryList.add("fields=" + fieldsValue);
+ }
+ if (depthValue != null) {
+ queryList.add("depth=" + depthValue);
+ }
+ if (!StringUtils.isEmpty(contentQuery)) {
+ queryList.add(contentQuery);
+ }
+ return queryList;
+ }
+
+
+ @NotNull
private String prepareGetSchemaUrl(final String nodeId) {
- final var topologyMountUrl = topologyUrlData + MOUNT_URL_TEMPLATE;
- final String topologyMountUrlWithNodeId = topologyMountUrl.replace("{nodeId}", nodeId);
- final String resourceUrl = topologyMountUrlWithNodeId.concat(GET_SCHEMA_URL);
- return resourceUrl;
+ final var getSchemaUrl = addResource(addTopologyDataUrlwithNode(nodeId), GET_SCHEMA_URL);
+ return getSchemaUrl;
}
private String prepareGetOperationSchemaUrl(final String nodeId) {
@@ -91,4 +136,43 @@ public class SdncOperations {
final var topologyMountUrlWithNodeId = topologyMountUrl.replace("{nodeId}", nodeId);
return topologyMountUrlWithNodeId.concat(GET_SCHEMA_SOURCES_URL);
}
-}
+
+ @NotNull
+ private String prepareResourceDataUrl(final String nodeId,
+ final String resourceId,
+ final List<String> queryList) {
+ final var resourceDataUrl = addQuery(addResource(addTopologyDataUrlwithNode(nodeId), resourceId), queryList);
+ return resourceDataUrl;
+ }
+
+ @NotNull
+ private String addResource(final String url, final String resourceId) {
+ if (resourceId.startsWith("/")) {
+ return url.concat(resourceId);
+ } else {
+ return url.concat("/" + resourceId);
+ }
+ }
+
+ @NotNull
+ private String addQuery(final String url, final List<String> queryList) {
+ if (queryList.isEmpty()) {
+ return url;
+ }
+ final StringBuilder urlBuilder = new StringBuilder(url);
+ urlBuilder.append("?");
+ urlBuilder.append(queryList.get(0));
+ for (int i = 1; i < queryList.size(); i++) {
+ urlBuilder.append("&");
+ urlBuilder.append(queryList.get(i));
+ }
+ return urlBuilder.toString();
+ }
+
+ @NotNull
+ private String addTopologyDataUrlwithNode(final String nodeId) {
+ 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 03bffe4b..0c8ae3fc 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
@@ -36,7 +36,9 @@ 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
@WebMvcTest
@AutoConfigureMockMvc(addFilters = false)
@@ -152,4 +154,25 @@ class DmiRestControllerSpec extends Specification {
then: 'a not found status is returned'
response.status == HttpStatus.NOT_FOUND.value()
}
-}
+
+ def 'Get resource data for cm handle.'() {
+ given: 'Get resource data url'
+ def getResourceDataForCmHandleUrl = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-operational" +
+ "/resourceIdentifier?fields=myfields&depth=5"
+ def json = '{"cmHandleProperties" : { "prop1" : "value1", "prop2" : "value2"}}'
+ when: 'get resource data GET api is invoked'
+ def response = mvc.perform(
+ put(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',
+ 'resourceIdentifier',
+ 'application/json',
+ 'myfields',
+ 5,
+ ['prop1':'value1', 'prop2':'value2'])
+ }
+} \ No newline at end of file
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 1854b24d..da8ff6b8 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
@@ -27,6 +27,7 @@ import org.onap.cps.ncmp.dmi.exception.CmHandleRegistrationException
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.ModuleReference
import org.onap.cps.ncmp.dmi.service.client.NcmpRestClient
import org.onap.cps.ncmp.dmi.service.operation.SdncOperations
@@ -136,8 +137,8 @@ class DmiServiceImplSpec extends Specification {
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)
- then: 'the response contains the expected response body'
- response.contains('["response-body1","response-body2"]')
+ and: 'the response equals to the expected response body'
+ response == '["response-body1","response-body2"]'
}
def 'Get module resources for a failed get module schema request.'() {
@@ -148,4 +149,39 @@ class DmiServiceImplSpec extends Specification {
then: 'ModuleResourceNotFoundException is thrown'
thrown(ModuleResourceNotFoundException)
}
-}
+
+ def 'Get resource data from cm handle.'() {
+ given: 'cm-handle, pass through parameter, resourceId, accept header, fields, depth'
+ def cmHandle = 'testCmHandle'
+ def resourceId = 'testResourceId'
+ def acceptHeaderParam = 'testAcceptParam'
+ def fieldsParam = 'testFields'
+ def depthParam = 10
+ and: 'sdnc operation returns OK response'
+ mockSdncOperations.getResouceDataForOperational(cmHandle, resourceId, fieldsParam, depthParam, acceptHeaderParam ) >> new ResponseEntity<>('response json', HttpStatus.OK)
+ when: 'get resource data from cm handles service method invoked'
+ def response = objectUnderTest.getResourceDataOperationalForCmHandle(cmHandle,
+ resourceId, acceptHeaderParam,
+ fieldsParam, depthParam, null)
+ 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 cmHandle = 'testCmHandle'
+ def resourceId = 'testResourceId'
+ def acceptHeaderParam = 'testAcceptParam'
+ def fieldsParam = 'testFields'
+ def depthParam = 10
+ and: 'sdnc operation returns "NOT_FOUND" response'
+ mockSdncOperations.getResouceDataForOperational(cmHandle, resourceId, fieldsParam, depthParam, acceptHeaderParam )
+ >> new ResponseEntity<>(HttpStatus.NOT_FOUND)
+ when: 'get resource data from cm handles service method invoked'
+ objectUnderTest.getResourceDataOperationalForCmHandle(cmHandle,
+ resourceId, acceptHeaderParam,
+ fieldsParam, depthParam, null)
+ then: 'resource data not found'
+ thrown(ResourceDataNotFound.class)
+ }
+} \ 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 6d9445c1..e2621e47 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
@@ -22,6 +22,7 @@ package org.onap.cps.ncmp.dmi.service.client
import org.onap.cps.ncmp.dmi.config.DmiConfiguration
import org.springframework.http.HttpEntity
+import org.springframework.http.HttpHeaders
import org.springframework.http.ResponseEntity
import org.springframework.web.client.RestTemplate
import spock.lang.Specification
@@ -64,6 +65,20 @@ class SdncRestconfClientSpec extends Specification {
result == mockResponseEntity
}
+ def 'SDNC GET operation with header.'() {
+ given: 'a get url'
+ def getResourceUrl = '/getResourceUrl'
+ and: 'sdnc properties'
+ setupTestConfigurationData()
+ and: 'the rest template returns a valid response entity'
+ def mockResponseEntity = Mock(ResponseEntity)
+ mockRestTemplate.getForEntity({ it.toString() == 'http://some-uri/getResourceUrl' }, String.class, _ as HttpEntity) >> mockResponseEntity
+ when: 'GET operation is invoked'
+ def result = objectUnderTest.getOperation(getResourceUrl, new HttpHeaders())
+ then: 'the output of the method is equal to the output from the test template'
+ result == mockResponseEntity
+ }
+
def setupTestConfigurationData() {
mockSdncProperties.baseUrl >> 'http://some-uri'
mockSdncProperties.authUsername >> 'some-username'
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 9b07d68e..8a415c82 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
@@ -25,6 +25,7 @@ import org.onap.cps.ncmp.dmi.service.client.SdncRestconfClient
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.test.context.ContextConfiguration
import spock.lang.Specification
@@ -34,6 +35,7 @@ class SdncOperationsSpec extends Specification {
@SpringBean
SdncRestconfClient mockSdncRestClient = Mock()
+
@Autowired
SdncOperations objectUnderTest
@@ -56,4 +58,13 @@ class SdncOperationsSpec extends Specification {
then: 'the SDNC Rest client is invoked with the correct URL and json data'
1 * mockSdncRestClient.postOperationWithJsonData(expectedUrl, 'some-json-data')
}
-}
+
+ def 'Get resource data from node 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?fields=testFields&depth=10&content=all'
+ when: 'called get modules from node'
+ objectUnderTest.getResouceDataForOperational('node1', 'testResourceId', 'testFields', 10,'testAcceptParam')
+ then: 'the get operation is executed with the correct URL'
+ 1 * mockSdncRestClient.getOperation(expectedUrl, _ as HttpHeaders)
+ }
+} \ No newline at end of file