Skip to content

Commit c6e1951

Browse files
committed
Merge branch '3.3.x'
Closes gh-43070
2 parents 8b6c80d + 81872af commit c6e1951

File tree

5 files changed

+86
-12
lines changed

5 files changed

+86
-12
lines changed

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ public void load(ImageArchive archive, UpdateListener<LoadImageUpdateEvent> list
270270
Assert.notNull(archive, "Archive must not be null");
271271
Assert.notNull(listener, "Listener must not be null");
272272
URI loadUri = buildUrl("/images/load");
273-
StreamCaptureUpdateListener streamListener = new StreamCaptureUpdateListener();
273+
LoadImageUpdateListener streamListener = new LoadImageUpdateListener(archive);
274274
listener.onStart();
275275
try {
276276
try (Response response = http().post(loadUri, "application/x-tar", archive::writeTo)) {
@@ -279,9 +279,7 @@ public void load(ImageArchive archive, UpdateListener<LoadImageUpdateEvent> list
279279
listener.onUpdate(event);
280280
});
281281
}
282-
Assert.state(StringUtils.hasText(streamListener.getCapturedStream()),
283-
"Invalid response received when loading image "
284-
+ ((archive.getTag() != null) ? "\"" + archive.getTag() + "\"" : ""));
282+
streamListener.assertValidResponseReceived();
285283
}
286284
finally {
287285
listener.onFinish();
@@ -557,19 +555,33 @@ public void onUpdate(ProgressUpdateEvent event) {
557555
}
558556

559557
/**
560-
* {@link UpdateListener} used to ensure an image load response stream.
558+
* {@link UpdateListener} for an image load response stream.
561559
*/
562-
private static final class StreamCaptureUpdateListener implements UpdateListener<LoadImageUpdateEvent> {
560+
private static final class LoadImageUpdateListener implements UpdateListener<LoadImageUpdateEvent> {
561+
562+
private final ImageArchive archive;
563563

564564
private String stream;
565565

566+
private LoadImageUpdateListener(ImageArchive archive) {
567+
this.archive = archive;
568+
}
569+
566570
@Override
567571
public void onUpdate(LoadImageUpdateEvent event) {
572+
Assert.state(event.getErrorDetail() == null,
573+
() -> "Error response received when loading image" + image() + ": " + event.getErrorDetail());
568574
this.stream = event.getStream();
569575
}
570576

571-
String getCapturedStream() {
572-
return this.stream;
577+
private String image() {
578+
ImageReference tag = this.archive.getTag();
579+
return (tag != null) ? " \"" + tag + "\"" : "";
580+
}
581+
582+
private void assertValidResponseReceived() {
583+
Assert.state(StringUtils.hasText(this.stream),
584+
() -> "Invalid response received when loading image" + image());
573585
}
574586

575587
}

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

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.buildpack.platform.docker;
1818

1919
import com.fasterxml.jackson.annotation.JsonCreator;
20+
import com.fasterxml.jackson.annotation.JsonProperty;
2021

2122
/**
2223
* A {@link ProgressUpdateEvent} fired as an image is loaded.
@@ -28,10 +29,14 @@ public class LoadImageUpdateEvent extends ProgressUpdateEvent {
2829

2930
private final String stream;
3031

32+
private final ErrorDetail errorDetail;
33+
3134
@JsonCreator
32-
public LoadImageUpdateEvent(String stream, String status, ProgressDetail progressDetail, String progress) {
35+
public LoadImageUpdateEvent(String stream, String status, ProgressDetail progressDetail, String progress,
36+
ErrorDetail errorDetail) {
3337
super(status, progressDetail, progress);
3438
this.stream = stream;
39+
this.errorDetail = errorDetail;
3540
}
3641

3742
/**
@@ -42,4 +47,42 @@ public String getStream() {
4247
return this.stream;
4348
}
4449

50+
/**
51+
* Return the error detail or {@code null} if no error occurred.
52+
* @return the error detail, if any
53+
* @since 3.2.12
54+
*/
55+
public ErrorDetail getErrorDetail() {
56+
return this.errorDetail;
57+
}
58+
59+
/**
60+
* Details of an error embedded in a response stream.
61+
*
62+
* @since 3.2.12
63+
*/
64+
public static class ErrorDetail {
65+
66+
private final String message;
67+
68+
@JsonCreator
69+
public ErrorDetail(@JsonProperty("message") String message) {
70+
this.message = message;
71+
}
72+
73+
/**
74+
* Returns the message field from the error detail.
75+
* @return the message
76+
*/
77+
public String getMessage() {
78+
return this.message;
79+
}
80+
81+
@Override
82+
public String toString() {
83+
return this.message;
84+
}
85+
86+
}
87+
4588
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,16 @@ void loadWithEmptyResponseThrowsException() throws Exception {
319319
.withMessageContaining("Invalid response received");
320320
}
321321

322+
@Test // gh-31243
323+
void loadWithErrorResponseThrowsException() throws Exception {
324+
Image image = Image.of(getClass().getResourceAsStream("type/image.json"));
325+
ImageArchive archive = ImageArchive.from(image);
326+
URI loadUri = new URI(IMAGES_URL + "/load");
327+
given(http().post(eq(loadUri), eq("application/x-tar"), any())).willReturn(responseOf("load-error.json"));
328+
assertThatIllegalStateException().isThrownBy(() -> this.api.load(archive, this.loadListener))
329+
.withMessageContaining("Error response received");
330+
}
331+
322332
@Test
323333
void loadLoadsImage() throws Exception {
324334
Image image = Image.of(getClass().getResourceAsStream("type/image.json"));

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import org.junit.jupiter.api.Test;
2020

21+
import org.springframework.boot.buildpack.platform.docker.LoadImageUpdateEvent.ErrorDetail;
2122
import org.springframework.boot.buildpack.platform.docker.ProgressUpdateEvent.ProgressDetail;
2223

2324
import static org.assertj.core.api.Assertions.assertThat;
@@ -36,9 +37,16 @@ void getStreamReturnsStream() {
3637
assertThat(event.getStream()).isEqualTo("stream");
3738
}
3839

40+
@Test
41+
void getErrorDetailReturnsErrorDetail() {
42+
LoadImageUpdateEvent event = createEvent();
43+
assertThat(event.getErrorDetail()).extracting(ErrorDetail::getMessage).isEqualTo("max depth exceeded");
44+
}
45+
3946
@Override
4047
protected LoadImageUpdateEvent createEvent(String status, ProgressDetail progressDetail, String progress) {
41-
return new LoadImageUpdateEvent("stream", status, progressDetail, progress);
48+
return new LoadImageUpdateEvent("stream", status, progressDetail, progress,
49+
new ErrorDetail("max depth exceeded"));
4250
}
4351

4452
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"errorDetail":{"message":"max depth exceeded"}}

0 commit comments

Comments
 (0)