Upgrade tests to OkHttp 5.x

See https://square.github.io/okhttp/changelogs/changelog/#version-500.

Closes gh-35183
This commit is contained in:
Sébastien Deleuze
2025-07-15 16:20:01 +02:00
parent b76e748ecf
commit 19086835a7
20 changed files with 838 additions and 818 deletions
@@ -16,10 +16,10 @@
package org.springframework.http.client;
import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import mockwebserver3.Dispatcher;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import mockwebserver3.RecordedRequest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -49,8 +49,8 @@ public abstract class AbstractMockWebServerTests {
}
@AfterEach
void tearDown() throws Exception {
this.server.shutdown();
void tearDown() {
this.server.close();
}
@@ -59,56 +59,57 @@ public abstract class AbstractMockWebServerTests {
@Override
public MockResponse dispatch(RecordedRequest request) {
try {
if (request.getPath().equals("/echo")) {
assertThat(request.getHeader("Host")).contains("localhost:" + port);
MockResponse response = new MockResponse()
.setHeaders(request.getHeaders())
.setHeader("Content-Length", request.getBody().size())
.setResponseCode(200)
.setBody(request.getBody());
request.getBody().flush();
return response;
if (request.getTarget().equals("/echo")) {
assertThat(request.getHeaders().get("Host")).contains("localhost:" + port);
MockResponse.Builder builder = new MockResponse.Builder().headers(request.getHeaders());
if (request.getBody() != null) {
builder = builder.body(request.getBody().utf8());
}
else {
builder.setHeader("Content-Length", 0);
}
return builder.code(200).build();
}
else if(request.getPath().equals("/status/ok")) {
return new MockResponse();
else if(request.getTarget().equals("/status/ok")) {
return new MockResponse.Builder().build();
}
else if(request.getPath().equals("/status/notfound")) {
return new MockResponse().setResponseCode(404);
else if(request.getTarget().equals("/status/notfound")) {
return new MockResponse.Builder().code(404).build();
}
else if (request.getPath().equals("/status/299")) {
assertThat(request.getHeader("Expect")).contains("299");
return new MockResponse().setResponseCode(299);
else if (request.getTarget().equals("/status/299")) {
assertThat(request.getHeaders().get("Expect")).contains("299");
return new MockResponse.Builder().code(299).build();
}
else if(request.getPath().startsWith("/params")) {
assertThat(request.getPath()).contains("param1=value");
assertThat(request.getPath()).contains("param2=value1&param2=value2");
return new MockResponse();
else if(request.getTarget().startsWith("/params")) {
assertThat(request.getTarget()).contains("param1=value");
assertThat(request.getTarget()).contains("param2=value1&param2=value2");
return new MockResponse.Builder().build();
}
else if(request.getPath().equals("/methods/post")) {
else if(request.getTarget().equals("/methods/post")) {
assertThat(request.getMethod()).isEqualTo("POST");
String transferEncoding = request.getHeader("Transfer-Encoding");
String transferEncoding = request.getHeaders().get("Transfer-Encoding");
if(StringUtils.hasLength(transferEncoding)) {
assertThat(transferEncoding).isEqualTo("chunked");
}
else {
long contentLength = Long.parseLong(request.getHeader("Content-Length"));
long contentLength = Long.parseLong(request.getHeaders().get("Content-Length"));
assertThat(request.getBody().size()).isEqualTo(contentLength);
}
return new MockResponse().setResponseCode(200);
return new MockResponse.Builder().code(200).build();
}
else if(request.getPath().startsWith("/methods/")) {
String expectedMethod = request.getPath().replace("/methods/","").toUpperCase();
else if(request.getTarget().startsWith("/methods/")) {
String expectedMethod = request.getTarget().replace("/methods/","").toUpperCase();
assertThat(request.getMethod()).isEqualTo(expectedMethod);
return new MockResponse();
return new MockResponse.Builder().build();
}
else if(request.getPath().startsWith("/header/")) {
String headerName = request.getPath().replace("/header/","");
return new MockResponse().setBody(headerName + ":" + request.getHeader(headerName)).setResponseCode(200);
else if(request.getTarget().startsWith("/header/")) {
String headerName = request.getTarget().replace("/header/","");
return new MockResponse.Builder().body(headerName + ":" + request.getHeaders().get(headerName)).code(200).build();
}
return new MockResponse().setResponseCode(404);
return new MockResponse.Builder().code(404).build();
}
catch (Throwable ex) {
return new MockResponse().setResponseCode(500).setBody(ex.toString());
return new MockResponse.Builder().code(500).body(ex.toString()).build();
}
}
}
@@ -34,10 +34,11 @@ import java.util.Random;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
import java.util.function.Function;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import mockwebserver3.RecordedRequest;
import okio.Buffer;
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
import org.junit.jupiter.api.AfterEach;
@@ -84,8 +85,8 @@ class ClientHttpConnectorTests {
}
@AfterEach
void stopServer() throws IOException {
server.shutdown();
void stopServer() {
server.close();
}
// Do not auto-close arguments since HttpComponentsClientHttpConnector implements
@@ -96,11 +97,10 @@ class ClientHttpConnectorTests {
URI uri = this.server.url("/").uri();
String responseBody = "bar\r\n";
prepareResponse(response -> {
response.setResponseCode(200);
response.addHeader("Baz", "Qux");
response.setBody(responseBody);
});
prepareResponse(builder -> builder
.code(200)
.addHeader("Baz", "Qux")
.body(responseBody));
String requestBody = "foo\r\n";
boolean requestHasBody = METHODS_WITH_BODY.contains(method);
@@ -144,9 +144,9 @@ class ClientHttpConnectorTests {
expectRequest(request -> {
assertThat(request.getMethod()).isEqualTo(method.name());
assertThat(request.getHeader("Foo")).isEqualTo("Bar");
assertThat(request.getHeaders().get("Foo")).isEqualTo("Bar");
if (requestHasBody) {
assertThat(request.getBody().readUtf8()).isEqualTo(requestBody);
assertThat(request.getBody().utf8()).isEqualTo(requestBody);
}
});
}
@@ -158,7 +158,7 @@ class ClientHttpConnectorTests {
stringBuffer("foo"),
Mono.error(error)
);
prepareResponse(response -> response.setResponseCode(200));
prepareResponse(builder -> builder.code(200));
Mono<ClientHttpResponse> futureResponse =
connector.connect(HttpMethod.POST, this.server.url("/").uri(), request -> request.writeWith(body));
StepVerifier.create(futureResponse)
@@ -169,7 +169,7 @@ class ClientHttpConnectorTests {
@ParameterizedConnectorTest
void cancelResponseBody(ClientHttpConnector connector) {
Buffer responseBody = randomBody(100);
prepareResponse(response -> response.setBody(responseBody));
prepareResponse(builder -> builder.body(responseBody));
ClientHttpResponse response = connector.connect(HttpMethod.POST, this.server.url("/").uri(),
ReactiveHttpOutputMessage::setComplete).block();
@@ -187,10 +187,9 @@ class ClientHttpConnectorTests {
ZonedDateTime tomorrow = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(1);
String formattedDate = tomorrow.format(DateTimeFormatter.RFC_1123_DATE_TIME);
prepareResponse(response -> {
response.setResponseCode(200);
response.addHeader("Set-Cookie", "id=test; Expires= " + formattedDate + ";");
});
prepareResponse(builder -> builder
.code(200)
.addHeader("Set-Cookie", "id=test; Expires= " + formattedDate + ";"));
Mono<ClientHttpResponse> futureResponse =
connector.connect(HttpMethod.GET, this.server.url("/").uri(), ReactiveHttpOutputMessage::setComplete);
StepVerifier.create(futureResponse)
@@ -206,10 +205,9 @@ class ClientHttpConnectorTests {
void partitionedCookieSupport(ClientHttpConnector connector) {
Assumptions.assumeFalse(connector instanceof JettyClientHttpConnector, "Jetty client does not support partitioned cookies");
Assumptions.assumeFalse(connector instanceof JdkClientHttpConnector, "JDK client does not support partitioned cookies");
prepareResponse(response -> {
response.setResponseCode(200);
response.addHeader("Set-Cookie", "id=test; Partitioned;");
});
prepareResponse(builder -> builder
.code(200)
.addHeader("Set-Cookie", "id=test; Partitioned;"));
Mono<ClientHttpResponse> futureResponse =
connector.connect(HttpMethod.GET, this.server.url("/").uri(), ReactiveHttpOutputMessage::setComplete);
StepVerifier.create(futureResponse)
@@ -227,10 +225,9 @@ class ClientHttpConnectorTests {
HttpAsyncClientBuilder.create().disableCookieManagement().build()
);
prepareResponse(response -> {
response.setResponseCode(200);
response.addHeader("Set-Cookie", "id=test;");
});
prepareResponse(builder -> builder
.code(200)
.addHeader("Set-Cookie", "id=test;"));
Mono<ClientHttpResponse> futureResponse =
connector.connect(HttpMethod.GET, this.server.url("/").uri(), ReactiveHttpOutputMessage::setComplete);
StepVerifier.create(futureResponse)
@@ -254,10 +251,9 @@ class ClientHttpConnectorTests {
return responseBody;
}
private void prepareResponse(Consumer<MockResponse> consumer) {
MockResponse response = new MockResponse();
consumer.accept(response);
this.server.enqueue(response);
private void prepareResponse(Function<MockResponse.Builder, MockResponse.Builder> f) {
MockResponse.Builder builder = new MockResponse.Builder();
this.server.enqueue(f.apply(builder).build());
}
private void expectRequest(Consumer<RecordedRequest> consumer) {
@@ -21,11 +21,12 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import mockwebserver3.Dispatcher;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import mockwebserver3.RecordedRequest;
import okio.Buffer;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -68,96 +69,102 @@ abstract class AbstractMockWebServerTests {
@AfterEach
void tearDown() throws Exception {
this.server.shutdown();
this.server.close();
}
private MockResponse getRequest(RecordedRequest request, byte[] body, String contentType) {
private MockResponse getRequest(RecordedRequest request, byte[] body, @Nullable String contentType) {
if (request.getMethod().equals("OPTIONS")) {
return new MockResponse().setResponseCode(200).setHeader("Allow", "GET, OPTIONS, HEAD, TRACE");
return new MockResponse.Builder().code(200).setHeader("Allow", "GET, OPTIONS, HEAD, TRACE").build();
}
Buffer buf = new Buffer();
buf.write(body);
MockResponse response = new MockResponse()
MockResponse.Builder builder = new MockResponse.Builder()
.setHeader(CONTENT_LENGTH, body.length)
.setBody(buf)
.setResponseCode(200);
.body(buf)
.code(200);
if (contentType != null) {
response = response.setHeader(CONTENT_TYPE, contentType);
return builder.setHeader(CONTENT_TYPE, contentType).build();
}
else {
return builder.build();
}
return response;
}
private MockResponse postRequest(RecordedRequest request, String expectedRequestContent,
String location, String contentType, byte[] responseBody) {
assertThat(request.getHeaders().values(CONTENT_LENGTH)).hasSize(1);
assertThat(Integer.parseInt(request.getHeader(CONTENT_LENGTH))).as("Invalid request content-length").isGreaterThan(0);
String requestContentType = request.getHeader(CONTENT_TYPE);
assertThat(Integer.parseInt(request.getHeaders().get(CONTENT_LENGTH))).as("Invalid request content-length").isGreaterThan(0);
String requestContentType = request.getHeaders().get(CONTENT_TYPE);
assertThat(requestContentType).as("No content-type").isNotNull();
Charset charset = StandardCharsets.ISO_8859_1;
if (requestContentType.contains("charset=")) {
String charsetName = requestContentType.split("charset=")[1];
charset = Charset.forName(charsetName);
}
assertThat(request.getBody().readString(charset)).as("Invalid request body").isEqualTo(expectedRequestContent);
assertThat(request.getBody().string(charset)).as("Invalid request body").isEqualTo(expectedRequestContent);
Buffer buf = new Buffer();
buf.write(responseBody);
return new MockResponse()
return new MockResponse.Builder()
.setHeader(LOCATION, baseUrl + location)
.setHeader(CONTENT_TYPE, contentType)
.setHeader(CONTENT_LENGTH, responseBody.length)
.setBody(buf)
.setResponseCode(201);
.body(buf)
.code(201)
.build();
}
private MockResponse jsonPostRequest(RecordedRequest request, String location, String contentType) {
if (request.getBodySize() > 0) {
String contentLength = request.getHeader(CONTENT_LENGTH);
String contentLength = request.getHeaders().get(CONTENT_LENGTH);
if (contentLength != null) {
assertThat(Integer.parseInt(contentLength)).as("Invalid request content-length").isGreaterThan(0);
}
assertThat(request.getHeader(CONTENT_TYPE)).as("No content-type").isNotNull();
assertThat(request.getHeaders().get(CONTENT_TYPE)).as("No content-type").isNotNull();
}
return new MockResponse()
return new MockResponse.Builder()
.setHeader(LOCATION, baseUrl + location)
.setHeader(CONTENT_TYPE, contentType)
.setHeader(CONTENT_LENGTH, request.getBody().size())
.setBody(request.getBody())
.setResponseCode(201);
.body(request.getBody().utf8())
.code(201)
.build();
}
private MockResponse multipartFormDataRequest(RecordedRequest request) {
MediaType mediaType = MediaType.parseMediaType(request.getHeader(CONTENT_TYPE));
MediaType mediaType = MediaType.parseMediaType(request.getHeaders().get(CONTENT_TYPE));
assertThat(mediaType.isCompatibleWith(MULTIPART_FORM_DATA)).as(MULTIPART_FORM_DATA.toString()).isTrue();
assertMultipart(request, mediaType);
return new MockResponse().setResponseCode(200);
return new MockResponse.Builder().code(200).build();
}
private MockResponse multipartMixedRequest(RecordedRequest request) {
MediaType mediaType = MediaType.parseMediaType(request.getHeader(CONTENT_TYPE));
MediaType mediaType = MediaType.parseMediaType(request.getHeaders().get(CONTENT_TYPE));
assertThat(mediaType.isCompatibleWith(MULTIPART_MIXED)).as(MULTIPART_MIXED.toString()).isTrue();
assertMultipart(request, mediaType);
return new MockResponse().setResponseCode(200);
return new MockResponse.Builder().code(200).build();
}
private MockResponse multipartRelatedRequest(RecordedRequest request) {
MediaType mediaType = MediaType.parseMediaType(request.getHeader(CONTENT_TYPE));
MediaType mediaType = MediaType.parseMediaType(request.getHeaders().get(CONTENT_TYPE));
assertThat(mediaType.isCompatibleWith(MULTIPART_RELATED)).as(MULTIPART_RELATED.toString()).isTrue();
assertMultipart(request, mediaType);
return new MockResponse().setResponseCode(200);
return new MockResponse.Builder().code(200).build();
}
private void assertMultipart(RecordedRequest request, MediaType mediaType) {
assertThat(mediaType.isCompatibleWith(new MediaType("multipart", "*"))).as("multipart/*").isTrue();
String boundary = mediaType.getParameter("boundary");
assertThat(boundary).as("boundary").isNotBlank();
Buffer body = request.getBody();
try {
assertPart(body, "form-data", boundary, "name 1", "text/plain", "value 1");
assertPart(body, "form-data", boundary, "name 2", "text/plain", "value 2+1");
assertPart(body, "form-data", boundary, "name 2", "text/plain", "value 2+2");
assertFilePart(body, "form-data", boundary, "logo", "logo.jpg", "image/jpeg");
try (Buffer buffer = new Buffer()) {
assertThat(request.getBody()).isNotNull();
buffer.write(request.getBody());
assertPart(buffer, "form-data", boundary, "name 1", "text/plain", "value 1");
assertPart(buffer, "form-data", boundary, "name 2", "text/plain", "value 2+1");
assertPart(buffer, "form-data", boundary, "name 2", "text/plain", "value 2+2");
assertFilePart(buffer, "form-data", boundary, "logo", "logo.jpg", "image/jpeg");
}
catch (EOFException ex) {
throw new AssertionError(ex);
@@ -192,43 +199,45 @@ abstract class AbstractMockWebServerTests {
}
private MockResponse formRequest(RecordedRequest request) {
assertThat(request.getHeader(CONTENT_TYPE)).isEqualTo("application/x-www-form-urlencoded");
assertThat(request.getBody().readUtf8()).contains("name+1=value+1", "name+2=value+2%2B1", "name+2=value+2%2B2");
return new MockResponse().setResponseCode(200);
assertThat(request.getHeaders().get(CONTENT_TYPE)).isEqualTo("application/x-www-form-urlencoded");
assertThat(request.getBody().utf8()).contains("name+1=value+1", "name+2=value+2%2B1", "name+2=value+2%2B2");
return new MockResponse.Builder().code(200).build();
}
private MockResponse patchRequest(RecordedRequest request, String expectedRequestContent,
String contentType, byte[] responseBody) {
assertThat(request.getMethod()).isEqualTo("PATCH");
assertThat(Integer.parseInt(request.getHeader(CONTENT_LENGTH))).as("Invalid request content-length").isGreaterThan(0);
String requestContentType = request.getHeader(CONTENT_TYPE);
assertThat(Integer.parseInt(request.getHeaders().get(CONTENT_LENGTH))).as("Invalid request content-length").isGreaterThan(0);
String requestContentType = request.getHeaders().get(CONTENT_TYPE);
assertThat(requestContentType).as("No content-type").isNotNull();
Charset charset = StandardCharsets.ISO_8859_1;
if (requestContentType.contains("charset=")) {
String charsetName = requestContentType.split("charset=")[1];
charset = Charset.forName(charsetName);
}
assertThat(request.getBody().readString(charset)).as("Invalid request body").isEqualTo(expectedRequestContent);
assertThat(request.getBody().string(charset)).as("Invalid request body").isEqualTo(expectedRequestContent);
Buffer buf = new Buffer();
buf.write(responseBody);
return new MockResponse().setResponseCode(201)
return new MockResponse.Builder()
.code(201)
.setHeader(CONTENT_LENGTH, responseBody.length)
.setHeader(CONTENT_TYPE, contentType)
.setBody(buf);
.body(buf)
.build();
}
private MockResponse putRequest(RecordedRequest request, String expectedRequestContent) {
assertThat(Integer.parseInt(request.getHeader(CONTENT_LENGTH))).as("Invalid request content-length").isGreaterThan(0);
String requestContentType = request.getHeader(CONTENT_TYPE);
assertThat(Integer.parseInt(request.getHeaders().get(CONTENT_LENGTH))).as("Invalid request content-length").isGreaterThan(0);
String requestContentType = request.getHeaders().get(CONTENT_TYPE);
assertThat(requestContentType).as("No content-type").isNotNull();
Charset charset = StandardCharsets.ISO_8859_1;
if (requestContentType.contains("charset=")) {
String charsetName = requestContentType.split("charset=")[1];
charset = Charset.forName(charsetName);
}
assertThat(request.getBody().readString(charset)).as("Invalid request body").isEqualTo(expectedRequestContent);
return new MockResponse().setResponseCode(202);
assertThat(request.getBody().string(charset)).as("Invalid request body").isEqualTo(expectedRequestContent);
return new MockResponse.Builder().code(202).build();
}
@@ -239,64 +248,64 @@ abstract class AbstractMockWebServerTests {
try {
byte[] helloWorldBytes = helloWorld.getBytes(StandardCharsets.UTF_8);
if (request.getPath().equals("/get")) {
if (request.getTarget().equals("/get")) {
return getRequest(request, helloWorldBytes, textContentType.toString());
}
else if (request.getPath().equals("/get/nothing")) {
else if (request.getTarget().equals("/get/nothing")) {
return getRequest(request, new byte[0], textContentType.toString());
}
else if (request.getPath().equals("/get/nocontenttype")) {
else if (request.getTarget().equals("/get/nocontenttype")) {
return getRequest(request, helloWorldBytes, null);
}
else if (request.getPath().equals("/post")) {
else if (request.getTarget().equals("/post")) {
return postRequest(request, helloWorld, "/post/1", textContentType.toString(), helloWorldBytes);
}
else if (request.getPath().equals("/jsonpost")) {
else if (request.getTarget().equals("/jsonpost")) {
return jsonPostRequest(request, "/jsonpost/1", "application/json; charset=utf-8");
}
else if (request.getPath().equals("/status/nocontent")) {
return new MockResponse().setResponseCode(204);
else if (request.getTarget().equals("/status/nocontent")) {
return new MockResponse.Builder().code(204).build();
}
else if (request.getPath().equals("/status/notmodified")) {
return new MockResponse().setResponseCode(304);
else if (request.getTarget().equals("/status/notmodified")) {
return new MockResponse.Builder().code(304).build();
}
else if (request.getPath().equals("/status/notfound")) {
return new MockResponse().setResponseCode(404);
else if (request.getTarget().equals("/status/notfound")) {
return new MockResponse.Builder().code(404).build();
}
else if (request.getPath().equals("/status/badrequest")) {
return new MockResponse().setResponseCode(400);
else if (request.getTarget().equals("/status/badrequest")) {
return new MockResponse.Builder().code(400).build();
}
else if (request.getPath().equals("/status/server")) {
return new MockResponse().setResponseCode(500);
else if (request.getTarget().equals("/status/server")) {
return new MockResponse.Builder().code(500).build();
}
else if (request.getPath().contains("/uri/")) {
return new MockResponse().setBody(request.getPath()).setHeader(CONTENT_TYPE, "text/plain");
else if (request.getTarget().contains("/uri/")) {
return new MockResponse.Builder().body(request.getTarget()).setHeader(CONTENT_TYPE, "text/plain").build();
}
else if (request.getPath().equals("/multipartFormData")) {
else if (request.getTarget().equals("/multipartFormData")) {
return multipartFormDataRequest(request);
}
else if (request.getPath().equals("/multipartMixed")) {
else if (request.getTarget().equals("/multipartMixed")) {
return multipartMixedRequest(request);
}
else if (request.getPath().equals("/multipartRelated")) {
else if (request.getTarget().equals("/multipartRelated")) {
return multipartRelatedRequest(request);
}
else if (request.getPath().equals("/form")) {
else if (request.getTarget().equals("/form")) {
return formRequest(request);
}
else if (request.getPath().equals("/delete")) {
return new MockResponse().setResponseCode(200);
else if (request.getTarget().equals("/delete")) {
return new MockResponse.Builder().code(200).build();
}
else if (request.getPath().equals("/patch")) {
else if (request.getTarget().equals("/patch")) {
return patchRequest(request, helloWorld, textContentType.toString(), helloWorldBytes);
}
else if (request.getPath().equals("/put")) {
else if (request.getTarget().equals("/put")) {
return putRequest(request, helloWorld);
}
return new MockResponse().setResponseCode(404);
return new MockResponse.Builder().code(404).build();
}
catch (Throwable ex) {
return new MockResponse().setResponseCode(500).setBody(ex.toString());
return new MockResponse.Builder().code(500).body(ex.toString()).build();
}
}
}
@@ -27,12 +27,13 @@ import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import com.fasterxml.jackson.annotation.JsonView;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import mockwebserver3.RecordedRequest;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.params.ParameterizedTest;
@@ -99,8 +100,9 @@ class RestClientIntegrationTests {
private RestClient restClient;
private void startServer(ClientHttpRequestFactory requestFactory) {
private void startServer(ClientHttpRequestFactory requestFactory) throws IOException {
this.server = new MockWebServer();
this.server.start();
this.restClient = RestClient
.builder()
.requestFactory(requestFactory)
@@ -111,17 +113,17 @@ class RestClientIntegrationTests {
@AfterEach
void shutdown() throws IOException {
if (server != null) {
this.server.shutdown();
this.server.close();
}
}
@ParameterizedRestClientTest
void retrieve(ClientHttpRequestFactory requestFactory) {
void retrieve(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder -> builder
.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
String result = this.restClient.get()
.uri("/greeting")
@@ -133,18 +135,18 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getHeader("X-Test-Header")).isEqualTo("testvalue");
assertThat(request.getPath()).isEqualTo("/greeting");
assertThat(request.getHeaders().get("X-Test-Header")).isEqualTo("testvalue");
assertThat(request.getTarget()).isEqualTo("/greeting");
});
}
@ParameterizedRestClientTest
void retrieveJson(ClientHttpRequestFactory requestFactory) {
void retrieveJson(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response
prepareResponse(builder -> builder
.setHeader("Content-Type", "application/json")
.setBody("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}"));
.body("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}"));
Pojo result = this.restClient.get()
.uri("/pojo")
@@ -157,18 +159,18 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/pojo");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/pojo");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void retrieveJsonWithParameterizedTypeReference(ClientHttpRequestFactory requestFactory) {
void retrieveJsonWithParameterizedTypeReference(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
String content = "{\"containerValue\":{\"bar\":\"barbar\",\"foo\":\"foofoo\"}}";
prepareResponse(response -> response
.setHeader("Content-Type", "application/json").setBody(content));
prepareResponse(builder -> builder
.setHeader("Content-Type", "application/json").body(content));
ValueContainer<Pojo> result = this.restClient.get()
.uri("/json").accept(MediaType.APPLICATION_JSON)
@@ -182,18 +184,18 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/json");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/json");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void retrieveJsonWithListParameterizedTypeReference(ClientHttpRequestFactory requestFactory) {
void retrieveJsonWithListParameterizedTypeReference(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
String content = "{\"containerValue\":[{\"bar\":\"barbar\",\"foo\":\"foofoo\"}]}";
prepareResponse(response -> response
.setHeader("Content-Type", "application/json").setBody(content));
prepareResponse(builder -> builder
.setHeader("Content-Type", "application/json").body(content));
ValueContainer<List<Pojo>> result = this.restClient.get()
.uri("/json").accept(MediaType.APPLICATION_JSON)
@@ -205,18 +207,18 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/json");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/json");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void retrieveJsonAsResponseEntity(ClientHttpRequestFactory requestFactory) {
void retrieveJsonAsResponseEntity(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
String content = "{\"bar\":\"barbar\",\"foo\":\"foofoo\"}";
prepareResponse(response -> response
.setHeader("Content-Type", "application/json").setBody(content));
prepareResponse(builder -> builder
.setHeader("Content-Type", "application/json").body(content));
ResponseEntity<String> result = this.restClient.get()
.uri("/json").accept(MediaType.APPLICATION_JSON)
@@ -230,17 +232,17 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/json");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/json");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void retrieveJsonAsBodilessEntity(ClientHttpRequestFactory requestFactory) {
void retrieveJsonAsBodilessEntity(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response
.setHeader("Content-Type", "application/json").setBody("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}"));
prepareResponse(builder -> builder
.setHeader("Content-Type", "application/json").body("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}"));
ResponseEntity<Void> result = this.restClient.get()
.uri("/json").accept(MediaType.APPLICATION_JSON)
@@ -254,18 +256,18 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/json");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/json");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void retrieveJsonArray(ClientHttpRequestFactory requestFactory) {
void retrieveJsonArray(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response
prepareResponse(builder -> builder
.setHeader("Content-Type", "application/json")
.setBody("[{\"bar\":\"bar1\",\"foo\":\"foo1\"},{\"bar\":\"bar2\",\"foo\":\"foo2\"}]"));
.body("[{\"bar\":\"bar1\",\"foo\":\"foo1\"},{\"bar\":\"bar2\",\"foo\":\"foo2\"}]"));
List<Pojo> result = this.restClient.get()
.uri("/pojos")
@@ -281,18 +283,18 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/pojos");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/pojos");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void retrieveJsonArrayAsResponseEntityList(ClientHttpRequestFactory requestFactory) {
void retrieveJsonArrayAsResponseEntityList(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
String content = "[{\"bar\":\"bar1\",\"foo\":\"foo1\"}, {\"bar\":\"bar2\",\"foo\":\"foo2\"}]";
prepareResponse(response -> response
.setHeader("Content-Type", "application/json").setBody(content));
prepareResponse(builder -> builder
.setHeader("Content-Type", "application/json").body(content));
ResponseEntity<List<Pojo>> result = this.restClient.get()
.uri("/json").accept(MediaType.APPLICATION_JSON)
@@ -310,18 +312,18 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/json");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/json");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void retrieveJsonAsSerializedText(ClientHttpRequestFactory requestFactory) {
void retrieveJsonAsSerializedText(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
String content = "{\"bar\":\"barbar\",\"foo\":\"foofoo\"}";
prepareResponse(response -> response
.setHeader("Content-Type", "application/json").setBody(content));
prepareResponse(builder -> builder
.setHeader("Content-Type", "application/json").body(content));
String result = this.restClient.get()
.uri("/json").accept(MediaType.APPLICATION_JSON)
@@ -332,20 +334,20 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/json");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/json");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
@SuppressWarnings({ "rawtypes", "unchecked" })
void retrieveJsonNull(ClientHttpRequestFactory requestFactory) {
void retrieveJsonNull(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response
.setResponseCode(200)
prepareResponse(builder -> builder
.code(200)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody("null"));
.body("null"));
Map result = this.restClient.get()
.uri("/null")
@@ -356,11 +358,11 @@ class RestClientIntegrationTests {
}
@ParameterizedRestClientTest
void retrieveJsonEmpty(ClientHttpRequestFactory requestFactory) {
void retrieveJsonEmpty(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response
.setResponseCode(200)
prepareResponse(builder -> builder
.code(200)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE));
Pojo result = this.restClient.get()
@@ -372,11 +374,10 @@ class RestClientIntegrationTests {
}
@ParameterizedRestClientTest
void retrieve404(ClientHttpRequestFactory requestFactory) {
void retrieve404(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(404)
.setHeader("Content-Type", "text/plain"));
prepareResponse(builder -> builder.code(404).setHeader("Content-Type", "text/plain"));
assertThatExceptionOfType(HttpClientErrorException.NotFound.class).isThrownBy(() ->
this.restClient.get().uri("/greeting")
@@ -385,16 +386,16 @@ class RestClientIntegrationTests {
);
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/greeting"));
}
@ParameterizedRestClientTest
void retrieve404WithBody(ClientHttpRequestFactory requestFactory) {
void retrieve404WithBody(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(404)
.setHeader("Content-Type", "text/plain").setBody("Not Found"));
prepareResponse(builder -> builder.code(404)
.setHeader("Content-Type", "text/plain").body("Not Found"));
assertThatExceptionOfType(HttpClientErrorException.NotFound.class).isThrownBy(() ->
this.restClient.get()
@@ -404,16 +405,16 @@ class RestClientIntegrationTests {
);
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/greeting"));
}
@ParameterizedRestClientTest
void retrieve500(ClientHttpRequestFactory requestFactory) {
void retrieve500(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
String errorMessage = "Internal Server error";
prepareResponse(response -> response.setResponseCode(500)
.setHeader("Content-Type", "text/plain").setBody(errorMessage));
prepareResponse(builder -> builder.code(500)
.setHeader("Content-Type", "text/plain").body(errorMessage));
String path = "/greeting";
try {
@@ -431,15 +432,15 @@ class RestClientIntegrationTests {
}
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo(path));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo(path));
}
@ParameterizedRestClientTest
void retrieve500AsEntity(ClientHttpRequestFactory requestFactory) {
void retrieve500AsEntity(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(500)
.setHeader("Content-Type", "text/plain").setBody("Internal Server error"));
prepareResponse(builder -> builder.code(500)
.setHeader("Content-Type", "text/plain").body("Internal Server error"));
assertThatExceptionOfType(HttpServerErrorException.InternalServerError.class).isThrownBy(() ->
this.restClient.get()
@@ -450,17 +451,17 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void retrieve500AsBodilessEntity(ClientHttpRequestFactory requestFactory) {
void retrieve500AsBodilessEntity(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(500)
.setHeader("Content-Type", "text/plain").setBody("Internal Server error"));
prepareResponse(builder -> builder.code(500)
.setHeader("Content-Type", "text/plain").body("Internal Server error"));
assertThatExceptionOfType(HttpServerErrorException.InternalServerError.class).isThrownBy(() ->
this.restClient.get()
@@ -471,20 +472,20 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void retrieve555UnknownStatus(ClientHttpRequestFactory requestFactory) {
void retrieve555UnknownStatus(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
int errorStatus = 555;
assertThat(HttpStatus.resolve(errorStatus)).isNull();
String errorMessage = "Something went wrong";
prepareResponse(response -> response.setResponseCode(errorStatus)
.setHeader("Content-Type", "text/plain").setBody(errorMessage));
prepareResponse(builder -> builder.code(errorStatus)
.setHeader("Content-Type", "text/plain").body(errorMessage));
try {
this.restClient.get()
@@ -502,15 +503,15 @@ class RestClientIntegrationTests {
}
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/unknownPage"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/unknownPage"));
}
@ParameterizedRestClientTest
void postPojoAsJson(ClientHttpRequestFactory requestFactory) {
void postPojoAsJson(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setHeader("Content-Type", "application/json")
.setBody("{\"bar\":\"BARBAR\",\"foo\":\"FOOFOO\"}"));
prepareResponse(builder -> builder.setHeader("Content-Type", "application/json")
.body("{\"bar\":\"BARBAR\",\"foo\":\"FOOFOO\"}"));
Pojo result = this.restClient.post()
.uri("/pojo/capitalize")
@@ -526,19 +527,19 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/pojo/capitalize");
assertThat(request.getBody().readUtf8()).isEqualTo("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/pojo/capitalize");
assertThat(request.getBody().utf8()).isEqualTo("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getHeaders().get(HttpHeaders.CONTENT_TYPE)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void postUserAsJsonWithJsonView(ClientHttpRequestFactory requestFactory) {
void postUserAsJsonWithJsonView(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setHeader("Content-Type", "application/json")
.setBody("{\"username\":\"USERNAME\"}"));
prepareResponse(builder -> builder.setHeader("Content-Type", "application/json")
.body("{\"username\":\"USERNAME\"}"));
User result = this.restClient.post()
.uri("/user/capitalize")
@@ -555,18 +556,18 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/user/capitalize");
assertThat(request.getBody().readUtf8()).isEqualTo("{\"username\":\"username\"}");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/user/capitalize");
assertThat(request.getBody().utf8()).isEqualTo("{\"username\":\"username\"}");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getHeaders().get(HttpHeaders.CONTENT_TYPE)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest // gh-31361
public void postForm(ClientHttpRequestFactory requestFactory) {
public void postForm(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(200));
prepareResponse(builder -> builder.code(200));
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.add("foo", "bar");
@@ -583,10 +584,10 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/form");
String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
assertThat(request.getTarget()).isEqualTo("/form");
String contentType = request.getHeaders().get(HttpHeaders.CONTENT_TYPE);
assertThat(contentType).startsWith(MediaType.MULTIPART_FORM_DATA_VALUE);
String[] lines = request.getBody().readUtf8().split("\r\n");
String[] lines = request.getBody().utf8().split("\r\n");
assertThat(lines).hasSize(13);
assertThat(lines[0]).startsWith("--"); // boundary
assertThat(lines[1]).isEqualTo("Content-Disposition: form-data; name=\"foo\"");
@@ -606,9 +607,9 @@ class RestClientIntegrationTests {
}
@ParameterizedRestClientTest // gh-35102
void postStreamingBody(ClientHttpRequestFactory requestFactory) {
void postStreamingBody(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(200));
prepareResponse(builder -> builder.code(200));
StreamingHttpOutputMessage.Body testBody = out -> {
assertThat(out).as("Not a streaming response").isNotInstanceOf(FastByteArrayOutputStream.class);
@@ -625,17 +626,17 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/streaming/body");
assertThat(request.getBody().readUtf8()).isEqualTo("test-data");
assertThat(request.getTarget()).isEqualTo("/streaming/body");
assertThat(request.getBody().utf8()).isEqualTo("test-data");
});
}
@ParameterizedRestClientTest
void statusHandler(ClientHttpRequestFactory requestFactory) {
void statusHandler(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(500)
.setHeader("Content-Type", "text/plain").setBody("Internal Server error"));
prepareResponse(builder -> builder.code(500)
.setHeader("Content-Type", "text/plain").body("Internal Server error"));
assertThatExceptionOfType(MyException.class).isThrownBy(() ->
this.restClient.get()
@@ -648,15 +649,15 @@ class RestClientIntegrationTests {
);
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/greeting"));
}
@ParameterizedRestClientTest
void statusHandlerIOException(ClientHttpRequestFactory requestFactory) {
void statusHandlerIOException(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(500)
.setHeader("Content-Type", "text/plain").setBody("Internal Server error"));
prepareResponse(builder -> builder.code(500)
.setHeader("Content-Type", "text/plain").body("Internal Server error"));
assertThatExceptionOfType(RestClientException.class).isThrownBy(() ->
this.restClient.get()
@@ -669,15 +670,15 @@ class RestClientIntegrationTests {
).withCauseInstanceOf(IOException.class);
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/greeting"));
}
@ParameterizedRestClientTest
void statusHandlerParameterizedTypeReference(ClientHttpRequestFactory requestFactory) {
void statusHandlerParameterizedTypeReference(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(500)
.setHeader("Content-Type", "text/plain").setBody("Internal Server error"));
prepareResponse(builder -> builder.code(500)
.setHeader("Content-Type", "text/plain").body("Internal Server error"));
assertThatExceptionOfType(MyException.class).isThrownBy(() ->
this.restClient.get()
@@ -691,15 +692,15 @@ class RestClientIntegrationTests {
);
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/greeting"));
}
@ParameterizedRestClientTest
void statusHandlerSuppressedErrorSignal(ClientHttpRequestFactory requestFactory) {
void statusHandlerSuppressedErrorSignal(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setResponseCode(500)
.setHeader("Content-Type", "text/plain").setBody("Internal Server error"));
prepareResponse(builder -> builder.code(500)
.setHeader("Content-Type", "text/plain").body("Internal Server error"));
String result = this.restClient.get()
.uri("/greeting")
@@ -710,16 +711,16 @@ class RestClientIntegrationTests {
assertThat(result).isEqualTo("Internal Server error");
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/greeting"));
}
@ParameterizedRestClientTest
void statusHandlerSuppressedErrorSignalWithEntity(ClientHttpRequestFactory requestFactory) {
void statusHandlerSuppressedErrorSignalWithEntity(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
String content = "Internal Server error";
prepareResponse(response ->
response.setResponseCode(500).setHeader("Content-Type", "text/plain").setBody(content));
prepareResponse(builder -> builder.code(500)
.setHeader("Content-Type", "text/plain").body(content));
ResponseEntity<String> result = this.restClient.get()
.uri("/").accept(MediaType.APPLICATION_JSON)
@@ -733,16 +734,16 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void exchangeForPlainText(ClientHttpRequestFactory requestFactory) {
void exchangeForPlainText(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setBody("Hello Spring!"));
prepareResponse(builder -> builder.body("Hello Spring!"));
String result = this.restClient.get()
.uri("/greeting")
@@ -753,18 +754,18 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getHeader("X-Test-Header")).isEqualTo("testvalue");
assertThat(request.getPath()).isEqualTo("/greeting");
assertThat(request.getHeaders().get("X-Test-Header")).isEqualTo("testvalue");
assertThat(request.getTarget()).isEqualTo("/greeting");
});
}
@ParameterizedRestClientTest
void exchangeForJson(ClientHttpRequestFactory requestFactory) {
void exchangeForJson(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response
prepareResponse(builder -> builder
.setHeader("Content-Type", "application/json")
.setBody("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}"));
.body("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}"));
Pojo result = this.restClient.get()
.uri("/pojo")
@@ -776,18 +777,18 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/pojo");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/pojo");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void exchangeForJsonArray(ClientHttpRequestFactory requestFactory) {
void exchangeForJsonArray(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response
prepareResponse(builder -> builder
.setHeader("Content-Type", "application/json")
.setBody("[{\"bar\":\"bar1\",\"foo\":\"foo1\"},{\"bar\":\"bar2\",\"foo\":\"foo2\"}]"));
.body("[{\"bar\":\"bar1\",\"foo\":\"foo1\"},{\"bar\":\"bar2\",\"foo\":\"foo2\"}]"));
List<Pojo> result = this.restClient.get()
.uri("/pojo")
@@ -802,17 +803,17 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getPath()).isEqualTo("/pojo");
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo("application/json");
assertThat(request.getTarget()).isEqualTo("/pojo");
assertThat(request.getHeaders().get(HttpHeaders.ACCEPT)).isEqualTo("application/json");
});
}
@ParameterizedRestClientTest
void exchangeFor404(ClientHttpRequestFactory requestFactory) {
void exchangeFor404(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setResponseCode(404).setHeader("Content-Type", "text/plain").setBody("Not Found"));
prepareResponse(builder ->
builder.code(404).setHeader("Content-Type", "text/plain").body("Not Found"));
String result = this.restClient.get()
.uri("/greeting")
@@ -821,14 +822,14 @@ class RestClientIntegrationTests {
assertThat(result).isEqualTo("Not Found");
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/greeting"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/greeting"));
}
@ParameterizedRestClientTest
void exchangeForRequiredValue(ClientHttpRequestFactory requestFactory) {
void exchangeForRequiredValue(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setBody("Hello Spring!"));
prepareResponse(builder -> builder.body("Hello Spring!"));
String result = this.restClient.get()
.uri("/greeting")
@@ -839,17 +840,17 @@ class RestClientIntegrationTests {
expectRequestCount(1);
expectRequest(request -> {
assertThat(request.getHeader("X-Test-Header")).isEqualTo("testvalue");
assertThat(request.getPath()).isEqualTo("/greeting");
assertThat(request.getHeaders().get("X-Test-Header")).isEqualTo("testvalue");
assertThat(request.getTarget()).isEqualTo("/greeting");
});
}
@ParameterizedRestClientTest
@SuppressWarnings("DataFlowIssue")
void exchangeForNullRequiredValue(ClientHttpRequestFactory requestFactory) {
void exchangeForNullRequiredValue(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response -> response.setBody("Hello Spring!"));
prepareResponse(builder -> builder.body("Hello Spring!"));
assertThatIllegalStateException().isThrownBy(() -> this.restClient.get()
.uri("/greeting")
@@ -858,11 +859,11 @@ class RestClientIntegrationTests {
}
@ParameterizedRestClientTest
void requestInitializer(ClientHttpRequestFactory requestFactory) {
void requestInitializer(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
RestClient initializedClient = this.restClient.mutate()
.requestInitializer(request -> request.getHeaders().add("foo", "bar"))
@@ -876,15 +877,15 @@ class RestClientIntegrationTests {
assertThat(result).isEqualTo("Hello Spring!");
expectRequestCount(1);
expectRequest(request -> assertThat(request.getHeader("foo")).isEqualTo("bar"));
expectRequest(request -> assertThat(request.getHeaders().get("foo")).isEqualTo("bar"));
}
@ParameterizedRestClientTest
void requestInterceptor(ClientHttpRequestFactory requestFactory) {
void requestInterceptor(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
RestClient interceptedClient = this.restClient.mutate()
.requestInterceptor((request, body, execution) -> {
@@ -901,15 +902,15 @@ class RestClientIntegrationTests {
assertThat(result).isEqualTo("Hello Spring!");
expectRequestCount(1);
expectRequest(request -> assertThat(request.getHeader("foo")).isEqualTo("bar"));
expectRequest(request -> assertThat(request.getHeaders().get("foo")).isEqualTo("bar"));
}
@ParameterizedRestClientTest
void requestInterceptorWithResponseBuffering(ClientHttpRequestFactory requestFactory) {
void requestInterceptorWithResponseBuffering(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
RestClient interceptedClient = this.restClient.mutate()
.requestInterceptor((request, body, execution) -> {
@@ -931,11 +932,11 @@ class RestClientIntegrationTests {
}
@ParameterizedRestClientTest
void bufferContent(ClientHttpRequestFactory requestFactory) {
void bufferContent(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
RestClient bufferingClient = this.restClient.mutate()
.bufferContent((uri, httpMethod) -> true)
@@ -956,10 +957,10 @@ class RestClientIntegrationTests {
}
@ParameterizedRestClientTest
void retrieveDefaultCookiesAsCookieHeader(ClientHttpRequestFactory requestFactory) {
void retrieveDefaultCookiesAsCookieHeader(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
RestClient restClientWithCookies = this.restClient.mutate()
.defaultCookie("testCookie", "firstValue", "secondValue")
@@ -972,13 +973,13 @@ class RestClientIntegrationTests {
.body(String.class);
expectRequest(request ->
assertThat(request.getHeader(HttpHeaders.COOKIE))
assertThat(request.getHeaders().get(HttpHeaders.COOKIE))
.isEqualTo("testCookie=firstValue; testCookie=secondValue")
);
}
@ParameterizedRestClientTest
void filterForErrorHandling(ClientHttpRequestFactory requestFactory) {
void filterForErrorHandling(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
ClientHttpRequestInterceptor interceptor = (request, body, execution) -> {
@@ -995,8 +996,8 @@ class RestClientIntegrationTests {
RestClient interceptedClient = this.restClient.mutate().requestInterceptor(interceptor).build();
// header not present
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
assertThatExceptionOfType(MyException.class).isThrownBy(() ->
interceptedClient.get()
@@ -1007,9 +1008,9 @@ class RestClientIntegrationTests {
// header present
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
prepareResponse(builder -> builder.setHeader("Content-Type", "text/plain")
.setHeader("Foo", "Bar")
.setBody("Hello Spring!"));
.body("Hello Spring!"));
String result = interceptedClient.get()
.uri("/greeting")
@@ -1021,11 +1022,11 @@ class RestClientIntegrationTests {
}
@ParameterizedRestClientTest
void defaultHeaders(ClientHttpRequestFactory requestFactory) {
void defaultHeaders(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
RestClient headersClient = this.restClient.mutate()
.defaultHeaders(headers -> headers.add("foo", "bar"))
@@ -1039,15 +1040,15 @@ class RestClientIntegrationTests {
assertThat(result).isEqualTo("Hello Spring!");
expectRequestCount(1);
expectRequest(request -> assertThat(request.getHeader("foo")).isEqualTo("bar"));
expectRequest(request -> assertThat(request.getHeaders().get("foo")).isEqualTo("bar"));
}
@ParameterizedRestClientTest
void defaultRequest(ClientHttpRequestFactory requestFactory) {
void defaultRequest(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
RestClient headersClient = this.restClient.mutate()
.defaultRequest(request -> request.header("foo", "bar"))
@@ -1061,15 +1062,15 @@ class RestClientIntegrationTests {
assertThat(result).isEqualTo("Hello Spring!");
expectRequestCount(1);
expectRequest(request -> assertThat(request.getHeader("foo")).isEqualTo("bar"));
expectRequest(request -> assertThat(request.getHeaders().get("foo")).isEqualTo("bar"));
}
@ParameterizedRestClientTest
void defaultRequestOverride(ClientHttpRequestFactory requestFactory) {
void defaultRequestOverride(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
RestClient headersClient = this.restClient.mutate()
.defaultRequest(request -> request.accept(MediaType.APPLICATION_JSON))
@@ -1084,15 +1085,15 @@ class RestClientIntegrationTests {
assertThat(result).isEqualTo("Hello Spring!");
expectRequestCount(1);
expectRequest(request -> assertThat(request.getHeader("Accept")).isEqualTo(MediaType.TEXT_PLAIN_VALUE));
expectRequest(request -> assertThat(request.getHeaders().get("Accept")).isEqualTo(MediaType.TEXT_PLAIN_VALUE));
}
@ParameterizedRestClientTest
void relativeUri(ClientHttpRequestFactory requestFactory) throws URISyntaxException {
void relativeUri(ClientHttpRequestFactory requestFactory) throws URISyntaxException, IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
URI uri = new URI(null, null, "/foo bar", null);
@@ -1106,15 +1107,15 @@ class RestClientIntegrationTests {
assertThat(result).isEqualTo("Hello Spring!");
expectRequestCount(1);
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/foo%20bar"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/foo%20bar"));
}
@ParameterizedRestClientTest
void cookieAddsCookie(ClientHttpRequestFactory requestFactory) {
void cookieAddsCookie(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
this.restClient.get()
.uri("/greeting")
@@ -1124,15 +1125,15 @@ class RestClientIntegrationTests {
.retrieve()
.body(String.class);
expectRequest(request -> assertThat(request.getHeader("Cookie")).isEqualTo("c1=v1a; c1=v1b; c2=v2a"));
expectRequest(request -> assertThat(request.getHeaders().get("Cookie")).isEqualTo("c1=v1a; c1=v1b; c2=v2a"));
}
@ParameterizedRestClientTest
void cookieOverridesDefaultCookie(ClientHttpRequestFactory requestFactory) {
void cookieOverridesDefaultCookie(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
RestClient restClientWithCookies = this.restClient.mutate()
.defaultCookie("testCookie", "firstValue", "secondValue")
@@ -1144,15 +1145,15 @@ class RestClientIntegrationTests {
.retrieve()
.body(String.class);
expectRequest(request -> assertThat(request.getHeader("Cookie")).isEqualTo("testCookie=test"));
expectRequest(request -> assertThat(request.getHeaders().get("Cookie")).isEqualTo("testCookie=test"));
}
@ParameterizedRestClientTest
void cookiesCanRemoveCookie(ClientHttpRequestFactory requestFactory) {
void cookiesCanRemoveCookie(ClientHttpRequestFactory requestFactory) throws IOException {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring!"));
this.restClient.get()
.uri("/greeting")
@@ -1162,13 +1163,12 @@ class RestClientIntegrationTests {
.retrieve()
.body(String.class);
expectRequest(request -> assertThat(request.getHeader("Cookie")).isEqualTo("test=Hello"));
expectRequest(request -> assertThat(request.getHeaders().get("Cookie")).isEqualTo("test=Hello"));
}
private void prepareResponse(Consumer<MockResponse> consumer) {
MockResponse response = new MockResponse();
consumer.accept(response);
this.server.enqueue(response);
private void prepareResponse(Function<MockResponse.Builder, MockResponse.Builder> f) {
MockResponse.Builder builder = new MockResponse.Builder();
this.server.enqueue(f.apply(builder).build());
}
private void expectRequest(Consumer<RecordedRequest> consumer) {
@@ -19,9 +19,9 @@ package org.springframework.web.client;
import java.io.IOException;
import java.util.function.Consumer;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import mockwebserver3.RecordedRequest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -39,46 +39,50 @@ public class RestClientVersionTests {
private final MockWebServer server = new MockWebServer();
private final RestClient.Builder restClientBuilder = RestClient.builder()
.requestFactory(new JdkClientHttpRequestFactory())
.baseUrl(this.server.url("/").toString());
private RestClient.Builder restClientBuilder;
@BeforeEach
void setUp() {
MockResponse response = new MockResponse();
response.setHeader("Content-Type", "text/plain").setBody("body");
void setUp() throws IOException {
this.server.start();
this.restClientBuilder = RestClient.builder()
.requestFactory(new JdkClientHttpRequestFactory())
.baseUrl(this.server.url("/").toString());
MockResponse response = new MockResponse.Builder()
.setHeader("Content-Type", "text/plain")
.body("body")
.build();
this.server.enqueue(response);
}
@AfterEach
void shutdown() throws IOException {
this.server.shutdown();
void shutdown() {
this.server.close();
}
@Test
void header() {
performRequest(ApiVersionInserter.useHeader("X-API-Version"));
expectRequest(request -> assertThat(request.getHeader("X-API-Version")).isEqualTo("1.2"));
expectRequest(request -> assertThat(request.getHeaders().get("X-API-Version")).isEqualTo("1.2"));
}
@Test
void queryParam() {
performRequest(ApiVersionInserter.useQueryParam("api-version"));
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/path?api-version=1.2"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/path?api-version=1.2"));
}
@Test
void pathSegmentIndexLessThanSize() {
performRequest(ApiVersionInserter.builder().usePathSegment(0).withVersionFormatter(v -> "v" + v).build());
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/v1.2/path"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/v1.2/path"));
}
@Test
void pathSegmentIndexEqualToSize() {
performRequest(ApiVersionInserter.builder().usePathSegment(1).withVersionFormatter(v -> "v" + v).build());
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/path/v1.2"));
expectRequest(request -> assertThat(request.getTarget()).isEqualTo("/path/v1.2"));
}
@Test
@@ -94,7 +98,7 @@ public class RestClientVersionTests {
RestClient restClient = restClientBuilder.defaultApiVersion(1.2).apiVersionInserter(inserter).build();
restClient.get().uri("/path").retrieve().body(String.class);
expectRequest(request -> assertThat(request.getHeader("X-API-Version")).isEqualTo("1.2"));
expectRequest(request -> assertThat(request.getHeaders().get("X-API-Version")).isEqualTo("1.2"));
}
private void performRequest(ApiVersionInserter versionInserter) {
@@ -28,9 +28,9 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import mockwebserver3.RecordedRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -504,18 +504,18 @@ class RestTemplateTests {
@Test // gh-23740
void headerAcceptAllOnPut() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.enqueue(new MockResponse().setResponseCode(500).setBody("internal server error"));
server.enqueue(new MockResponse.Builder().code(500).body("internal server error").build());
server.start();
template.setRequestFactory(new SimpleClientHttpRequestFactory());
template.put(server.url("/internal/server/error").uri(), null);
assertThat(server.takeRequest().getHeader("Accept")).isEqualTo("*/*");
assertThat(server.takeRequest().getHeaders().get("Accept")).isEqualTo("*/*");
}
}
@Test // gh-23740
void keepGivenAcceptHeaderOnPut() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.enqueue(new MockResponse().setResponseCode(500).setBody("internal server error"));
server.enqueue(new MockResponse.Builder().code(500).body("internal server error").build());
server.start();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
@@ -582,11 +582,11 @@ class RestTemplateTests {
@Test // gh-23740
void headerAcceptAllOnDelete() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.enqueue(new MockResponse().setResponseCode(500).setBody("internal server error"));
server.enqueue(new MockResponse.Builder().code(500).body("internal server error").build());
server.start();
template.setRequestFactory(new SimpleClientHttpRequestFactory());
template.delete(server.url("/internal/server/error").uri());
assertThat(server.takeRequest().getHeader("Accept")).isEqualTo("*/*");
assertThat(server.takeRequest().getHeaders().get("Accept")).isEqualTo("*/*");
}
}
@@ -773,7 +773,7 @@ class RestTemplateTests {
@Test
void requestInterceptorWithBuffering() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.enqueue(new MockResponse().setResponseCode(200).setBody("Hello Spring!"));
server.enqueue(new MockResponse.Builder().code(200).body("Hello Spring!").build());
server.start();
template.setRequestFactory(new SimpleClientHttpRequestFactory());
template.setInterceptors(List.of((request, body, execution) -> {
@@ -793,7 +793,7 @@ class RestTemplateTests {
@Test
void buffering() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.enqueue(new MockResponse().setResponseCode(200).setBody("Hello Spring!"));
server.enqueue(new MockResponse.Builder().code(200).body("Hello Spring!").build());
server.start();
template.setRequestFactory(new SimpleClientHttpRequestFactory());
template.setBufferingPredicate((uri, httpMethod) -> true);
@@ -28,15 +28,16 @@ import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import io.micrometer.observation.tck.TestObservationRegistry;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import mockwebserver3.RecordedRequest;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -82,10 +83,14 @@ class RestClientAdapterTests {
private final MockWebServer anotherServer = new MockWebServer();
@BeforeEach
void setUp() throws IOException {
this.anotherServer.start();
}
@AfterEach
void shutdown() throws IOException {
this.anotherServer.shutdown();
void shutdown() {
this.anotherServer.close();
}
@@ -96,7 +101,7 @@ class RestClientAdapterTests {
@interface ParameterizedAdapterTest {
}
public static Stream<Object[]> arguments() {
public static Stream<Object[]> arguments() throws IOException {
return Stream.of(
createArgsForAdapter((url, or) -> {
RestClient restClient = RestClient.builder().baseUrl(url).observationRegistry(or).build();
@@ -112,12 +117,15 @@ class RestClientAdapterTests {
@SuppressWarnings("resource")
private static Object[] createArgsForAdapter(
BiFunction<String, TestObservationRegistry, HttpExchangeAdapter> adapterFactory) {
BiFunction<String, TestObservationRegistry, HttpExchangeAdapter> adapterFactory) throws IOException {
MockWebServer server = new MockWebServer();
server.start();
MockResponse response = new MockResponse();
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!");
MockResponse response = new MockResponse.Builder()
.setHeader("Content-Type", "text/plain")
.body("Hello Spring!")
.build();
server.enqueue(response);
TestObservationRegistry registry = TestObservationRegistry.create();
@@ -137,7 +145,7 @@ class RestClientAdapterTests {
RecordedRequest request = server.takeRequest();
assertThat(response).isEqualTo("Hello Spring!");
assertThat(request.getMethod()).isEqualTo("GET");
assertThat(request.getPath()).isEqualTo("/greeting");
assertThat(request.getTarget()).isEqualTo("/greeting");
assertThat(registry).hasObservationWithNameEqualTo("http.client.requests").that()
.hasLowCardinalityKeyValue("uri", "/greeting");
}
@@ -151,7 +159,7 @@ class RestClientAdapterTests {
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isEqualTo("Hello Spring!");
assertThat(request.getMethod()).isEqualTo("GET");
assertThat(request.getPath()).isEqualTo("/greeting/456");
assertThat(request.getTarget()).isEqualTo("/greeting/456");
assertThat(registry).hasObservationWithNameEqualTo("http.client.requests").that()
.hasLowCardinalityKeyValue("uri", "/greeting/{id}");
}
@@ -165,15 +173,15 @@ class RestClientAdapterTests {
RecordedRequest request = server.takeRequest();
assertThat(response.orElse("empty")).isEqualTo("Hello Spring!");
assertThat(request.getMethod()).isEqualTo("GET");
assertThat(request.getRequestUrl().uri()).isEqualTo(dynamicUri);
assertThat(request.getUrl().uri()).isEqualTo(dynamicUri);
assertThat(registry).hasObservationWithNameEqualTo("http.client.requests").that()
.hasLowCardinalityKeyValue("uri", "none");
}
@Test
void greetingWithApiVersion() throws Exception {
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring 2!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring 2!"));
RestClient restClient = RestClient.builder()
.baseUrl(anotherServer.url("/").toString())
@@ -186,14 +194,14 @@ class RestClientAdapterTests {
String actualResponse = service.getGreetingWithVersion();
RecordedRequest request = anotherServer.takeRequest();
assertThat(request.getHeader("X-API-Version")).isEqualTo("1.2");
assertThat(request.getHeaders().get("X-API-Version")).isEqualTo("1.2");
assertThat(actualResponse).isEqualTo("Hello Spring 2!");
}
@ParameterizedAdapterTest
void getWithUriBuilderFactory(MockWebServer server, Service service) throws InterruptedException {
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring 2!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring 2!"));
String url = this.anotherServer.url("/").toString();
UriBuilderFactory factory = new DefaultUriBuilderFactory(url);
@@ -204,14 +212,14 @@ class RestClientAdapterTests {
assertThat(actualResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(actualResponse.getBody()).isEqualTo("Hello Spring 2!");
assertThat(request.getMethod()).isEqualTo("GET");
assertThat(request.getPath()).isEqualTo("/greeting");
assertThat(request.getTarget()).isEqualTo("/greeting");
assertThat(server.getRequestCount()).isEqualTo(0);
}
@ParameterizedAdapterTest
void getWithFactoryPathVariableAndRequestParam(MockWebServer server, Service service) throws InterruptedException {
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring 2!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring 2!"));
String url = this.anotherServer.url("/").toString();
UriBuilderFactory factory = new DefaultUriBuilderFactory(url);
@@ -222,14 +230,14 @@ class RestClientAdapterTests {
assertThat(actualResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(actualResponse.getBody()).isEqualTo("Hello Spring 2!");
assertThat(request.getMethod()).isEqualTo("GET");
assertThat(request.getPath()).isEqualTo("/greeting/123?param=test");
assertThat(request.getTarget()).isEqualTo("/greeting/123?param=test");
assertThat(server.getRequestCount()).isEqualTo(0);
}
@ParameterizedAdapterTest
void getWithIgnoredUriBuilderFactory(MockWebServer server, Service service) throws InterruptedException {
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring 2!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring 2!"));
URI dynamicUri = server.url("/greeting/123").uri();
UriBuilderFactory factory = new DefaultUriBuilderFactory(this.anotherServer.url("/").toString());
@@ -240,7 +248,7 @@ class RestClientAdapterTests {
assertThat(actualResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(actualResponse.getBody()).isEqualTo("Hello Spring!");
assertThat(request.getMethod()).isEqualTo("GET");
assertThat(request.getPath()).isEqualTo("/greeting/123");
assertThat(request.getTarget()).isEqualTo("/greeting/123");
assertThat(this.anotherServer.getRequestCount()).isEqualTo(0);
}
@@ -250,9 +258,9 @@ class RestClientAdapterTests {
RecordedRequest request = server.takeRequest();
assertThat(request.getMethod()).isEqualTo("POST");
assertThat(request.getPath()).isEqualTo("/greeting");
assertThat(request.getTarget()).isEqualTo("/greeting");
assertThat(request.getHeaders().get("testHeaderName")).isEqualTo("testHeader");
assertThat(request.getBody().readUtf8()).isEqualTo("testBody");
assertThat(request.getBody().utf8()).isEqualTo("testBody");
}
@ParameterizedAdapterTest
@@ -265,7 +273,7 @@ class RestClientAdapterTests {
RecordedRequest request = server.takeRequest();
assertThat(request.getHeaders().get("Content-Type")).isEqualTo("application/x-www-form-urlencoded");
assertThat(request.getBody().readUtf8()).isEqualTo("param1=value+1&param2=value+2");
assertThat(request.getBody().utf8()).isEqualTo("param1=value+1&param2=value+2");
}
@ParameterizedAdapterTest // gh-30342
@@ -277,7 +285,7 @@ class RestClientAdapterTests {
RecordedRequest request = server.takeRequest();
assertThat(request.getHeaders().get("Content-Type")).startsWith("multipart/form-data;boundary=");
assertThat(request.getBody().readUtf8()).containsSubsequence(
assertThat(request.getBody().utf8()).containsSubsequence(
"Content-Disposition: form-data; name=\"file\"; filename=\"originalTestFileName\"",
"Content-Type: application/json", "Content-Length: 4", "test",
"Content-Disposition: form-data; name=\"anotherPart\"", "Content-Type: text/plain;charset=UTF-8",
@@ -293,8 +301,8 @@ class RestClientAdapterTests {
RecordedRequest request = server.takeRequest();
assertThat(request.getMethod()).isEqualTo("POST");
assertThat(request.getPath()).isEqualTo("/persons");
assertThat(request.getBody().readUtf8()).isEqualTo("[{\"name\":\"John\"},{\"name\":\"Richard\"}]");
assertThat(request.getTarget()).isEqualTo("/persons");
assertThat(request.getBody().utf8()).isEqualTo("[{\"name\":\"John\"},{\"name\":\"Richard\"}]");
}
@ParameterizedAdapterTest
@@ -303,7 +311,7 @@ class RestClientAdapterTests {
RecordedRequest request = server.takeRequest();
assertThat(request.getMethod()).isEqualTo("PUT");
assertThat(request.getHeader("Cookie")).isEqualTo("firstCookie=test1; secondCookie=test2");
assertThat(request.getHeaders().get("Cookie")).isEqualTo("firstCookie=test1; secondCookie=test2");
}
@ParameterizedAdapterTest
@@ -312,38 +320,37 @@ class RestClientAdapterTests {
RecordedRequest request = server.takeRequest();
assertThat(request.getMethod()).isEqualTo("PUT");
assertThat(request.getHeader("Cookie")).isEqualTo("testCookie=test1; testCookie=test2");
assertThat(request.getHeaders().get("Cookie")).isEqualTo("testCookie=test1; testCookie=test2");
}
@Test
void getInputStream() throws Exception {
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring 2!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring 2!"));
InputStream inputStream = initService().getInputStream();
RecordedRequest request = this.anotherServer.takeRequest();
assertThat(request.getPath()).isEqualTo("/input-stream");
assertThat(request.getTarget()).isEqualTo("/input-stream");
assertThat(StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8)).isEqualTo("Hello Spring 2!");
}
@Test
void postOutputStream() throws Exception {
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring 2!"));
prepareResponse(builder ->
builder.setHeader("Content-Type", "text/plain").body("Hello Spring 2!"));
String body = "test stream";
initService().postOutputStream(outputStream -> outputStream.write(body.getBytes()));
RecordedRequest request = this.anotherServer.takeRequest();
assertThat(request.getPath()).isEqualTo("/output-stream");
assertThat(request.getBody().readUtf8()).isEqualTo(body);
assertThat(request.getTarget()).isEqualTo("/output-stream");
assertThat(request.getBody().utf8()).isEqualTo(body);
}
@Test
void handleNotFoundException() {
MockResponse response = new MockResponse();
response.setResponseCode(404);
MockResponse response = new MockResponse.Builder().code(404).build();
this.anotherServer.enqueue(response);
RestClientAdapter clientAdapter = RestClientAdapter.create(
@@ -366,10 +373,9 @@ class RestClientAdapterTests {
return HttpServiceProxyFactory.builderFor(adapter).build().createClient(Service.class);
}
private void prepareResponse(Consumer<MockResponse> consumer) {
MockResponse response = new MockResponse();
consumer.accept(response);
this.anotherServer.enqueue(response);
private void prepareResponse(Function<MockResponse.Builder, MockResponse.Builder> f) {
MockResponse.Builder builder = new MockResponse.Builder();
this.anotherServer.enqueue(f.apply(builder).build());
}
@@ -16,11 +16,9 @@
package org.springframework.web.client.support;
import java.io.IOException;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import mockwebserver3.RecordedRequest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -61,8 +59,8 @@ public class RestClientProxyRegistryIntegrationTests {
}
@AfterEach
void shutdown() throws IOException {
this.server.shutdown();
void shutdown() {
this.server.close();
}
@@ -89,7 +87,7 @@ public class RestClientProxyRegistryIntegrationTests {
assertThat(registry.getClient(GreetingB.class)).isSameAs(greetingB);
for (int i = 0; i < 4; i++) {
this.server.enqueue(new MockResponse().setBody("body"));
this.server.enqueue(new MockResponse.Builder().body("body").build());
}
echoA.handle("a");
@@ -97,22 +95,22 @@ public class RestClientProxyRegistryIntegrationTests {
RecordedRequest request = this.server.takeRequest();
assertThat(request.getMethod()).isEqualTo("GET");
assertThat(request.getPath()).isEqualTo("/echoA?input=a");
assertThat(request.getTarget()).isEqualTo("/echoA?input=a");
request = this.server.takeRequest();
assertThat(request.getMethod()).isEqualTo("GET");
assertThat(request.getPath()).isEqualTo("/echoB?input=b");
assertThat(request.getTarget()).isEqualTo("/echoB?input=b");
greetingA.handle("a");
greetingB.handle("b");
request = this.server.takeRequest();
assertThat(request.getMethod()).isEqualTo("GET");
assertThat(request.getPath()).isEqualTo("/greetingA?input=a");
assertThat(request.getTarget()).isEqualTo("/greetingA?input=a");
request = this.server.takeRequest();
assertThat(request.getMethod()).isEqualTo("GET");
assertThat(request.getPath()).isEqualTo("/greetingB?input=b");
assertThat(request.getTarget()).isEqualTo("/greetingB?input=b");
}
@Test