Skip to content

Commit 42f4670

Browse files
author
Marcus Linke
committed
Fix issue docker-java#424
Conflicts: src/main/java/com/github/dockerjava/core/command/ExecStartCmdImpl.java src/main/java/com/github/dockerjava/core/command/ExecStartResultCallback.java src/main/java/com/github/dockerjava/jaxrs/ExecStartCmdExec.java src/main/java/com/github/dockerjava/netty/handler/FramedResponseStreamHandler.java src/test/java/com/github/dockerjava/core/command/ExecStartCmdImplTest.java src/test/java/com/github/dockerjava/core/command/InspectExecCmdImplTest.java src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java src/test/java/com/github/dockerjava/netty/exec/InspectExecCmdExecTest.java
1 parent 1eaa75a commit 42f4670

File tree

7 files changed

+130
-53
lines changed

7 files changed

+130
-53
lines changed

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import java.io.InputStream;
44

5-
import com.github.dockerjava.api.NotFoundException;
5+
import com.github.dockerjava.api.async.ResultCallback;
6+
import com.github.dockerjava.api.model.Frame;
67

7-
public interface ExecStartCmd extends SyncDockerCmd<InputStream> {
8+
public interface ExecStartCmd extends AsyncDockerCmd<ExecStartCmd, Frame> {
89

910
public String getExecId();
1011

@@ -29,8 +30,8 @@ public interface ExecStartCmd extends SyncDockerCmd<InputStream> {
2930
* No such exec instance
3031
*/
3132
@Override
32-
public InputStream exec() throws NotFoundException;
33+
public <T extends ResultCallback<Frame>> T exec(T resultCallback);
3334

34-
public static interface Exec extends DockerCmdSyncExec<ExecStartCmd, InputStream> {
35+
public static interface Exec extends DockerCmdAsyncExec<ExecStartCmd, Frame> {
3536
}
3637
}

src/main/java/com/github/dockerjava/core/command/ExecStartCmdImpl.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,27 @@
55
import java.io.InputStream;
66

77
import com.github.dockerjava.api.NotFoundException;
8+
9+
import com.fasterxml.jackson.annotation.JsonIgnore;
10+
import com.fasterxml.jackson.annotation.JsonInclude;
11+
import com.fasterxml.jackson.annotation.JsonInclude.Include;
12+
import com.fasterxml.jackson.annotation.JsonProperty;
13+
import com.github.dockerjava.api.async.ResultCallback;
814
import com.github.dockerjava.api.command.ExecStartCmd;
15+
import com.github.dockerjava.api.model.Frame;
916

10-
public class ExecStartCmdImpl extends AbstrDockerCmd<ExecStartCmd, InputStream> implements ExecStartCmd {
17+
@JsonInclude(Include.NON_NULL)
18+
public class ExecStartCmdImpl extends AbstrAsyncDockerCmd<ExecStartCmd, Frame> implements ExecStartCmd {
1119

20+
@JsonIgnore
1221
private String execId;
1322

14-
private boolean detach, tty;
23+
@JsonProperty("Detach")
24+
private Boolean detach;
25+
26+
@JsonProperty("Tty")
27+
private Boolean tty;
28+
1529

1630
public ExecStartCmdImpl(ExecStartCmd.Exec exec, String execId) {
1731
super(exec);
@@ -67,8 +81,8 @@ public ExecStartCmd withTty() {
6781
* No such exec instance
6882
*/
6983
@Override
70-
public InputStream exec() throws NotFoundException {
71-
return super.exec();
84+
public <T extends ResultCallback<Frame>> T exec(T resultCallback) {
85+
return super.exec(resultCallback);
7286
}
7387

7488
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.github.dockerjava.core.command;
2+
3+
import java.io.IOException;
4+
import java.io.OutputStream;
5+
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
9+
import com.github.dockerjava.api.model.Frame;
10+
import com.github.dockerjava.core.async.ResultCallbackTemplate;
11+
12+
/**
13+
*
14+
* @author Marcus Linke
15+
*
16+
*/
17+
public class ExecStartResultCallback extends ResultCallbackTemplate<ExecStartResultCallback, Frame> {
18+
19+
private final static Logger LOGGER = LoggerFactory.getLogger(ExecStartResultCallback.class);
20+
21+
private OutputStream stdout, stderr;
22+
23+
public ExecStartResultCallback(OutputStream stdout, OutputStream stderr) {
24+
this.stdout = stdout;
25+
this.stderr = stderr;
26+
}
27+
28+
public ExecStartResultCallback() {
29+
this(null, null);
30+
}
31+
32+
@Override
33+
public void onNext(Frame frame) {
34+
if (frame != null) {
35+
try {
36+
switch (frame.getStreamType()) {
37+
case STDOUT:
38+
case RAW:
39+
if (stdout != null) {
40+
System.err.println(new String(frame.getPayload()));
41+
stdout.write(frame.getPayload());
42+
stdout.flush();
43+
}
44+
break;
45+
case STDERR:
46+
if (stderr != null) {
47+
stderr.write(frame.getPayload());
48+
stderr.flush();
49+
}
50+
break;
51+
default:
52+
LOGGER.error("unknown stream type:" + frame.getStreamType());
53+
}
54+
} catch (IOException e) {
55+
onError(e);
56+
}
57+
58+
}
59+
LOGGER.debug(frame.toString());
60+
}
61+
}
Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
package com.github.dockerjava.jaxrs;
22

3-
import com.github.dockerjava.api.command.ExecStartCmd;
4-
import com.github.dockerjava.core.DockerClientConfig;
5-
import com.github.dockerjava.jaxrs.util.WrappedResponseInputStream;
6-
import org.slf4j.Logger;
7-
import org.slf4j.LoggerFactory;
8-
3+
import static javax.ws.rs.client.Entity.entity;
94
import javax.ws.rs.client.WebTarget;
105
import javax.ws.rs.core.MediaType;
11-
import javax.ws.rs.core.Response;
12-
import java.io.InputStream;
136

14-
import static javax.ws.rs.client.Entity.entity;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
10+
import com.github.dockerjava.api.async.ResultCallback;
11+
import com.github.dockerjava.api.command.ExecStartCmd;
12+
import com.github.dockerjava.api.model.Frame;
13+
import com.github.dockerjava.core.DockerClientConfig;
14+
import com.github.dockerjava.core.async.FrameStreamProcessor;
15+
import com.github.dockerjava.jaxrs.async.AbstractCallbackNotifier;
16+
import com.github.dockerjava.jaxrs.async.POSTCallbackNotifier;
1517

16-
public class ExecStartCmdExec extends AbstrSyncDockerCmdExec<ExecStartCmd, InputStream> implements ExecStartCmd.Exec {
18+
public class ExecStartCmdExec extends AbstrAsyncDockerCmdExec<ExecStartCmd, Frame> implements ExecStartCmd.Exec {
1719

1820
private static final Logger LOGGER = LoggerFactory.getLogger(ExecStartCmdExec.class);
1921

@@ -22,14 +24,13 @@ public ExecStartCmdExec(WebTarget baseResource, DockerClientConfig dockerClientC
2224
}
2325

2426
@Override
25-
protected InputStream execute(ExecStartCmd command) {
26-
WebTarget webResource = getBaseResource().path("/exec/{id}/start").resolveTemplate("id", command.getExecId());
27-
28-
LOGGER.trace("POST: {}", webResource);
27+
protected AbstractCallbackNotifier<Frame> callbackNotifier(ExecStartCmd command,
28+
ResultCallback<Frame> resultCallback) {
29+
WebTarget webTarget = getBaseResource().path("/exec/{id}/start").resolveTemplate("id", command.getExecId());
2930

30-
Response response = webResource.request().accept(MediaType.APPLICATION_JSON)
31-
.post(entity(command, MediaType.APPLICATION_JSON), Response.class);
31+
LOGGER.trace("POST: {}", webTarget);
3232

33-
return new WrappedResponseInputStream(response);
33+
return new POSTCallbackNotifier<Frame>(new FrameStreamProcessor(), resultCallback, webTarget.request().accept(
34+
MediaType.APPLICATION_JSON), entity(command, MediaType.APPLICATION_JSON));
3435
}
3536
}

src/test/java/com/github/dockerjava/core/command/ExecStartCmdImplTest.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ public void execStart() throws Exception {
5454

5555
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
5656
.withAttachStdout(true).withCmd("touch", "/execStartTest.log").exec();
57-
dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec();
57+
58+
dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec(
59+
new ExecStartResultCallback(System.out, System.err)).awaitCompletion();
5860

5961
InputStream response = dockerClient.copyFileFromContainerCmd(container.getId(), "/execStartTest.log").exec();
6062
boolean bytesAvailable = response.available() > 0;
@@ -79,7 +81,8 @@ public void execStartAttached() throws Exception {
7981

8082
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
8183
.withAttachStdout(true).withCmd("touch", "/execStartTest.log").exec();
82-
dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withTty(true).exec();
84+
dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withTty(true).exec(
85+
new ExecStartResultCallback(System.out, System.err)).awaitCompletion();
8386

8487
InputStream response = dockerClient.copyFileFromContainerCmd(container.getId(), "/execStartTest.log").exec();
8588
boolean bytesAvailable = response.available() > 0;

src/test/java/com/github/dockerjava/core/command/InspectExecCmdImplTest.java

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void afterMethod(ITestResult result) {
4747
}
4848

4949
@Test(groups = "ignoreInCircleCi")
50-
public void inspectExecTest() throws IOException {
50+
public void inspectExec() throws Exception {
5151
String containerName = "generated_" + new SecureRandom().nextInt();
5252

5353
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("top")
@@ -57,37 +57,34 @@ public void inspectExecTest() throws IOException {
5757

5858
dockerClient.startContainerCmd(container.getId()).exec();
5959

60-
ExecCreateCmdResponse touchFileCmdCreateResponse = dockerClient.execCreateCmd(container.getId())
61-
.withAttachStdout().withAttachStderr().withCmd("touch", "/marker").exec();
62-
LOG.info("Created exec {}", touchFileCmdCreateResponse.toString());
63-
assertThat(touchFileCmdCreateResponse.getId(), not(isEmptyString()));
64-
ExecCreateCmdResponse checkFileCmdCreateResponse = dockerClient.execCreateCmd(container.getId())
65-
.withAttachStdout().withAttachStderr().withCmd("test", "-e", "/marker").exec();
66-
LOG.info("Created exec {}", checkFileCmdCreateResponse.toString());
67-
assertThat(checkFileCmdCreateResponse.getId(), not(isEmptyString()));
68-
6960
// Check that file does not exist
70-
InputStream response1 = dockerClient.execStartCmd(container.getId())
71-
.withExecId(checkFileCmdCreateResponse.getId()).exec();
72-
asString(response1); // consume
73-
74-
InspectExecResponse first = dockerClient.inspectExecCmd(checkFileCmdCreateResponse.getId()).exec();
61+
ExecCreateCmdResponse checkFileExec1 = dockerClient.execCreateCmd(container.getId())
62+
.withAttachStdout(true).withAttachStderr(true).withCmd("test", "-e", "/marker").exec();
63+
LOG.info("Created exec {}", checkFileExec1.toString());
64+
assertThat(checkFileExec1.getId(), not(isEmptyString()));
65+
dockerClient.execStartCmd(checkFileExec1.getId()).exec(new ExecStartResultCallback(System.out, System.err)).awaitCompletion();
66+
InspectExecResponse first = dockerClient.inspectExecCmd(checkFileExec1.getId()).exec();
7567
assertThat(first.getExitCode(), is(1));
7668

7769
// Create the file
78-
InputStream response2 = dockerClient.execStartCmd(container.getId())
79-
.withExecId(touchFileCmdCreateResponse.getId()).exec();
80-
asString(response2);
81-
82-
InspectExecResponse second = dockerClient.inspectExecCmd(touchFileCmdCreateResponse.getId()).exec();
70+
ExecCreateCmdResponse touchFileExec = dockerClient.execCreateCmd(container.getId())
71+
.withAttachStdout(true).withAttachStderr(true).withCmd("touch", "/marker").exec();
72+
LOG.info("Created exec {}", touchFileExec.toString());
73+
assertThat(touchFileExec.getId(), not(isEmptyString()));
74+
dockerClient.execStartCmd(container.getId())
75+
.withExecId(touchFileExec.getId()).exec(new ExecStartResultCallback(System.out, System.err));
76+
InspectExecResponse second = dockerClient.inspectExecCmd(touchFileExec.getId()).exec();
8377
assertThat(second.getExitCode(), is(0));
8478

85-
// Check that file does exist now
86-
InputStream response3 = dockerClient.execStartCmd(container.getId())
87-
.withExecId(checkFileCmdCreateResponse.getId()).exec();
88-
asString(response3);
8979

90-
InspectExecResponse third = dockerClient.inspectExecCmd(checkFileCmdCreateResponse.getId()).exec();
80+
// Check that file does exist now
81+
ExecCreateCmdResponse checkFileExec2 = dockerClient.execCreateCmd(container.getId())
82+
.withAttachStdout(true).withAttachStderr(true).withCmd("test", "-e", "/marker").exec();
83+
LOG.info("Created exec {}", checkFileExec2.toString());
84+
assertThat(checkFileExec2.getId(), not(isEmptyString()));
85+
dockerClient.execStartCmd(container.getId())
86+
.withExecId(checkFileExec2.getId()).exec(new ExecStartResultCallback(System.out, System.err));
87+
InspectExecResponse third = dockerClient.inspectExecCmd(checkFileExec2.getId()).exec();
9188
assertThat(third.getExitCode(), is(0));
9289

9390
// Get container info and check its roundtrip to ensure the consistency

src/test/resources/testAddUrl/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM ubuntu:latest
22

33
# Copy testrun.sh files into the container
44

5-
ADD http://www.docker.io /tmp/docker_home.html
5+
ADD https://hub.docker.com/r/marcuslinke/busybox/ /tmp/docker_home.html
66
ADD ./testrun.sh /tmp/
77

88
RUN cp /tmp/testrun.sh /usr/local/bin/ && chmod +x /usr/local/bin/testrun.sh

0 commit comments

Comments
 (0)