Skip to content

Commit ce03f50

Browse files
Merge pull request #20297 from mikesmithson
2 parents 7634bfb + ada0741 commit ce03f50

File tree

2 files changed

+42
-33
lines changed
  • spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src

2 files changed

+42
-33
lines changed

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/HttpClientHttp.java

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.io.IOException;
2020
import java.io.InputStream;
2121
import java.io.OutputStream;
22+
import java.io.PrintWriter;
23+
import java.io.StringWriter;
2224
import java.net.URI;
2325

2426
import org.apache.http.HttpEntity;
@@ -36,7 +38,6 @@
3638
import org.apache.http.impl.client.CloseableHttpClient;
3739
import org.apache.http.impl.client.HttpClientBuilder;
3840
import org.apache.http.impl.client.HttpClients;
39-
import org.apache.http.util.EntityUtils;
4041

4142
import org.springframework.boot.buildpack.platform.io.Content;
4243
import org.springframework.boot.buildpack.platform.io.IOConsumer;
@@ -46,6 +47,8 @@
4647
* {@link Http} implementation backed by a {@link HttpClient}.
4748
*
4849
* @author Phillip Webb
50+
* @author Mike Smithson
51+
* @author Scott Frederick
4952
*/
5053
class HttpClientHttp implements Http {
5154

@@ -66,21 +69,19 @@ class HttpClientHttp implements Http {
6669
* Perform a HTTP GET operation.
6770
* @param uri the destination URI
6871
* @return the operation response
69-
* @throws IOException on IO error
7072
*/
7173
@Override
72-
public Response get(URI uri) throws IOException {
74+
public Response get(URI uri) {
7375
return execute(new HttpGet(uri));
7476
}
7577

7678
/**
7779
* Perform a HTTP POST operation.
7880
* @param uri the destination URI
7981
* @return the operation response
80-
* @throws IOException on IO error
8182
*/
8283
@Override
83-
public Response post(URI uri) throws IOException {
84+
public Response post(URI uri) {
8485
return execute(new HttpPost(uri));
8586
}
8687

@@ -90,11 +91,10 @@ public Response post(URI uri) throws IOException {
9091
* @param contentType the content type to write
9192
* @param writer a content writer
9293
* @return the operation response
93-
* @throws IOException on IO error
9494
*/
9595

9696
@Override
97-
public Response post(URI uri, String contentType, IOConsumer<OutputStream> writer) throws IOException {
97+
public Response post(URI uri, String contentType, IOConsumer<OutputStream> writer) {
9898
return execute(new HttpPost(uri), contentType, writer);
9999
}
100100

@@ -104,51 +104,50 @@ public Response post(URI uri, String contentType, IOConsumer<OutputStream> write
104104
* @param contentType the content type to write
105105
* @param writer a content writer
106106
* @return the operation response
107-
* @throws IOException on IO error
108107
*/
109108

110109
@Override
111-
public Response put(URI uri, String contentType, IOConsumer<OutputStream> writer) throws IOException {
110+
public Response put(URI uri, String contentType, IOConsumer<OutputStream> writer) {
112111
return execute(new HttpPut(uri), contentType, writer);
113112
}
114113

115114
/**
116115
* Perform a HTTP DELETE operation.
117116
* @param uri the destination URI
118117
* @return the operation response
119-
* @throws IOException on IO error
120118
*/
121119

122120
@Override
123-
public Response delete(URI uri) throws IOException {
121+
public Response delete(URI uri) {
124122
return execute(new HttpDelete(uri));
125123
}
126124

127125
private Response execute(HttpEntityEnclosingRequestBase request, String contentType,
128-
IOConsumer<OutputStream> writer) throws IOException {
126+
IOConsumer<OutputStream> writer) {
129127
request.setHeader(HttpHeaders.CONTENT_TYPE, contentType);
130128
request.setEntity(new WritableHttpEntity(writer));
131129
return execute(request);
132130
}
133131

134-
private Response execute(HttpUriRequest request) throws IOException {
135-
CloseableHttpResponse response = this.client.execute(request);
136-
StatusLine statusLine = response.getStatusLine();
137-
int statusCode = statusLine.getStatusCode();
138-
HttpEntity entity = response.getEntity();
139-
if (statusCode >= 200 && statusCode < 300) {
140-
return new HttpClientResponse(response);
141-
}
142-
Errors errors = null;
143-
if (statusCode >= 400 && statusCode < 500) {
144-
try {
145-
errors = SharedObjectMapper.get().readValue(entity.getContent(), Errors.class);
132+
private Response execute(HttpUriRequest request) {
133+
try {
134+
CloseableHttpResponse response = this.client.execute(request);
135+
StatusLine statusLine = response.getStatusLine();
136+
int statusCode = statusLine.getStatusCode();
137+
HttpEntity entity = response.getEntity();
138+
139+
if (statusCode >= 400 && statusCode < 500) {
140+
Errors errors = SharedObjectMapper.get().readValue(entity.getContent(), Errors.class);
141+
throw new DockerException(request.getURI(), statusCode, statusLine.getReasonPhrase(), errors);
146142
}
147-
catch (Exception ex) {
143+
if (statusCode == 500) {
144+
throw new DockerException(request.getURI(), statusCode, statusLine.getReasonPhrase(), null);
148145
}
146+
return new HttpClientResponse(response);
147+
}
148+
catch (IOException ioe) {
149+
throw new DockerException(request.getURI(), 500, ioe.getMessage(), null);
149150
}
150-
EntityUtils.consume(entity);
151-
throw new DockerException(request.getURI(), statusCode, statusLine.getReasonPhrase(), errors);
152151
}
153152

154153
/**
@@ -175,7 +174,7 @@ public long getContentLength() {
175174
}
176175

177176
@Override
178-
public InputStream getContent() throws IOException, UnsupportedOperationException {
177+
public InputStream getContent() throws UnsupportedOperationException {
179178
throw new UnsupportedOperationException();
180179
}
181180

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/HttpClientHttpTests.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.apache.http.HttpEntityEnclosingRequest;
2727
import org.apache.http.HttpHeaders;
2828
import org.apache.http.StatusLine;
29-
import org.apache.http.client.ClientProtocolException;
3029
import org.apache.http.client.methods.CloseableHttpResponse;
3130
import org.apache.http.client.methods.HttpDelete;
3231
import org.apache.http.client.methods.HttpGet;
@@ -54,6 +53,8 @@
5453
* Tests for {@link HttpClientHttp}.
5554
*
5655
* @author Phillip Webb
56+
* @author Mike Smithson
57+
* @author Scott Frederick
5758
*/
5859
class HttpClientHttpTests {
5960

@@ -132,7 +133,7 @@ void postWithContentShouldExecuteHttpPost() throws Exception {
132133
assertThat(entity.isRepeatable()).isFalse();
133134
assertThat(entity.getContentLength()).isEqualTo(-1);
134135
assertThat(entity.isStreaming()).isTrue();
135-
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> entity.getContent());
136+
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(entity::getContent);
136137
assertThat(writeToString(entity)).isEqualTo("test");
137138
assertThat(response.getContent()).isSameAs(this.content);
138139
}
@@ -152,7 +153,7 @@ void putWithContentShouldExecuteHttpPut() throws Exception {
152153
assertThat(entity.isRepeatable()).isFalse();
153154
assertThat(entity.getContentLength()).isEqualTo(-1);
154155
assertThat(entity.isStreaming()).isTrue();
155-
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> entity.getContent());
156+
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(entity::getContent);
156157
assertThat(writeToString(entity)).isEqualTo("test");
157158
assertThat(response.getContent()).isSameAs(this.content);
158159
}
@@ -171,20 +172,29 @@ void deleteShouldExecuteHttpDelete() throws IOException {
171172
}
172173

173174
@Test
174-
void executeWhenResposeIsIn400RangeShouldThrowDockerException() throws ClientProtocolException, IOException {
175+
void executeWhenResposeIsIn400RangeShouldThrowDockerException() throws IOException {
175176
given(this.entity.getContent()).willReturn(getClass().getResourceAsStream("errors.json"));
176177
given(this.statusLine.getStatusCode()).willReturn(404);
177178
assertThatExceptionOfType(DockerException.class).isThrownBy(() -> this.http.get(this.uri))
178179
.satisfies((ex) -> assertThat(ex.getErrors()).hasSize(2));
179180
}
180181

181182
@Test
182-
void executeWhenResposeIsIn500RangeShouldThrowDockerException() throws ClientProtocolException, IOException {
183+
void executeWhenResposeIsIn500RangeShouldThrowDockerException() {
183184
given(this.statusLine.getStatusCode()).willReturn(500);
184185
assertThatExceptionOfType(DockerException.class).isThrownBy(() -> this.http.get(this.uri))
185186
.satisfies((ex) -> assertThat(ex.getErrors()).isNull());
186187
}
187188

189+
@Test
190+
void executeWhenClientThrowsIOExceptionRethrowsAsDockerException() throws IOException {
191+
given(this.client.execute(any())).willThrow(new IOException("test IO exception"));
192+
assertThatExceptionOfType(DockerException.class).isThrownBy(() -> this.http.get(this.uri))
193+
.satisfies((ex) -> assertThat(ex.getErrors()).isNull())
194+
.satisfies(DockerException::getStatusCode).withMessageContaining("500")
195+
.satisfies((ex) -> assertThat(ex.getReasonPhrase()).contains("test IO exception"));
196+
}
197+
188198
private String writeToString(HttpEntity entity) throws IOException {
189199
ByteArrayOutputStream out = new ByteArrayOutputStream();
190200
entity.writeTo(out);

0 commit comments

Comments
 (0)