Add Integration Test to cover DmiRestClient Fluent lambda method calls 96/142396/3
authorToineSiebelink <toine.siebelink@est.tech>
Fri, 7 Nov 2025 13:29:36 +0000 (13:29 +0000)
committerToine Siebelink <toine.siebelink@est.tech>
Mon, 10 Nov 2025 17:08:45 +0000 (17:08 +0000)
- Tests to cover WebClient method calls that cannot be covered in unit test
  .headers(..)
  .OnErrorMap()
- refactored error handling and removed impossible (legacy() exception handling
- refactored 2 data Job specifically (named) methods to single generic data get method
- removed all unit test no longer needed due to integration test for DMI Web Client

Issue-ID: CPS-2702
Change-Id: I431df50189c10f230ed0459a73a98fda17384070
Signed-off-by: ToineSiebelink <toine.siebelink@est.tech>
cps-ncmp-service/pom.xml
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImpl.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImpl.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiRestClient.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImplSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImplSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientIntegrationSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientSpec.groovy

index 3bffd57..4517d4d 100644 (file)
@@ -34,7 +34,7 @@
     <artifactId>cps-ncmp-service</artifactId>
 
     <properties>
-        <minimum-coverage>0.96</minimum-coverage>
+        <minimum-coverage>0.97</minimum-coverage>
     </properties>
     <dependencies>
         <dependency>
             <groupId>io.swagger.core.v3</groupId>
             <artifactId>swagger-annotations</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>mockwebserver</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
     <build>
         <plugins>
index 1bc90cd..991ca1f 100644 (file)
@@ -51,6 +51,6 @@ public class DataJobResultServiceImpl implements DataJobResultService {
                                            .queryParameter("destination", destination)
                                            .createUrlTemplateParameters(dmiServiceName,
                                                dmiServiceAuthenticationProperties.getDmiBasePath());
-        return dmiRestClient.getDataJobResult(urlTemplateParameters, authorization).block();
+        return dmiRestClient.asynchronousDmiDataRequest(urlTemplateParameters, authorization).block();
     }
 }
