From e398be5923a47650b109512c795244cdc2b5eb10 Mon Sep 17 00:00:00 2001 From: tragait Date: Fri, 6 Aug 2021 17:01:31 +0100 Subject: implement passthough operational for dmi Issue-ID: CPS-486 Signed-off-by: tragait Change-Id: Icf48fa93ea1f0d8a27d2e7e1ab0cfd6096a765ec --- docs/openapi/components.yml | 11 +++ docs/openapi/openapi.yml | 50 ++++++++++ .../ncmp/dmi/exception/ResourceDataNotFound.java | 38 ++++++++ .../dmi/rest/controller/DmiRestController.java | 34 ++++++- .../org/onap/cps/ncmp/dmi/service/DmiService.java | 25 ++++- .../onap/cps/ncmp/dmi/service/DmiServiceImpl.java | 46 ++++++++-- .../dmi/service/client/SdncRestconfClient.java | 20 +++- .../ncmp/dmi/service/operation/SdncOperations.java | 102 +++++++++++++++++++-- .../rest/controller/DmiRestControllerSpec.groovy | 25 ++++- .../cps/ncmp/dmi/service/DmiServiceImplSpec.groovy | 42 ++++++++- .../service/client/SdncRestconfClientSpec.groovy | 15 +++ .../service/operation/SdncOperationsSpec.groovy | 13 ++- 12 files changed, 391 insertions(+), 30 deletions(-) create mode 100644 src/main/java/org/onap/cps/ncmp/dmi/exception/ResourceDataNotFound.java 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 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 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 convertRestObjectToJavaApiObject(final ModuleRequestParent moduleRequestParent) { return objectMapper .convertValue(moduleRequestParent.getData().getModules(), new TypeReference>() {}); } -} +} \ 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 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 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 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 cmHandlePropertyMap) { + // not using cmHandlePropertyMap of onap dmi impl , other dmi impl might use this. + final ResponseEntity responseEntity = sdncOperations.getResouceDataForOperational(cmHandle, + resourceIdentifier, + fieldsQuery, + depthQuery, + acceptParam); + return prepareAndSendResponse(responseEntity, cmHandle); + } + + private String prepareAndSendResponse(final ResponseEntity 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 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 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 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 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 getQueryList(final String fieldsValue, final Integer depthValue, final String contentQuery) { + final List 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 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 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('response-body1', HttpStatus.OK) 1 * mockSdncOperations.getModuleResource(cmHandle,excpectedModulesJson2) >> new ResponseEntity('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 -- cgit 1.2.3-korg