diff options
Diffstat (limited to 'cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy')
-rw-r--r-- | cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy | 108 |
1 files changed, 69 insertions, 39 deletions
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy index 003dbf5b0..d2dce06b0 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation + * Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,32 +21,36 @@ package org.onap.cps.ncmp.api.impl.client +import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ +import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH +import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE +import static org.springframework.http.HttpStatus.SERVICE_UNAVAILABLE +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 com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.ObjectNode -import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration; -import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException +import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration +import org.onap.cps.ncmp.api.impl.exception.InvalidDmiResourceUrlException +import org.onap.cps.ncmp.api.impl.exception.DmiClientRequestException import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.utils.JsonObjectMapper 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.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.test.context.ContextConfiguration -import org.springframework.test.context.TestPropertySource import org.springframework.web.client.HttpServerErrorException import org.springframework.web.reactive.function.client.WebClient import reactor.core.publisher.Mono import spock.lang.Specification - -import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ -import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH -import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE +import org.springframework.web.reactive.function.client.WebClientResponseException +import org.onap.cps.ncmp.api.impl.config.DmiProperties @SpringBootTest -@ContextConfiguration(classes = [DmiWebClientConfiguration, DmiRestClient, ObjectMapper]) +@ContextConfiguration(classes = [DmiProperties, DmiRestClient, ObjectMapper]) class DmiRestClientSpec extends Specification { static final NO_AUTH_HEADER = null @@ -54,7 +58,7 @@ class DmiRestClientSpec extends Specification { static final BEARER_AUTH_HEADER = 'Bearer my-bearer-token' @Autowired - DmiWebClientConfiguration.DmiProperties dmiProperties + DmiProperties dmiProperties @Autowired DmiRestClient objectUnderTest @@ -62,51 +66,83 @@ class DmiRestClientSpec extends Specification { @SpringBean WebClient mockWebClient = Mock(WebClient); - @Autowired - ObjectMapper objectMapper + @SpringBean + JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) def mockRequestBodyUriSpec = Mock(WebClient.RequestBodyUriSpec) def mockResponseSpec = Mock(WebClient.ResponseSpec) def mockResponseEntity = Mock(ResponseEntity) - def monoSpec = Mono.just(mockResponseEntity) + + def setup() { + mockRequestBodyUriSpec.uri(_) >> mockRequestBodyUriSpec + mockRequestBodyUriSpec.headers(_) >> mockRequestBodyUriSpec + mockRequestBodyUriSpec.retrieve() >> mockResponseSpec + } + def 'DMI POST operation with JSON.'() { given: 'the web client returns a valid response entity for the expected parameters' mockWebClient.post() >> mockRequestBodyUriSpec - mockWebclientResponse() mockRequestBodyUriSpec.body(_) >> mockRequestBodyUriSpec - mockResponseSpec.toEntity(Object.class) >> monoSpec + def monoSpec = Mono.just(mockResponseEntity) + mockResponseSpec.bodyToMono(Object.class) >> monoSpec monoSpec.block() >> mockResponseEntity when: 'POST operation is invoked' - def result = objectUnderTest.postOperationWithJsonData('/my/url', 'some json', READ, null) + def response = objectUnderTest.postOperationWithJsonData('/my/url', 'some json', READ, null) then: 'the output of the method is equal to the output from the test template' - result == mockResponseEntity + assert response.statusCode.value() == 200 + assert response.hasBody() } - def 'Failing DMI POST operation.'() { - given: 'the rest template returns a valid response entity' - def serverResponse = 'server response'.getBytes() - def httpServerErrorException = new HttpServerErrorException(HttpStatus.FORBIDDEN, 'status text', serverResponse, null) - mockWebClient.post() >> { throw httpServerErrorException } + def 'Failing DMI POST operation for server error'() { + given: 'the web client throws an exception' + mockWebClient.post() >> { throw new HttpServerErrorException(SERVICE_UNAVAILABLE, null, null, null) } when: 'POST operation is invoked' - def result = objectUnderTest.postOperationWithJsonData('/some', 'some json', operation, null) - then: 'a Http Client Exception is thrown' - def thrown = thrown(HttpClientRequestException) + objectUnderTest.postOperationWithJsonData('/some', 'some json', READ, null) + 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.code == '102' + assert thrown.httpStatusCode == 503 + } + + def 'Failing DMI POST operation due to invalid dmi resource url.'() { + when: 'POST operation is invoked with invalid dmi resource url' + objectUnderTest.postOperationWithJsonData('/invalid dmi url', null, null, null) + then: 'invalid dmi resource url exception is thrown' + def thrown = thrown(InvalidDmiResourceUrlException) and: 'the exception has the relevant details from the error response' - assert thrown.httpStatus == 403 - assert thrown.message == "Unable to ${operation} resource data." - assert thrown.details == 'server response' - where: 'the following operation is executed' + assert thrown.httpStatus == 400 + assert thrown.message == 'Invalid dmi resource url: /invalid dmi url' + where: 'the following operations are executed' operation << [CREATE, READ, PATCH] } + def 'Dmi service sends client error response when #scenario'() { + given: 'the web client unable to return response entity but error' + mockWebClient.post() >> mockRequestBodyUriSpec + mockRequestBodyUriSpec.body(_) >> mockRequestBodyUriSpec + def monoSpec = Mono.error(new WebClientResponseException('message', httpStatusCode, null, null, null, null)) + mockResponseSpec.bodyToMono(Object.class) >> monoSpec + when: 'POST operation is invoked' + objectUnderTest.postOperationWithJsonData('/my/url', 'some json', READ, null) + 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.code == expectedNcmpResponseStatusCode + assert thrown.httpStatusCode == httpStatusCode + where: 'the following errors occur' + scenario | httpStatusCode | expectedNcmpResponseStatusCode + 'dmi request timeout' | 408 | DMI_SERVICE_NOT_RESPONDING.code + 'other error code' | 500 | UNABLE_TO_READ_RESOURCE_DATA.code + } + def 'Dmi trust level is determined by spring boot health status'() { given: 'a health check response' def dmiPluginHealthCheckResponseJsonData = TestUtils.getResourceFileContent('dmiPluginHealthCheckResponse.json') - def jsonNode = objectMapper.readValue(dmiPluginHealthCheckResponseJsonData, JsonNode.class) + def jsonNode = jsonObjectMapper.convertJsonString(dmiPluginHealthCheckResponseJsonData, JsonNode.class) ((ObjectNode) jsonNode).put('status', 'my status') def monoResponse = Mono.just(jsonNode) mockWebClient.get() >> mockRequestBodyUriSpec - mockWebclientResponse() mockResponseSpec.bodyToMono(_) >> monoResponse monoResponse.block() >> jsonNode when: 'get trust level of the dmi plugin' @@ -143,10 +179,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 mockWebclientResponse() { - mockRequestBodyUriSpec.uri(_) >> mockRequestBodyUriSpec - mockRequestBodyUriSpec.headers(_) >> mockRequestBodyUriSpec - mockRequestBodyUriSpec.retrieve() >> mockResponseSpec - } } |