2 * ============LICENSE_START====================================
3 * DCAEGEN2-SERVICES-SDK
4 * =========================================================
5 * Copyright (C) 2019-2020 Nokia. All rights reserved.
6 * =========================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=====================================
21 package org.onap.dcaegen2.services.sdk.rest.services.adapters.http;
23 import io.netty.handler.codec.http.HttpResponseStatus;
24 import io.netty.handler.timeout.ReadTimeoutException;
25 import org.junit.jupiter.api.AfterAll;
26 import org.junit.jupiter.api.BeforeAll;
27 import org.junit.jupiter.api.Test;
28 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.exceptions.HttpException;
29 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.test.DummyHttpServer;
30 import reactor.core.publisher.Mono;
31 import reactor.test.StepVerifier;
33 import java.net.MalformedURLException;
35 import java.time.Duration;
37 import static org.assertj.core.api.Assertions.assertThat;
38 import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.test.DummyHttpServer.sendString;
40 class RxHttpClientIT {
42 private static final Duration TIMEOUT = Duration.ofHours(5);
43 private final RxHttpClient cut = RxHttpClientFactory.create();
44 private static DummyHttpServer httpServer;
47 static void setUpClass() {
48 httpServer = DummyHttpServer.start(routes -> routes
49 .get("/sample-get", (req, resp) -> sendString(resp, Mono.just("OK")))
50 .get("/delayed-get", (req, resp) -> sendString(resp, Mono.just("OK").delayElement(Duration.ofMinutes(1))))
51 .get("/sample-get-500", (req, resp) -> resp.status(HttpResponseStatus.INTERNAL_SERVER_ERROR).send())
52 .post("/headers-post", (req, resp) -> resp
53 .sendString(Mono.just(req.requestHeaders().toString())))
54 .post("/echo-post", (req, resp) -> resp.send(req.receive().retain()))
59 static void tearDownClass() {
63 private ImmutableHttpRequest.Builder requestFor(String path) throws MalformedURLException {
64 return ImmutableHttpRequest.builder()
65 .url(new URL("http", httpServer.host(), httpServer.port(), path).toString());
69 void simpleGet() throws Exception {
71 final HttpRequest httpRequest = requestFor("/sample-get")
72 .method(HttpMethod.GET)
76 final Mono<String> bodyAsString = cut.call(httpRequest)
77 .doOnNext(HttpResponse::throwIfUnsuccessful)
78 .map(HttpResponse::bodyAsString);
81 StepVerifier.create(bodyAsString)
88 void getWithError() throws Exception {
90 final HttpRequest httpRequest = requestFor("/sample-get-500")
91 .method(HttpMethod.GET)
95 final Mono<String> bodyAsString = cut.call(httpRequest)
96 .doOnNext(HttpResponse::throwIfUnsuccessful)
97 .map(HttpResponse::bodyAsString);
100 StepVerifier.create(bodyAsString)
101 .expectError(HttpException.class)
106 void simplePost() throws Exception {
108 final String requestBody = "hello world";
109 final HttpRequest httpRequest = requestFor("/echo-post")
110 .method(HttpMethod.POST)
111 .body(RequestBody.fromString(requestBody))
115 final Mono<String> bodyAsString = cut.call(httpRequest)
116 .doOnNext(HttpResponse::throwIfUnsuccessful)
117 .map(HttpResponse::bodyAsString);
120 StepVerifier.create(bodyAsString)
121 .expectNext(requestBody)
127 void testChunkedEncoding() throws Exception {
129 final String requestBody = "hello world";
130 final HttpRequest httpRequest = requestFor("/headers-post")
131 .method(HttpMethod.POST)
132 .body(RequestBody.chunkedFromString(Mono.just(requestBody)))
136 final Mono<String> bodyAsString = cut.call(httpRequest)
137 .doOnNext(HttpResponse::throwIfUnsuccessful)
138 .map(HttpResponse::bodyAsString);
141 StepVerifier.create(bodyAsString.map(String::toLowerCase))
142 .consumeNextWith(responseBody -> {
143 assertThat(responseBody).contains("transfer-encoding: chunked");
144 assertThat(responseBody).doesNotContain("content-length");
151 void testUnchunkedEncoding() throws Exception {
153 final String requestBody = "hello world";
154 final HttpRequest httpRequest = requestFor("/headers-post")
155 .method(HttpMethod.POST)
156 .body(RequestBody.fromString(requestBody))
160 final Mono<String> bodyAsString = cut.call(httpRequest)
161 .doOnNext(HttpResponse::throwIfUnsuccessful)
162 .map(HttpResponse::bodyAsString);
165 StepVerifier.create(bodyAsString.map(String::toLowerCase))
166 .consumeNextWith(responseBody -> {
167 assertThat(responseBody).doesNotContain("transfer-encoding");
168 assertThat(responseBody).contains("content-length");
175 void getWithTimeoutError() throws Exception {
177 final HttpRequest httpRequest = requestFor("/delayed-get")
178 .method(HttpMethod.GET)
179 .timeout(Duration.ofSeconds(1))
183 final Mono<HttpResponse> response = cut.call(httpRequest);
186 StepVerifier.create(response)
187 .expectError(ReadTimeoutException.class)