index 8d7061c..3525f57 100644 (file)
@@ -48,7 +48,7 @@ public class DataJobStatusServiceImpl implements DataJobStatusService {
         final UrlTemplateParameters urlTemplateParameters = buildUrlParameters(dmiServiceName,
                                                                               dataProducerId,
                                                                               dataProducerJobId);
-        return dmiRestClient.getDataJobStatus(urlTemplateParameters, authorization).block();
+        return dmiRestClient.asynchronousDmiDataRequest(urlTemplateParameters, authorization).block();
     }
 
     private UrlTemplateParameters buildUrlParameters(final String dmiServiceName,
index cec1c36..9939e61 100644 (file)
@@ -24,6 +24,8 @@ package org.onap.cps.ncmp.impl.dmi;
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING;
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA;
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR;
+import static org.onap.cps.ncmp.api.data.models.OperationType.READ;
+import static org.onap.cps.ncmp.impl.models.RequiredDmiService.DATA;
 import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
 import static org.springframework.http.HttpStatus.REQUEST_TIMEOUT;
 
@@ -31,6 +33,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 import java.util.Locale;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.NcmpResponseStatus;
 import org.onap.cps.ncmp.api.data.models.OperationType;
 import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException;
 import org.onap.cps.ncmp.impl.models.RequiredDmiService;
@@ -41,7 +44,6 @@ import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Component;
-import org.springframework.web.client.HttpServerErrorException;
 import org.springframework.web.reactive.function.BodyInserters;
 import org.springframework.web.reactive.function.client.WebClient;
 import org.springframework.web.reactive.function.client.WebClientRequestException;
@@ -82,13 +84,11 @@ public class DmiRestClient {
                                                            final String requestBodyAsJsonString,
                                                            final OperationType operationType,
                                                            final String authorization) {
-        final Mono<ResponseEntity<Object>> responseEntityMono =
-            asynchronousPostOperation(requiredDmiService,
-                    urlTemplateParameters,
-                requestBodyAsJsonString,
-                operationType,
-                authorization);
-        return responseEntityMono.block();
+        return asynchronousPostOperation(requiredDmiService,
+                                         urlTemplateParameters,
+                                         requestBodyAsJsonString,
+                                         operationType,
+                                         authorization).block();
     }
 
     /**
@@ -102,13 +102,11 @@ public class DmiRestClient {
      * @param authorization           The authorization token to be added to the request headers.
      * @return A Mono emitting the response entity containing the server's response.
      */
-    public Mono<ResponseEntity<Object>> asynchronousPostOperation(final RequiredDmiService
-                                                                                      requiredDmiService,
-                                                                              final UrlTemplateParameters
-                                                                                      urlTemplateParameters,
-                                                                              final String requestBodyAsJsonString,
-                                                                              final OperationType operationType,
-                                                                              final String authorization) {
+    public Mono<ResponseEntity<Object>> asynchronousPostOperation(final RequiredDmiService requiredDmiService,
+                                                                  final UrlTemplateParameters urlTemplateParameters,
+                                                                  final String requestBodyAsJsonString,
+                                                                  final OperationType operationType,
+                                                                  final String authorization) {
         final WebClient webClient = getWebClient(requiredDmiService);
         return webClient.post()
                 .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
@@ -129,16 +127,16 @@ public class DmiRestClient {
      * @throws DmiClientRequestException If there is an error during the DMI request.
      */
     public ResponseEntity<Object> synchronousGetOperation(final RequiredDmiService requiredDmiService,
-                                                                        final UrlTemplateParameters
-                                                                            urlTemplateParameters,
-                                                                        final OperationType operationType) {
+                                                          final UrlTemplateParameters urlTemplateParameters,
+                                                          final OperationType operationType) {
         return getWebClient(requiredDmiService)
             .get()
             .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
             .headers(httpHeaders -> configureHttpHeaders(httpHeaders, NO_AUTHORIZATION))
             .retrieve()
             .toEntity(Object.class)
-            .onErrorMap(throwable -> handleDmiClientException(throwable, operationType.getOperationName()))
+            .onErrorMap(throwable ->
+                handleDmiClientException(throwable, operationType.getOperationName()))
             .block();
     }
 
@@ -152,9 +150,8 @@ public class DmiRestClient {
      * @throws DmiClientRequestException If there is an error during the DMI request.
      */
     public ResponseEntity<Object> synchronousPutOperation(final RequiredDmiService requiredDmiService,
-                                                            final UrlTemplateParameters
-                                                                urlTemplateParameters,
-                                                            final OperationType operationType) {
+                                                          final UrlTemplateParameters urlTemplateParameters,
+                                                          final OperationType operationType) {
         return getWebClient(requiredDmiService)
             .get()
             .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
@@ -192,39 +189,21 @@ public class DmiRestClient {
     }
 
     /**
-     * Retrieves the status of a data job from the DMI service.
+     * Retrieves the result of a data get request from the DMI service asynchronously.
      *
-     * @param urlTemplateParameters   The URL template parameters for the DMI data job status endpoint.
+     * @param urlTemplateParameters   The URL template parameters for the DMI data endpoint.
      * @param authorization           The authorization token to be added to the request headers.
-     * @return A Mono emitting the status of the data job in JSON format.
-     * @throws DmiClientRequestException If there is an error during the DMI request.
+     * @return A Mono emitting the result of the request as a String.
      */
-    public Mono<String> getDataJobStatus(final UrlTemplateParameters urlTemplateParameters,
-                                         final String authorization) {
+    public Mono<String> asynchronousDmiDataRequest(final UrlTemplateParameters urlTemplateParameters,
+                                                   final String authorization) {
 
         return dataServicesWebClient.get()
                 .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
                 .headers(httpHeaders -> configureHttpHeaders(httpHeaders, authorization))
                 .retrieve()
                 .bodyToMono(String.class)
-                .onErrorMap(throwable -> handleDmiClientException(throwable, OperationType.READ.getOperationName()));
-    }
-
-    /**
-     * Retrieves the result of a data job from the DMI service.
-     *
-     * @param urlTemplateParameters   The URL template parameters for the DMI data job status endpoint.
-     * @param authorization           The authorization token to be added to the request headers.
-     * @return A Mono emitting the result of the data job as a String.
-     * @throws DmiClientRequestException If there is an error during the DMI request.
-     */
-    public Mono<String> getDataJobResult(final UrlTemplateParameters urlTemplateParameters,
-                                         final String authorization) {
-        return dataServicesWebClient.get()
-                .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
-                .headers(httpHeaders -> configureHttpHeaders(httpHeaders, authorization))
-                .retrieve().bodyToMono(String.class)
-                .onErrorMap(throwable -> handleDmiClientException(throwable, OperationType.READ.getOperationName()));
+                .onErrorMap(throwable -> handleDmiClientException(throwable, READ.getOperationName()));
     }
 
     /**
@@ -249,7 +228,7 @@ public class DmiRestClient {
     }
 
     private WebClient getWebClient(final RequiredDmiService requiredDmiService) {
-        return requiredDmiService.equals(RequiredDmiService.DATA) ? dataServicesWebClient : modelServicesWebClient;
+        return DATA.equals(requiredDmiService) ? dataServicesWebClient : modelServicesWebClient;
     }
 
     private void configureHttpHeaders(final HttpHeaders httpHeaders, final String authorization) {
@@ -263,29 +242,20 @@ public class DmiRestClient {
 
     private DmiClientRequestException handleDmiClientException(final Throwable throwable, final String operationType) {
         if (throwable instanceof WebClientResponseException webClientResponseException) {
-            if (webClientResponseException.getStatusCode().isSameCodeAs(REQUEST_TIMEOUT)) {
-                throw new DmiClientRequestException(webClientResponseException.getStatusCode().value(),
-                        webClientResponseException.getMessage(),
-                        jsonObjectMapper.asJsonString(webClientResponseException.getResponseBodyAsString()),
-                        DMI_SERVICE_NOT_RESPONDING);
-            }
-            throw new DmiClientRequestException(webClientResponseException.getStatusCode().value(),
+            final NcmpResponseStatus ncmpResponseStatus =  webClientResponseException.getStatusCode()
+                .isSameCodeAs(REQUEST_TIMEOUT) ? DMI_SERVICE_NOT_RESPONDING : UNABLE_TO_READ_RESOURCE_DATA;
+            return new DmiClientRequestException(webClientResponseException.getStatusCode().value(),
                     webClientResponseException.getMessage(),
                     jsonObjectMapper.asJsonString(webClientResponseException.getResponseBodyAsString()),
-                    UNABLE_TO_READ_RESOURCE_DATA);
-
+                    ncmpResponseStatus);
         }
         final String exceptionMessage = "Unable to " + operationType + " resource data.";
-        if (throwable instanceof WebClientRequestException webClientRequestException) {
-            throw new DmiClientRequestException(HttpStatus.SERVICE_UNAVAILABLE.value(),
-                    webClientRequestException.getMessage(),
+        if (throwable instanceof WebClientRequestException) {
+            return new DmiClientRequestException(HttpStatus.SERVICE_UNAVAILABLE.value(), throwable.getMessage(),
                     exceptionMessage, DMI_SERVICE_NOT_RESPONDING);
         }
-        if (throwable instanceof HttpServerErrorException httpServerErrorException) {
-            throw new DmiClientRequestException(httpServerErrorException.getStatusCode().value(), exceptionMessage,
-                    httpServerErrorException.getResponseBodyAsString(), DMI_SERVICE_NOT_RESPONDING);
-        }
-        throw new DmiClientRequestException(INTERNAL_SERVER_ERROR.value(), exceptionMessage, throwable.getMessage(),
+        return new DmiClientRequestException(INTERNAL_SERVER_ERROR.value(), exceptionMessage, throwable.getMessage(),
                 UNKNOWN_ERROR);
     }
+
 }
index bc2b3d3..b25261a 100644 (file)
@@ -45,7 +45,7 @@ class DataJobResultServiceImplSpec extends Specification {
             def destination = 'some-destination'
             def urlParams = new UrlTemplateParameters('some-dmi-service/dmi/v1/cmwriteJob/dataProducer/{dataProducerId}/dataProducerJob/{dataProducerJobId}/result?destination={destination}', ['dataProducerJobId':'some-data-producer-job-id', 'dataProducerId':'some-data-producer-id', 'destination': 'some-destination'])
         and: 'the rest client returns the result for the given parameters'
-            mockDmiRestClient.getDataJobResult(urlParams, authorization) >> Mono.just('some result')
+            mockDmiRestClient.asynchronousDmiDataRequest(urlParams, authorization) >> Mono.just('some result')
         when: 'the job status is queried'
             def result = objectUnderTest.getDataJobResult(authorization, dmiServiceName,dataProducerId,  dataProducerJobId, destination)
         then: 'the result from the rest client is returned'
index da557de..bb2fe3e 100644 (file)
@@ -44,7 +44,7 @@ class DataJobStatusServiceImplSpec extends Specification {
             def authorization = 'my authorization header'
             def urlParams = new UrlTemplateParameters('some-dmi-service/dmi/v1/cmwriteJob/dataProducer/{dataProducerId}/dataProducerJob/{dataProducerJobId}/status', ['dataProducerId':'some-data-producer-id', 'dataProducerJobId':'some-data-producer-job-id'])
         and: 'the rest client returns a status for the given parameters'
-            mockDmiRestClient.getDataJobStatus(urlParams, authorization) >> Mono.just('some status')
+            mockDmiRestClient.asynchronousDmiDataRequest(urlParams, authorization) >> Mono.just('some status')
         when: 'the job status is queried'
             def status = objectUnderTest.getDataJobStatus(authorization, dmiServiceName, dataProducerId, dataProducerJobId)
         then: 'the status from the rest client is returned'
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientIntegrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientIntegrationSpec.groovy
new file mode 100644 (file)
index 0000000..8d70591
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved.
+ *  ================================================================================
+ *  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.impl.dmi
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import okhttp3.mockwebserver.MockResponse
+import okhttp3.mockwebserver.MockWebServer
+import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters
+import org.onap.cps.utils.JsonObjectMapper
+import org.springframework.http.HttpStatus
+import org.springframework.web.reactive.function.client.WebClient
+import org.springframework.web.util.InvalidUrlException
+import spock.lang.Specification
+
+import static org.onap.cps.ncmp.api.data.models.OperationType.CREATE
+import static org.onap.cps.ncmp.api.data.models.OperationType.READ
+import static org.onap.cps.ncmp.api.data.models.OperationType.UPDATE
+import static org.onap.cps.ncmp.impl.models.RequiredDmiService.DATA
+import static org.onap.cps.ncmp.impl.models.RequiredDmiService.MODEL
+
+class DmiRestClientIntegrationSpec extends Specification {
+
+    def mockWebServer = new MockWebServer()
+    def baseUrl = mockWebServer.url('/')
+    def webClientForMockServer = WebClient.builder().baseUrl(baseUrl.toString()).build()
+
+    def urlTemplateParameters = new UrlTemplateParameters('/myPath', [someParam: 'value'])
+    def mockDmiServiceAuthenticationProperties = Mock(DmiServiceAuthenticationProperties)
+
+    JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+    def objectUnderTest = new DmiRestClient(mockDmiServiceAuthenticationProperties, jsonObjectMapper, webClientForMockServer, webClientForMockServer, webClientForMockServer)
+
+    def cleanup() throws IOException {
+        mockWebServer.shutdown()
+    }
+
+    def 'Synchronous DMI #method request.'() {
+        given: 'Web Server wil return OK response'
+            mockWebServer.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.value))
+        when: 'synchronous #method request is made'
+            def result
+            switch(method) {
+                case 'get':
+                    result = objectUnderTest.synchronousGetOperation(DATA, urlTemplateParameters, READ)
+                    break
+                case 'post':
+                    result = objectUnderTest.synchronousPostOperation(DATA, urlTemplateParameters, 'body', CREATE, '')
+                    break
+                case 'put':
+                    result = objectUnderTest.synchronousPutOperation(DATA, urlTemplateParameters, UPDATE)
+                    break
+                case 'delete':
+                    result = objectUnderTest.synchronousDeleteOperation(DATA, urlTemplateParameters)
+            }
+        then: 'the result has the same status code of 200'
+            assert result.statusCode.value() == 200
+        where: 'the following http methods are used'
+            method << ['get', 'post', 'put', 'delete']
+    }
+
+    def 'Synchronous DMI #method request with invalid JSON.'() {
+        given: 'Web Server wil return OK response'
+            mockWebServer.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.value)
+                .setBody('invalid-json:!!')
+                .addHeader('Content-Type', 'application/json'))
+        when: 'synchronous #method request is attempted (on Model service this time for coverage on service selector)'
+            switch(method) {
+                case 'get':
+                    objectUnderTest.synchronousGetOperation(MODEL, urlTemplateParameters, READ)
+                    break;
+                case 'post':
+                    objectUnderTest.synchronousPostOperation(MODEL, urlTemplateParameters, 'body', READ, 'some authorization')
+                    break
+                case 'put':
+                    objectUnderTest.synchronousPutOperation(MODEL, urlTemplateParameters, UPDATE)
+                    break
+                case 'delete':
+                    objectUnderTest.synchronousDeleteOperation(MODEL, urlTemplateParameters)
+            }
+        then: 'a dmi client request exception is thrown with the correct error codes'
+            def thrown = thrown(DmiClientRequestException)
+            assert thrown.getHttpStatusCode() == 500
+            assert thrown.ncmpResponseStatus.code == '108'
+        where: 'the following http methods are used'
+            method << ['get','post','put','delete']
+    }
+
+    def 'DMI Request with non-responding server.'() {
+        given: 'the web server is shut down'
+            mockWebServer.shutdown()
+        when: 'a synchronous read request is attempted'
+            objectUnderTest.synchronousGetOperation(DATA, urlTemplateParameters, READ)
+        then: 'a dmi client request exception is thrown with status code of 503 Service Unavailable'
+            def thrown = thrown(DmiClientRequestException)
+            assert thrown.getHttpStatusCode() == 503
+    }
+
+    def 'DMI Request with #scenario.'() {
+        given: 'the mock server or exception setup'
+            mockWebServer.enqueue(new MockResponse().setResponseCode(responseCode.value))
+        when: 'a synchronous read request is attempted'
+            objectUnderTest.synchronousGetOperation(DATA, urlTemplateParameters, READ)
+        then: 'a DMI client request exception is thrown with the right status'
+            def thrown = thrown(DmiClientRequestException)
+            assert thrown.httpStatusCode == expectedStatus
+        where: 'the following HTTP Errors are applied'
+            scenario             | responseCode                   || expectedStatus
+            'Client error (418)' | HttpStatus.I_AM_A_TEAPOT       || 418
+            'Timeout (408)'      | HttpStatus.REQUEST_TIMEOUT     || 408
+            'Server error (503)' | HttpStatus.SERVICE_UNAVAILABLE || 503
+    }
+
+    def 'DMI Request with unexpected runtime exception.'() {
+        given: 'Mock a bad URL that causes IllegalArgumentException before HTTP call'
+            def badUrlParameters = new UrlTemplateParameters(':://bad url', [someParam: 'value'])
+        when: 'a synchronous request is attempted'
+            objectUnderTest.synchronousGetOperation(DATA, badUrlParameters, READ)
+        then: 'a invalid url exception is thrown (no mapping)'
+            thrown(InvalidUrlException)
+    }
+
+    def 'DMI health status check with #scenario.'() {
+        given: 'Web Server will return OK response with status TEST'
+            mockWebServer.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.value)
+                .setBody(jsonBody)
+                .addHeader('Content-Type', 'application/json'))
+        when: 'DMI health status is checked'
+            def result = objectUnderTest.getDmiHealthStatus(urlTemplateParameters).block()
+        then: 'result is as expected'
+            result == expectedResult
+        where: 'following json data is used'
+            scenario       | jsonBody            || expectedResult
+            'Valid Json'   | '{"status":"TEST"}' || 'TEST'
+            'Invalid Json' | 'invalid-json:!!'   || ''
+    }
+
+    def 'Asynchronous DMI data request.'() {
+        given: 'web Server will return OK response with status TEST'
+            mockWebServer.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.value).setBody('TEST'))
+        when: 'asynchronous DMI data request is made'
+            def result = objectUnderTest.asynchronousDmiDataRequest(urlTemplateParameters, 'some authorization').block()
+        then: 'result is TEST'
+            assert result == 'TEST'
+    }
+
+    def 'Asynchronous DMI Data Request with Http Error'() {
+        given: 'web Server will return OK response with status TEST'
+            mockWebServer.enqueue(new MockResponse().setResponseCode(HttpStatus.I_AM_A_TEAPOT.value))
+        when: 'asynchronous DMI data request is attempted'
+            objectUnderTest.asynchronousDmiDataRequest(urlTemplateParameters, 'some authorization').block()
+        then: 'a DMI client request exception is thrown with the same status code 418'
+            def thrown = thrown(DmiClientRequestException)
+            assert thrown.getHttpStatusCode() == 418
+    }
+
+}
index 65437bd..c5f73e4 100644 (file)
 
 package org.onap.cps.ncmp.impl.dmi
 
-import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.databind.node.ObjectNode
-import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException
-import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters
-import org.onap.cps.ncmp.utils.TestUtils
 import org.onap.cps.utils.JsonObjectMapper
 import org.springframework.http.HttpHeaders
-import org.springframework.http.HttpStatus
-import org.springframework.http.HttpStatusCode
-import org.springframework.http.ResponseEntity
-import org.springframework.web.client.HttpServerErrorException
-import org.springframework.web.reactive.function.client.WebClient
-import org.springframework.web.reactive.function.client.WebClientRequestException
-import org.springframework.web.reactive.function.client.WebClientResponseException
-import reactor.core.publisher.Mono
 import spock.lang.Specification
 
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR
-import static org.onap.cps.ncmp.api.data.models.OperationType.READ
-import static org.onap.cps.ncmp.impl.models.RequiredDmiService.DATA
-import static org.onap.cps.ncmp.impl.models.RequiredDmiService.MODEL
-
 class DmiRestClientSpec extends Specification {
 
-    static final NO_AUTH_HEADER = null
-    static final BASIC_AUTH_HEADER = 'Basic c29tZSB1c2VyOnNvbWUgcGFzc3dvcmQ='
-    static final BEARER_AUTH_HEADER = 'Bearer my-bearer-token'
-    static final urlTemplateParameters = new UrlTemplateParameters('/{pathParam1}/{pathParam2}', ['pathParam1': 'my', 'pathParam2': 'url'])
-
-    def mockDataServicesWebClient = Mock(WebClient)
-    def mockModelServicesWebClient = Mock(WebClient)
-    def mockHealthChecksWebClient = Mock(WebClient)
-
-    def mockRequestBodyUriSpec = Mock(WebClient.RequestBodyUriSpec)
-    def mockResponseSpec = Mock(WebClient.ResponseSpec)
+    static NO_AUTH_HEADER = null
+    static BASIC_AUTH_HEADER = 'Basic c29tZSB1c2VyOnNvbWUgcGFzc3dvcmQ='
+    static BEARER_AUTH_HEADER = 'Bearer my-bearer-token'
 
     def mockDmiServiceAuthenticationProperties = Mock(DmiServiceAuthenticationProperties)
 
     JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
-    def responseFromDmiService = new ResponseEntity<>('Response from DMI service', HttpStatus.I_AM_A_TEAPOT)
-
-    DmiRestClient objectUnderTest = new DmiRestClient(mockDmiServiceAuthenticationProperties, jsonObjectMapper, mockDataServicesWebClient, mockModelServicesWebClient, mockHealthChecksWebClient)
-
-    def setup() {
-        mockRequestBodyUriSpec.uri(*_) >> mockRequestBodyUriSpec
-        mockRequestBodyUriSpec.headers(_) >> mockRequestBodyUriSpec
-        mockRequestBodyUriSpec.body(_) >> mockRequestBodyUriSpec
-        mockRequestBodyUriSpec.retrieve() >> mockResponseSpec
-    }
 
-    def 'DMI POST Operation with JSON for DMI Data Service.'() {
-        given: 'the Data web client returns a valid response entity for the expected parameters'
-            mockDataServicesWebClient.post() >> mockRequestBodyUriSpec
-            mockResponseSpec.toEntity(Object.class) >> Mono.just(responseFromDmiService)
-        when: 'POST operation is invoked for Data Service'
-            def result = objectUnderTest.synchronousPostOperation(DATA, urlTemplateParameters, 'some json', READ, NO_AUTH_HEADER)
-        then: 'the output of the method is equal to the output from dmi service'
-            assert result.equals(responseFromDmiService)
-    }
-
-    def 'DMI POST Operation with JSON for DMI Model Service.'() {
-        given: 'the Model web client returns a valid response entity for the expected parameters'
-            mockModelServicesWebClient.post() >> mockRequestBodyUriSpec
-            mockResponseSpec.toEntity(Object.class) >> Mono.just(responseFromDmiService)
-        when: 'POST operation is invoked for Model Service'
-            def result = objectUnderTest.synchronousPostOperation(MODEL, urlTemplateParameters, 'some json', READ, NO_AUTH_HEADER)
-        then: 'the output of the method is equal to the output from the dmi service'
-            assert result.equals(responseFromDmiService)
-    }
-
-    def 'Synchronous DMI POST operation with #scenario.'() {
-        given: 'the web client unable to return response entity but error'
-            mockDataServicesWebClient.post() >> mockRequestBodyUriSpec
-            mockResponseSpec.toEntity(Object.class) >> Mono.error(exception)
-        when: 'POST operation is invoked'
-            objectUnderTest.synchronousPostOperation(DATA, urlTemplateParameters, 'some json', READ, NO_AUTH_HEADER)
-        then: 'a http client exception is thrown'
-            def thrown = thrown(DmiClientRequestException)
-        and: 'the exception has the relevant details from the error response'
-            assert thrown.ncmpResponseStatus == expectedNcmpResponseStatusCode
-            assert thrown.httpStatusCode == httpStatusCode
-        where: 'the following errors occur'
-            scenario                  | httpStatusCode | exception                                                                                        || expectedNcmpResponseStatusCode
-            'dmi service unavailable' | 503            | new WebClientRequestException(new RuntimeException('some-error'), null, null, new HttpHeaders()) || DMI_SERVICE_NOT_RESPONDING
-            'dmi request timeout'     | 408            | new WebClientResponseException('message', httpStatusCode, 'statusText', null, null, null)        || DMI_SERVICE_NOT_RESPONDING
-            'dmi server error'        | 500            | new WebClientResponseException('message', httpStatusCode, 'statusText', null, null, null)        || UNABLE_TO_READ_RESOURCE_DATA
-            'dmi service unavailable' | 503            | new HttpServerErrorException(HttpStatusCode.valueOf(503))                                        || DMI_SERVICE_NOT_RESPONDING
-            'unknown error'           | 500            | new Throwable('message')                                                                         || UNKNOWN_ERROR
-    }
-
-    def 'Synchronous DMI GET Operation.'() {
-        given: 'the Data web client returns a valid response entity for the expected parameters'
-            mockDataServicesWebClient.get() >> mockRequestBodyUriSpec
-            mockResponseSpec.toEntity(_) >> Mono.just(responseFromDmiService)
-        when: 'GET operation is invoked for Data Service'
-            def result = objectUnderTest.synchronousGetOperation(DATA, urlTemplateParameters, READ)
-        then: 'the output of the method is equal to the output from the DMI service'
-            assert result.equals(responseFromDmiService)
-    }
-
-    def 'Dmi trust level is determined by spring boot health status.'() {
-        given: 'a health check response'
-            def dmiPluginHealthCheckResponseJsonData = TestUtils.getResourceFileContent('dmiPluginHealthCheckResponse.json')
-            def jsonNode = jsonObjectMapper.convertJsonString(dmiPluginHealthCheckResponseJsonData, JsonNode.class)
-            ((ObjectNode) jsonNode).put('status', 'my status')
-            mockHealthChecksWebClient.get() >> mockRequestBodyUriSpec
-            mockResponseSpec.bodyToMono(JsonNode.class) >> Mono.just(jsonNode)
-        when: 'get trust level of the dmi plugin'
-            def urlTemplateParameters = new UrlTemplateParameters('some url', [:])
-            def result = objectUnderTest.getDmiHealthStatus(urlTemplateParameters).block()
-        then: 'the status value from the json is returned'
-            assert result == 'my status'
-    }
-
-    def 'Failing to get dmi plugin health status #scenario.'() {
-        given: 'web client instance with #scenario'
-            mockHealthChecksWebClient.get() >> mockRequestBodyUriSpec
-            mockResponseSpec.bodyToMono(_) >> Mono.error(exceptionType)
-        when: 'attempt to get health status of the dmi plugin'
-            def urlTemplateParameters = new UrlTemplateParameters('some url', [:])
-            def result = objectUnderTest.getDmiHealthStatus(urlTemplateParameters).block()
-        then: 'result will be empty'
-            assert result == ''
-        where: 'the following responses are used'
-            scenario                  | exceptionType
-            'dmi request timeout'     | new WebClientResponseException('some-message', 408, 'some-text', null, null, null)
-            'dmi service unavailable' | new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE)
-    }
+    DmiRestClient objectUnderTest = new DmiRestClient(mockDmiServiceAuthenticationProperties, jsonObjectMapper, null, null, null)
 
     def 'DMI auth header #scenario.'() {
         when: 'Specific dmi properties are provided'
@@ -171,34 +56,4 @@ class DmiRestClientSpec extends Specification {
             'DMI basic auth disabled, with NCMP bearer token' | false       | BEARER_AUTH_HEADER || BEARER_AUTH_HEADER
             'DMI basic auth disabled, with NCMP basic auth'   | false       | BASIC_AUTH_HEADER  || NO_AUTH_HEADER
     }
-
-    def 'DMI Data Job Status request for DMI Data Service.'() {
-        given: 'the Data web client returns a valid response entity for the expected parameters'
-            mockDataServicesWebClient.get() >> mockRequestBodyUriSpec
-            mockResponseSpec.bodyToMono(String.class) >> Mono.just(responseFromDmiService)
-        when: 'Data job status is invoked for Data Service'
-            def result = objectUnderTest.getDataJobStatus(urlTemplateParameters, NO_AUTH_HEADER).block()
-        then: 'the response equals to response from the DMI service'
-            assert result.equals(responseFromDmiService)
-    }
-
-    def 'Get data job result from DMI.'() {
-        given: 'the Data web client returns a valid response entity for the expected parameters'
-            mockDataServicesWebClient.get() >> mockRequestBodyUriSpec
-            mockResponseSpec.bodyToMono(String.class) >> Mono.just(responseFromDmiService)
-        when: 'GET operation is invoked for Data Service'
-            def result = objectUnderTest.getDataJobResult(urlTemplateParameters, NO_AUTH_HEADER).block()
-        then: 'the response has some value'
-            assert result.equals(responseFromDmiService)
-    }
-
-    def 'DMI DELETE Operation for DMI Data Service.'() {
-        given: 'the Data web client returns a valid response entity for the expected parameters'
-            mockDataServicesWebClient.delete() >> mockRequestBodyUriSpec
-            mockResponseSpec.toEntity(Object.class) >> Mono.just(responseFromDmiService)
-        when: 'DELETE operation is invoked for Data Service'
-            def result = objectUnderTest.synchronousDeleteOperation(DATA, urlTemplateParameters)
-        then: 'The response is the same as the response from the DMI service'
-            assert result.equals(responseFromDmiService)
-    }
 }