X Tutup
Skip to content

Commit 376e7ed

Browse files
author
Marcus Linke
committed
Introduce WrappedResponseInputStream to close underlying Response
1 parent 155f24c commit 376e7ed

17 files changed

+233
-79
lines changed

src/main/java/com/github/dockerjava/api/command/AttachContainerCmd.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ public interface AttachContainerCmd extends DockerCmd<InputStream>{
5555
public AttachContainerCmd withLogs();
5656

5757
/**
58+
* Its the responsibility of the caller to consume and/or close the {@link InputStream} to prevent
59+
* connection leaks.
60+
*
5861
* @throws NotFoundException No such container
5962
*/
6063
@Override

src/main/java/com/github/dockerjava/api/command/CopyFileFromContainerCmd.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ public interface CopyFileFromContainerCmd extends DockerCmd<InputStream> {
1919
public CopyFileFromContainerCmd withHostPath(String hostPath);
2020

2121
/**
22+
* Its the responsibility of the caller to consume and/or close the {@link InputStream} to prevent
23+
* connection leaks.
24+
*
2225
* @throws NotFoundException No such container
2326
*/
2427
@Override

src/main/java/com/github/dockerjava/api/command/ExecStartCmd.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public interface ExecStartCmd extends DockerCmd<InputStream> {
2323
public ExecStartCmd withTty();
2424

2525
/**
26+
* Its the responsibility of the caller to consume and/or close the {@link InputStream} to prevent
27+
* connection leaks.
28+
*
2629
* @throws com.github.dockerjava.api.NotFoundException
2730
* No such exec instance
2831
*/

src/main/java/com/github/dockerjava/api/command/LogContainerCmd.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ public interface LogContainerCmd extends DockerCmd<InputStream>{
5656
public LogContainerCmd withTail(int tail);
5757

5858
/**
59+
* Its the responsibility of the caller to consume and/or close the {@link InputStream} to prevent
60+
* connection leaks.
61+
*
5962
* @throws NotFoundException No such container
6063
*/
6164
@Override

src/main/java/com/github/dockerjava/api/command/PullImageCmd.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,12 @@ public interface PullImageCmd extends DockerCmd<InputStream>{
2929

3030
public static interface Exec extends DockerCmdExec<PullImageCmd, InputStream> {
3131
}
32+
33+
/**
34+
* Its the responsibility of the caller to consume and/or close the {@link InputStream} to prevent
35+
* connection leaks.
36+
*/
37+
@Override
38+
public InputStream exec();
3239

3340
}

src/main/java/com/github/dockerjava/api/command/SaveImageCmd.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ public interface SaveImageCmd extends DockerCmd<InputStream>{
2121
public SaveImageCmd withTag(String tag);
2222

2323
/**
24+
* Its the responsibility of the caller to consume and/or close the {@link InputStream} to prevent
25+
* connection leaks.
26+
*
2427
* @throws com.github.dockerjava.api.NotFoundException No such image
2528
*/
2629
public InputStream exec() throws NotFoundException;

src/main/java/com/github/dockerjava/jaxrs/AttachContainerCmdExec.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.slf4j.LoggerFactory;
1111

1212
import com.github.dockerjava.api.command.AttachContainerCmd;
13+
import com.github.dockerjava.jaxrs.util.WrappedResponseInputStream;
1314

1415
public class AttachContainerCmdExec extends
1516
AbstrDockerCmdExec<AttachContainerCmd, InputStream> implements
@@ -36,9 +37,11 @@ protected InputStream execute(AttachContainerCmd command) {
3637

3738
LOGGER.trace("POST: {}", webResource);
3839

39-
return webResource.request()
40+
Response response = webResource.request()
4041
.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE)
41-
.post(null, Response.class).readEntity(InputStream.class);
42+
.post(null, Response.class);
43+
44+
return new WrappedResponseInputStream(response);
4245
}
4346

4447
}

src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java

Lines changed: 69 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -21,86 +21,93 @@
2121
import com.github.dockerjava.api.command.BuildImageCmd;
2222
import com.github.dockerjava.api.model.AuthConfigurations;
2323
import com.github.dockerjava.api.model.EventStreamItem;
24+
import com.github.dockerjava.jaxrs.util.WrappedResponseInputStream;
2425
import com.google.common.collect.ImmutableList;
2526

26-
public class BuildImageCmdExec extends AbstrDockerCmdExec<BuildImageCmd, BuildImageCmd.Response> implements BuildImageCmd.Exec {
27-
27+
public class BuildImageCmdExec extends
28+
AbstrDockerCmdExec<BuildImageCmd, BuildImageCmd.Response> implements
29+
BuildImageCmd.Exec {
30+
2831
private static final Logger LOGGER = LoggerFactory
2932
.getLogger(BuildImageCmdExec.class);
30-
33+
3134
public BuildImageCmdExec(WebTarget baseResource) {
3235
super(baseResource);
3336
}
3437

3538
@Override
3639
protected ResponseImpl execute(BuildImageCmd command) {
3740
WebTarget webResource = getBaseResource().path("/build");
38-
String dockerFilePath = command.getPathToDockerfile();
39-
40-
if(command.getTag() != null) {
41+
String dockerFilePath = command.getPathToDockerfile();
42+
43+
if (command.getTag() != null) {
4144
webResource = webResource.queryParam("t", command.getTag());
4245
}
43-
if (command.hasNoCacheEnabled()) {
44-
webResource = webResource.queryParam("nocache", "true");
45-
}
46-
if (command.hasRemoveEnabled()) {
47-
webResource = webResource.queryParam("rm", "true");
48-
}
49-
if (command.isQuiet()) {
50-
webResource = webResource.queryParam("q", "true");
51-
}
52-
if( dockerFilePath != null && !"Dockerfile".equals(dockerFilePath)) {
53-
webResource = webResource.queryParam("dockerfile", dockerFilePath);
54-
}
55-
56-
57-
webResource.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.CHUNKED);
58-
webResource.property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024*1024);
59-
60-
61-
LOGGER.debug("POST: {}", webResource);
62-
InputStream is = resourceWithOptionalAuthConfig(command, webResource.request())
63-
.accept(MediaType.TEXT_PLAIN)
64-
.post(entity(command.getTarInputStream(), "application/tar"), Response.class).readEntity(InputStream.class);
65-
66-
return new ResponseImpl(is);
67-
46+
if (command.hasNoCacheEnabled()) {
47+
webResource = webResource.queryParam("nocache", "true");
48+
}
49+
if (command.hasRemoveEnabled()) {
50+
webResource = webResource.queryParam("rm", "true");
51+
}
52+
if (command.isQuiet()) {
53+
webResource = webResource.queryParam("q", "true");
54+
}
55+
if (dockerFilePath != null && !"Dockerfile".equals(dockerFilePath)) {
56+
webResource = webResource.queryParam("dockerfile", dockerFilePath);
57+
}
58+
59+
webResource.property(ClientProperties.REQUEST_ENTITY_PROCESSING,
60+
RequestEntityProcessing.CHUNKED);
61+
webResource.property(ClientProperties.CHUNKED_ENCODING_SIZE,
62+
1024 * 1024);
63+
64+
LOGGER.debug("POST: {}", webResource);
65+
Response response = resourceWithOptionalAuthConfig(command,
66+
webResource.request())
67+
.accept(MediaType.TEXT_PLAIN)
68+
.post(entity(command.getTarInputStream(), "application/tar"),
69+
Response.class);
70+
71+
return new ResponseImpl(new WrappedResponseInputStream(response));
72+
6873
}
6974

70-
private Invocation.Builder resourceWithOptionalAuthConfig(BuildImageCmd command, Invocation.Builder request) {
75+
private Invocation.Builder resourceWithOptionalAuthConfig(
76+
BuildImageCmd command, Invocation.Builder request) {
7177
AuthConfigurations authConfigs = command.getBuildAuthConfigs();
7278
if (authConfigs != null) {
73-
request = request.header("X-Registry-Config", registryConfigs(authConfigs));
79+
request = request.header("X-Registry-Config",
80+
registryConfigs(authConfigs));
7481
}
7582
return request;
7683
}
77-
78-
public static class ResponseImpl extends BuildImageCmd.Response {
79-
80-
private final InputStream proxy;
81-
82-
public ResponseImpl(InputStream proxy) {
83-
this.proxy = proxy;
84-
}
85-
86-
@Override
87-
public Iterable<EventStreamItem> getItems() throws IOException {
88-
ObjectMapper mapper = new ObjectMapper();
89-
// we'll be reading instances of MyBean
90-
ObjectReader reader = mapper.reader(EventStreamItem.class);
91-
// and then do other configuration, if any, and read:
92-
Iterator<EventStreamItem> items = reader.readValues(proxy);
93-
94-
try {
95-
return ImmutableList.copyOf(items);
96-
} finally {
97-
proxy.close();
98-
}
99-
}
100-
101-
@Override
102-
public int read() throws IOException {
103-
return proxy.read();
104-
}
105-
}
84+
85+
public static class ResponseImpl extends BuildImageCmd.Response {
86+
87+
private final InputStream proxy;
88+
89+
public ResponseImpl(InputStream proxy) {
90+
this.proxy = proxy;
91+
}
92+
93+
@Override
94+
public Iterable<EventStreamItem> getItems() throws IOException {
95+
ObjectMapper mapper = new ObjectMapper();
96+
// we'll be reading instances of MyBean
97+
ObjectReader reader = mapper.reader(EventStreamItem.class);
98+
// and then do other configuration, if any, and read:
99+
Iterator<EventStreamItem> items = reader.readValues(proxy);
100+
101+
try {
102+
return ImmutableList.copyOf(items);
103+
} finally {
104+
proxy.close();
105+
}
106+
}
107+
108+
@Override
109+
public int read() throws IOException {
110+
return proxy.read();
111+
}
112+
}
106113
}

src/main/java/com/github/dockerjava/jaxrs/CopyFileFromContainerCmdExec.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66

77
import javax.ws.rs.client.WebTarget;
88
import javax.ws.rs.core.MediaType;
9+
import javax.ws.rs.core.Response;
910

1011
import org.slf4j.Logger;
1112
import org.slf4j.LoggerFactory;
1213

1314
import com.github.dockerjava.api.command.CopyFileFromContainerCmd;
15+
import com.github.dockerjava.jaxrs.util.WrappedResponseInputStream;
1416

1517
public class CopyFileFromContainerCmdExec extends AbstrDockerCmdExec<CopyFileFromContainerCmd, InputStream> implements CopyFileFromContainerCmd.Exec {
1618

@@ -29,7 +31,9 @@ protected InputStream execute(CopyFileFromContainerCmd command) {
2931

3032
LOGGER.trace("POST: " + webResource.toString());
3133

32-
return webResource.request().accept(MediaType.APPLICATION_OCTET_STREAM_TYPE).post(entity(command, MediaType.APPLICATION_JSON)).readEntity(InputStream.class);
34+
Response response = webResource.request().accept(MediaType.APPLICATION_OCTET_STREAM_TYPE).post(entity(command, MediaType.APPLICATION_JSON));
35+
36+
return new WrappedResponseInputStream(response);
3337
}
3438

3539
}

src/main/java/com/github/dockerjava/jaxrs/EventsCmdExec.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.github.dockerjava.api.command.EventCallback;
2121
import com.github.dockerjava.api.command.EventsCmd;
2222
import com.github.dockerjava.api.model.Event;
23+
import com.github.dockerjava.jaxrs.util.WrappedResponseInputStream;
2324

2425
public class EventsCmdExec extends AbstrDockerCmdExec<EventsCmd, ExecutorService> implements EventsCmd.Exec {
2526
private static final Logger LOGGER = LoggerFactory.getLogger(EventsCmdExec.class);
@@ -66,7 +67,7 @@ public Void call() throws Exception {
6667
Response response = null;
6768
try {
6869
response = webTarget.request().get(Response.class);
69-
InputStream inputStream = response.readEntity(InputStream.class);
70+
InputStream inputStream = new WrappedResponseInputStream(response);
7071
JsonParser jp = JSON_FACTORY.createParser(inputStream);
7172
while (jp.nextToken() != JsonToken.END_OBJECT && !jp.isClosed() && eventCallback.isReceiving()) {
7273
eventCallback.onEvent(OBJECT_MAPPER.readValue(jp, Event.class));

0 commit comments

Comments
 (0)
X Tutup