implement passthough operational for dmi 69/123169/8
authortragait <rahul.tyagi@est.tech>
Fri, 6 Aug 2021 16:01:31 +0000 (17:01 +0100)
committertragait <rahul.tyagi@est.tech>
Tue, 17 Aug 2021 12:55:12 +0000 (13:55 +0100)
Issue-ID: CPS-486
Signed-off-by: tragait <rahul.tyagi@est.tech>
Change-Id: Icf48fa93ea1f0d8a27d2e7e1ab0cfd6096a765ec

12 files changed:
docs/openapi/components.yml
docs/openapi/openapi.yml
src/main/java/org/onap/cps/ncmp/dmi/exception/ResourceDataNotFound.java [new file with mode: 0644]
src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java
src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java
src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy
src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy

index c67dad6..05f1ac0 100644 (file)
@@ -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
index f261c0d..a4a238c 100644 (file)
@@ -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 (file)
index 0000000..dbef347
--- /dev/null
@@ -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);
+    }
+}
index 5725f09..969e08d 100644 (file)
@@ -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
index aeff3dc..528eb64 100644 (file)
@@ -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
index bf0689c..32c8526 100644 (file)
@@ -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
index adac5e6..499033d 100644 (file)
@@ -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
index 0d1c343..358da59 100644 (file)
 
 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
index 03bffe4..0c8ae3f 100644 (file)
@@ -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
index 1854b24..da8ff6b 100644 (file)
@@ -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
index 6d9445c..e2621e4 100644 (file)
@@ -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'
index 9b07d68..8a415c8 100644 (file)
@@ -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