Browse Source

Merge branch '3.4.x'

Closes gh-44631
pull/44636/head
Moritz Halbritter 11 months ago
parent
commit
dde9bfbeaa
  1. 41
      spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpClientTransport.java
  2. 15
      spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/HttpClientTransportTests.java
  3. 15
      spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/transport/message-and-errors.json

41
spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpClientTransport.java

@ -36,7 +36,6 @@ import org.apache.hc.core5.http.Header; @@ -36,7 +36,6 @@ import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
import org.apache.hc.core5.http.message.StatusLine;
import org.springframework.boot.buildpack.platform.io.Content;
import org.springframework.boot.buildpack.platform.io.IOConsumer;
@ -51,6 +50,7 @@ import org.springframework.util.StringUtils; @@ -51,6 +50,7 @@ import org.springframework.util.StringUtils;
* @author Phillip Webb
* @author Mike Smithson
* @author Scott Frederick
* @author Moritz Halbritter
*/
abstract class HttpClientTransport implements HttpTransport {
@ -159,12 +159,12 @@ abstract class HttpClientTransport implements HttpTransport { @@ -159,12 +159,12 @@ abstract class HttpClientTransport implements HttpTransport {
ClassicHttpResponse response = this.client.executeOpen(this.host, request, null);
int statusCode = response.getCode();
if (statusCode >= 400 && statusCode <= 500) {
HttpEntity entity = response.getEntity();
Errors errors = (statusCode != 500) ? getErrorsFromResponse(entity) : null;
Message message = getMessageFromResponse(entity);
StatusLine statusLine = new StatusLine(response);
byte[] content = readContent(response);
response.close();
Errors errors = (statusCode != 500) ? deserializeErrors(content) : null;
Message message = deserializeMessage(content);
throw new DockerEngineException(this.host.toHostString(), request.getUri(), statusCode,
statusLine.getReasonPhrase(), errors, message);
response.getReasonPhrase(), errors, message);
}
return new HttpClientResponse(response);
}
@ -173,19 +173,38 @@ abstract class HttpClientTransport implements HttpTransport { @@ -173,19 +173,38 @@ abstract class HttpClientTransport implements HttpTransport {
}
}
private Errors getErrorsFromResponse(HttpEntity entity) {
private byte[] readContent(ClassicHttpResponse response) throws IOException {
HttpEntity entity = response.getEntity();
if (entity == null) {
return null;
}
try (InputStream stream = entity.getContent()) {
if (stream == null) {
return null;
}
return stream.readAllBytes();
}
}
private Errors deserializeErrors(byte[] content) {
if (content == null) {
return null;
}
try {
return SharedObjectMapper.get().readValue(entity.getContent(), Errors.class);
return SharedObjectMapper.get().readValue(content, Errors.class);
}
catch (IOException ex) {
return null;
}
}
private Message getMessageFromResponse(HttpEntity entity) {
private Message deserializeMessage(byte[] content) {
if (content == null) {
return null;
}
try {
return (entity.getContent() != null)
? SharedObjectMapper.get().readValue(entity.getContent(), Message.class) : null;
Message message = SharedObjectMapper.get().readValue(content, Message.class);
return (message.getMessage() != null) ? message : null;
}
catch (IOException ex) {
return null;

15
spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/HttpClientTransportTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -57,6 +57,7 @@ import static org.mockito.BDDMockito.then; @@ -57,6 +57,7 @@ import static org.mockito.BDDMockito.then;
* @author Phillip Webb
* @author Mike Smithson
* @author Scott Frederick
* @author Moritz Halbritter
*/
@ExtendWith(MockitoExtension.class)
class HttpClientTransportTests {
@ -309,6 +310,18 @@ class HttpClientTransportTests { @@ -309,6 +310,18 @@ class HttpClientTransportTests {
});
}
@Test
void shouldReturnErrorsAndMessage() throws IOException {
givenClientWillReturnResponse();
given(this.entity.getContent()).willReturn(getClass().getResourceAsStream("message-and-errors.json"));
given(this.response.getCode()).willReturn(404);
assertThatExceptionOfType(DockerEngineException.class).isThrownBy(() -> this.http.get(this.uri))
.satisfies((ex) -> {
assertThat(ex.getErrors()).hasSize(2);
assertThat(ex.getResponseMessage().getMessage()).contains("test message");
});
}
@Test
void executeWhenClientThrowsIOExceptionRethrowsAsDockerException() throws IOException {
given(this.client.executeOpen(any(HttpHost.class), any(HttpUriRequest.class), isNull()))

15
spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/transport/message-and-errors.json

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
{
"message": "test message",
"errors": [
{
"code": "TEST1",
"message": "Test One",
"detail": 123
},
{
"code": "TEST2",
"message": "Test Two",
"detail": "fail"
}
]
}
Loading…
Cancel
Save