下面列出了 io.netty.handler.codec.http.HttpClientUpgradeHandler #com.github.dockerjava.api.async.ResultCallback 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Test
@SuppressWarnings({"unchecked", "rawtypes"})
public void pullImageAsyncIfNeededWithError() {
final DockerImage image = DockerImage.fromString("test:1.2.3");
InspectImageCmd imageInspectCmd = mock(InspectImageCmd.class);
when(imageInspectCmd.exec()).thenThrow(new NotFoundException("Image not found"));
// Array to make it final
ArgumentCaptor<ResultCallback> resultCallback = ArgumentCaptor.forClass(ResultCallback.class);
PullImageCmd pullImageCmd = mock(PullImageCmd.class);
when(pullImageCmd.exec(resultCallback.capture())).thenReturn(null);
when(dockerClient.inspectImageCmd(image.asString())).thenReturn(imageInspectCmd);
when(dockerClient.pullImageCmd(eq(image.asString()))).thenReturn(pullImageCmd);
assertTrue("Should return true, we just scheduled the pull", docker.pullImageAsyncIfNeeded(image));
assertTrue("Should return true, the pull i still ongoing", docker.pullImageAsyncIfNeeded(image));
try {
resultCallback.getValue().onComplete();
} catch (Exception ignored) { }
assertFalse(docker.imageIsDownloaded(image));
assertTrue("Should return true, new pull scheduled", docker.pullImageAsyncIfNeeded(image));
}
private static void putImageInRegistry() throws InterruptedException {
// It doesn't matter which image we use for this test, but use one that's likely to have been pulled already
final String dummySourceImage = TestcontainersConfiguration.getInstance().getRyukImage();
client.pullImageCmd(dummySourceImage)
.exec(new PullImageResultCallback())
.awaitCompletion(1, TimeUnit.MINUTES);
final String id = client.inspectImageCmd(dummySourceImage)
.exec()
.getId();
// push the image to the registry
client.tagImageCmd(id, testImageName, "latest").exec();
client.pushImageCmd(testImageNameWithTag)
.exec(new ResultCallback.Adapter<>())
.awaitCompletion(1, TimeUnit.MINUTES);
}
@Override
default ResultCallback.Adapter<PushResponseItem> start() {
return exec(new ResultCallback.Adapter<PushResponseItem>() {
@Nullable
private PushResponseItem latestItem = null;
@Override
public void onNext(PushResponseItem item) {
this.latestItem = item;
}
@Override
protected void throwFirstError() {
super.throwFirstError();
if (latestItem == null) {
throw new DockerClientException("Could not push image");
} else if (latestItem.isErrorIndicated()) {
throw new DockerClientException("Could not push image: " + latestItem.getError());
}
}
});
}
@Override
protected Void execute0(LogSwarmObjectCmd command, ResultCallback<Frame> resultCallback) {
WebTarget webTarget = getBaseResource().path("/" + endpoint + "/{id}/logs").resolveTemplate("id", command.getId());
if (command.getTail() != null) {
webTarget = webTarget.queryParam("tail", command.getTail());
} else {
webTarget = webTarget.queryParam("tail", "all");
}
if (command.getSince() != null) {
webTarget = webTarget.queryParam("since", command.getSince());
}
webTarget = booleanQueryParam(webTarget, "timestamps", command.getTimestamps());
webTarget = booleanQueryParam(webTarget, "stdout", command.getStdout());
webTarget = booleanQueryParam(webTarget, "stderr", command.getStderr());
webTarget = booleanQueryParam(webTarget, "follow", command.getFollow());
LOGGER.trace("GET: {}", webTarget);
webTarget.request().get(resultCallback);
return null;
}
@Override
protected Void execute0(StatsCmd command, ResultCallback<Statistics> resultCallback) {
WebTarget webTarget = getBaseResource().path("/containers/{id}/stats").resolveTemplate("id",
command.getContainerId());
if (Boolean.TRUE.equals(command.hasNoStream())) {
webTarget = webTarget.queryParam("stream", "0");
}
LOGGER.trace("GET: {}", webTarget);
webTarget.request().get(new TypeReference<Statistics>() {
}, resultCallback);
return null;
}
@Override
protected Void execute0(PullImageCmd command, ResultCallback<PullResponseItem> resultCallback) {
WebTarget webResource = getBaseResource().path("/images/create").queryParam("tag", command.getTag())
.queryParam("fromImage", command.getRepository()).queryParam("registry", command.getRegistry());
if (command.getPlatform() != null) {
webResource = webResource.queryParam("platform", command.getPlatform());
}
LOGGER.trace("POST: {}", webResource);
resourceWithOptionalAuthConfig(command.getAuthConfig(), webResource.request())
.accept(MediaType.APPLICATION_OCTET_STREAM)
.post(null, new TypeReference<PullResponseItem>() {
}, resultCallback);
return null;
}
@Override
protected Void execute0(LogContainerCmd command, ResultCallback<Frame> resultCallback) {
WebTarget webTarget = getBaseResource().path("/containers/{id}/logs").resolveTemplate("id",
command.getContainerId());
if (command.getTail() != null) {
webTarget = webTarget.queryParam("tail", command.getTail());
}
if (command.getSince() != null) {
webTarget = webTarget.queryParam("since", command.getSince());
}
webTarget = booleanQueryParam(webTarget, "timestamps", command.hasTimestampsEnabled());
webTarget = booleanQueryParam(webTarget, "stdout", command.hasStdoutEnabled());
webTarget = booleanQueryParam(webTarget, "stderr", command.hasStderrEnabled());
webTarget = booleanQueryParam(webTarget, "follow", command.hasFollowStreamEnabled());
LOGGER.trace("GET: {}", webTarget);
webTarget.request().get(resultCallback);
return null;
}
@Override
protected Void execute0(EventsCmd command, ResultCallback<Event> resultCallback) {
WebTarget webTarget = getBaseResource().path("/events").queryParam("since", command.getSince())
.queryParam("until", command.getUntil());
if (command.getFilters() != null && !command.getFilters().isEmpty()) {
webTarget = webTarget
.queryParam("filters", FiltersEncoder.jsonEncode(command.getFilters()));
}
LOGGER.trace("GET: {}", webTarget);
webTarget.request().get(new TypeReference<Event>() {
}, resultCallback);
return null;
}
@Override
protected Void execute0(PushImageCmd command, ResultCallback<PushResponseItem> resultCallback) {
WebTarget webResource = getBaseResource().path("/images/{imageName}/push")
.resolveTemplate("imageName", command.getName())
.queryParam("tag", command.getTag());
LOGGER.trace("POST: {}", webResource);
InvocationBuilder builder = resourceWithAuthConfig(command.getAuthConfig(), webResource.request())
.accept(MediaType.APPLICATION_JSON);
builder.post(null, new TypeReference<PushResponseItem>() {
}, resultCallback);
return null;
}
@Override
protected Void execute0(AttachContainerCmd command, ResultCallback<Frame> resultCallback) {
WebTarget webTarget = getBaseResource().path("/containers/{id}/attach").resolveTemplate("id",
command.getContainerId());
webTarget = booleanQueryParam(webTarget, "logs", command.hasLogsEnabled());
webTarget = booleanQueryParam(webTarget, "stdout", command.hasStdoutEnabled());
webTarget = booleanQueryParam(webTarget, "stderr", command.hasStderrEnabled());
webTarget = booleanQueryParam(webTarget, "stdin", command.getStdin() != null);
webTarget = booleanQueryParam(webTarget, "stream", command.hasFollowStreamEnabled());
LOGGER.trace("POST: {}", webTarget);
webTarget.request().post(null, command.getStdin(), resultCallback);
return null;
}
@Override
public void post(Object entity, InputStream stdin, ResultCallback<Frame> resultCallback) {
final DockerHttpClient.Request request;
try {
request = requestBuilder
.method(DockerHttpClient.Request.Method.POST)
.putHeader("content-type", "application/json")
.body(new ByteArrayInputStream(objectMapper.writeValueAsBytes(entity)))
.hijackedInput(stdin)
.build();
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
executeAndStream(
request,
resultCallback,
new FramedInputStreamConsumer(resultCallback)
);
}
protected <T> void executeAndStream(
DockerHttpClient.Request request,
ResultCallback<T> callback,
Consumer<DockerHttpClient.Response> sourceConsumer
) {
Thread thread = new Thread(() -> {
Thread streamingThread = Thread.currentThread();
try (DockerHttpClient.Response response = execute(request)) {
callback.onStart(() -> {
streamingThread.interrupt();
response.close();
});
sourceConsumer.accept(response);
callback.onComplete();
} catch (Exception e) {
callback.onError(e);
}
}, "docker-java-stream-" + Objects.hashCode(request));
thread.setDaemon(true);
thread.start();
}
public <T> void post(TypeReference<T> typeReference, ResultCallback<T> resultCallback, InputStream body) {
HttpRequestProvider requestProvider = httpPostRequestProvider(null);
Channel channel = getChannel();
JsonResponseCallbackHandler<T> jsonResponseHandler = new JsonResponseCallbackHandler<>(
objectMapper,
typeReference,
resultCallback);
HttpResponseHandler responseHandler = new HttpResponseHandler(requestProvider, resultCallback);
channel.pipeline().addLast(new ChunkedWriteHandler());
channel.pipeline().addLast(responseHandler);
channel.pipeline().addLast(new JsonObjectDecoder(3 * 1024 * 1024));
channel.pipeline().addLast(jsonResponseHandler);
postChunkedStreamRequest(requestProvider, channel, body);
}
@Test
@SuppressWarnings({"unchecked", "rawtypes"})
public void pullImageAsyncIfNeededSuccessfully() {
final DockerImage image = DockerImage.fromString("test:1.2.3");
InspectImageResponse inspectImageResponse = mock(InspectImageResponse.class);
when(inspectImageResponse.getId()).thenReturn(image.asString());
InspectImageCmd imageInspectCmd = mock(InspectImageCmd.class);
when(imageInspectCmd.exec())
.thenThrow(new NotFoundException("Image not found"))
.thenReturn(inspectImageResponse);
// Array to make it final
ArgumentCaptor<ResultCallback> resultCallback = ArgumentCaptor.forClass(ResultCallback.class);
PullImageCmd pullImageCmd = mock(PullImageCmd.class);
when(pullImageCmd.exec(resultCallback.capture())).thenReturn(null);
when(dockerClient.inspectImageCmd(image.asString())).thenReturn(imageInspectCmd);
when(dockerClient.pullImageCmd(eq(image.asString()))).thenReturn(pullImageCmd);
assertTrue("Should return true, we just scheduled the pull", docker.pullImageAsyncIfNeeded(image));
assertTrue("Should return true, the pull i still ongoing", docker.pullImageAsyncIfNeeded(image));
assertTrue(docker.imageIsDownloaded(image));
resultCallback.getValue().onComplete();
assertFalse(docker.pullImageAsyncIfNeeded(image));
}
@Test(expected = NotFoundException.class)
public void testWaitNonExistingContainer() throws Exception {
ResultCallback.Adapter<WaitResponse> callback = new ResultCallback.Adapter<WaitResponse>() {
public void onNext(WaitResponse waitResponse) {
throw new AssertionError("expected NotFoundException");
}
};
dockerRule.getClient().waitContainerCmd("non-existing").exec(callback).awaitCompletion();
}
protected final Void execute(final CMD_T command, final ResultCallback<A_RES_T> resultCallback) {
ResultCallback<A_RES_T> delegatingResultCallback = new ResultCallback<A_RES_T>() {
@Override
public void close() throws IOException {
resultCallback.close();
command.close();
}
@Override
public void onStart(Closeable closeable) {
resultCallback.onStart(closeable);
}
@Override
public void onNext(A_RES_T object) {
resultCallback.onNext(object);
}
@Override
public void onError(Throwable throwable) {
resultCallback.onError(throwable);
}
@Override
public void onComplete() {
resultCallback.onComplete();
command.close();
}
};
execute0(command, delegatingResultCallback);
return null;
}
@Override
protected Void execute0(WaitContainerCmd command, ResultCallback<WaitResponse> resultCallback) {
WebTarget webTarget = getBaseResource().path("/containers/{id}/wait").resolveTemplate("id",
command.getContainerId());
LOGGER.trace("POST: {}", webTarget);
webTarget.request().accept(MediaType.APPLICATION_JSON).post((Object) null, new TypeReference<WaitResponse>() {
}, resultCallback);
return null;
}
@Override
protected Void execute0(ExecStartCmd command, ResultCallback<Frame> resultCallback) {
WebTarget webTarget = getBaseResource().path("/exec/{id}/start").resolveTemplate("id", command.getExecId());
webTarget.request().accept(MediaType.APPLICATION_JSON).post(command, command.getStdin(), resultCallback);
return null;
}
@Override
public void get(ResultCallback<Frame> resultCallback) {
DockerHttpClient.Request request = requestBuilder
.method(DockerHttpClient.Request.Method.GET)
.build();
executeAndStream(
request,
resultCallback,
new FramedInputStreamConsumer(resultCallback)
);
}
@Override
public <T> void get(TypeReference<T> typeReference, ResultCallback<T> resultCallback) {
DockerHttpClient.Request request = requestBuilder
.method(DockerHttpClient.Request.Method.GET)
.build();
executeAndStream(
request,
resultCallback,
new JsonSink<>(typeReference, resultCallback)
);
}
@Override
public <T> void post(Object entity, TypeReference<T> typeReference, ResultCallback<T> resultCallback) {
try {
post(typeReference, resultCallback, new ByteArrayInputStream(objectMapper.writeValueAsBytes(entity)));
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
@Override
public <T> void post(TypeReference<T> typeReference, ResultCallback<T> resultCallback, InputStream body) {
DockerHttpClient.Request request = requestBuilder
.method(DockerHttpClient.Request.Method.POST)
.body(body)
.build();
executeAndStream(
request,
resultCallback,
new JsonSink<>(typeReference, resultCallback)
);
}
@Deprecated
public JsonResponseCallbackHandler(TypeReference<T> typeReference, ResultCallback<T> callback) {
this(
DefaultDockerClientConfig.createDefaultConfigBuilder().build().getObjectMapper(),
typeReference,
callback
);
}
public static CompletableFuture<ContainerExecResult> runCommandAsync(DockerClient dockerClient,
String containerId,
String... cmd) {
CompletableFuture<ContainerExecResult> future = new CompletableFuture<>();
String execId = dockerClient.execCreateCmd(containerId)
.withCmd(cmd)
.withAttachStderr(true)
.withAttachStdout(true)
.exec()
.getId();
final InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(containerId).exec();
final String containerName = inspectContainerResponse.getName().replace("/","");
String cmdString = String.join(" ", cmd);
StringBuilder stdout = new StringBuilder();
StringBuilder stderr = new StringBuilder();
dockerClient.execStartCmd(execId).withDetach(false)
.exec(new ResultCallback<Frame>() {
@Override
public void close() {}
@Override
public void onStart(Closeable closeable) {
LOG.info("DOCKER.exec({}:{}): Executing...", containerName, cmdString);
}
@Override
public void onNext(Frame object) {
LOG.info("DOCKER.exec({}:{}): {}", containerName, cmdString, object);
if (StreamType.STDOUT == object.getStreamType()) {
stdout.append(new String(object.getPayload(), UTF_8));
} else if (StreamType.STDERR == object.getStreamType()) {
stderr.append(new String(object.getPayload(), UTF_8));
}
}
@Override
public void onError(Throwable throwable) {
future.completeExceptionally(throwable);
}
@Override
public void onComplete() {
LOG.info("DOCKER.exec({}:{}): Done", containerName, cmdString);
InspectExecResponse resp = dockerClient.inspectExecCmd(execId).exec();
while (resp.isRunning()) {
try {
Thread.sleep(200);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException(ie);
}
resp = dockerClient.inspectExecCmd(execId).exec();
}
int retCode = resp.getExitCode();
ContainerExecResult result = ContainerExecResult.of(
retCode,
stdout.toString(),
stderr.toString()
);
LOG.info("DOCKER.exec({}:{}): completed with {}", containerName, cmdString, retCode);
if (retCode != 0) {
LOG.error("DOCKER.exec({}:{}): completed with non zero return code: {}\nstdout: {}\nstderr: {}",
containerName, cmdString, result.getExitCode(), result.getStdout(), result.getStderr());
future.completeExceptionally(new ContainerExecException(cmdString, containerId, result));
} else {
future.complete(result);
}
}
});
return future;
}
public static ContainerExecResultBytes runCommandWithRawOutput(DockerClient dockerClient,
String containerId,
String... cmd) throws ContainerExecException {
CompletableFuture<Boolean> future = new CompletableFuture<>();
String execId = dockerClient.execCreateCmd(containerId)
.withCmd(cmd)
.withAttachStderr(true)
.withAttachStdout(true)
.exec()
.getId();
final InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(containerId).exec();
final String containerName = inspectContainerResponse.getName().replace("/","");
String cmdString = String.join(" ", cmd);
ByteBuf stdout = Unpooled.buffer();
ByteBuf stderr = Unpooled.buffer();
dockerClient.execStartCmd(execId).withDetach(false)
.exec(new ResultCallback<Frame>() {
@Override
public void close() {
}
@Override
public void onStart(Closeable closeable) {
LOG.info("DOCKER.exec({}:{}): Executing...", containerName, cmdString);
}
@Override
public void onNext(Frame object) {
if (StreamType.STDOUT == object.getStreamType()) {
stdout.writeBytes(object.getPayload());
} else if (StreamType.STDERR == object.getStreamType()) {
stderr.writeBytes(object.getPayload());
}
}
@Override
public void onError(Throwable throwable) {
future.completeExceptionally(throwable);
}
@Override
public void onComplete() {
LOG.info("DOCKER.exec({}:{}): Done", containerName, cmdString);
future.complete(true);
}
});
future.join();
InspectExecResponse resp = dockerClient.inspectExecCmd(execId).exec();
while (resp.isRunning()) {
try {
Thread.sleep(200);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException(ie);
}
resp = dockerClient.inspectExecCmd(execId).exec();
}
int retCode = resp.getExitCode();
byte[] stdoutBytes = new byte[stdout.readableBytes()];
stdout.readBytes(stdoutBytes);
byte[] stderrBytes = new byte[stderr.readableBytes()];
stderr.readBytes(stderrBytes);
ContainerExecResultBytes result = ContainerExecResultBytes.of(
retCode,
stdoutBytes,
stderrBytes);
LOG.info("DOCKER.exec({}:{}): completed with {}", containerName, cmdString, retCode);
if (retCode != 0) {
throw new ContainerExecException(cmdString, containerId, null);
}
return result;
}
/**
* {@link ResultCallback#onComplete()} should be called immediately after
* container exit. It was broken for Netty and TLS connection.
*/
@Test
public void attachContainerClosesStdoutWhenContainerExits() throws Exception {
DockerClient dockerClient = dockerRule.getClient();
CreateContainerResponse container = dockerClient.createContainerCmd(DEFAULT_IMAGE)
.withCmd("echo", "hello")
.withTty(false)
.exec();
LOG.info("Created container: {}", container.toString());
CountDownLatch gotLine = new CountDownLatch(1);
try (
ResultCallback.Adapter<Frame> resultCallback = dockerClient.attachContainerCmd(container.getId())
.withStdOut(true)
.withStdErr(true)
.withFollowStream(true)
.exec(new ResultCallback.Adapter<Frame>() {
@Override
public void onNext(Frame item) {
LOG.info("Got frame: {}", item);
if (item.getStreamType() == StreamType.STDOUT) {
gotLine.countDown();
}
super.onNext(item);
}
@Override
public void onComplete() {
LOG.info("On complete");
super.onComplete();
}
})
) {
resultCallback.awaitStarted(5, SECONDS);
LOG.info("Attach started");
dockerClient.startContainerCmd(container.getId()).exec();
LOG.info("Container started");
assertTrue("Should get first line quickly after the start", gotLine.await(15, SECONDS));
resultCallback.awaitCompletion(5, SECONDS);
}
}
@Override
default ResultCallback.Adapter<PullResponseItem> start() {
return exec(new PullImageResultCallback());
}
default ResultCallbackTemplate<?, A_RES_T> start() {
return exec(new ResultCallback.Adapter<>());
}
@Override
public Void exec(CMD_T command, ResultCallback<A_RES_T> resultCallback) {
return execute(command, resultCallback);
}
@Override
protected Void execute0(BuildImageCmd command, ResultCallback<BuildResponseItem> resultCallback) {
WebTarget webTarget = getBaseResource().path("/build");
String dockerFilePath = command.getPathToDockerfile();
if (dockerFilePath != null && command.getRemote() == null && !"Dockerfile".equals(dockerFilePath)) {
webTarget = webTarget.queryParam("dockerfile", dockerFilePath);
}
if (command.getTags() != null && !command.getTags().isEmpty()) {
webTarget = webTarget.queryParamsSet("t", command.getTags());
} else if (isNotBlank(command.getTag())) {
webTarget = webTarget.queryParam("t", command.getTag());
}
if (command.getCacheFrom() != null && !command.getCacheFrom().isEmpty()) {
webTarget = webTarget.queryParam("cachefrom", jsonEncode(command.getCacheFrom()));
}
if (command.getRemote() != null) {
webTarget = webTarget.queryParam("remote", command.getRemote().toString());
}
webTarget = booleanQueryParam(webTarget, "q", command.isQuiet());
webTarget = booleanQueryParam(webTarget, "nocache", command.hasNoCacheEnabled());
webTarget = booleanQueryParam(webTarget, "pull", command.hasPullEnabled());
webTarget = booleanQueryParam(webTarget, "rm", command.hasRemoveEnabled());
webTarget = booleanQueryParam(webTarget, "forcerm", command.isForcerm());
// this has to be handled differently as it should switch to 'false'
if (command.hasRemoveEnabled() == null || !command.hasRemoveEnabled()) {
webTarget = webTarget.queryParam("rm", "false");
}
if (command.getMemory() != null) {
webTarget = webTarget.queryParam("memory", command.getMemory());
}
if (command.getMemswap() != null) {
webTarget = webTarget.queryParam("memswap", command.getMemswap());
}
if (command.getCpushares() != null) {
webTarget = webTarget.queryParam("cpushares", command.getCpushares());
}
if (command.getCpusetcpus() != null) {
webTarget = webTarget.queryParam("cpusetcpus", command.getCpusetcpus());
}
if (command.getBuildArgs() != null) {
webTarget = webTarget.queryParamsJsonMap("buildargs", command.getBuildArgs());
}
if (command.getShmsize() != null) {
webTarget = webTarget.queryParam("shmsize", command.getShmsize());
}
if (command.getLabels() != null) {
webTarget = webTarget.queryParamsJsonMap("labels", command.getLabels());
}
if (command.getNetworkMode() != null) {
webTarget = webTarget.queryParam("networkmode", command.getNetworkMode());
}
if (command.getPlatform() != null) {
webTarget = webTarget.queryParam("platform", command.getPlatform());
}
if (command.getTarget() != null) {
webTarget = webTarget.queryParam("target", command.getTarget());
}
if (command.getExtraHosts() != null) {
webTarget = webTarget.queryParamsSet("extrahosts", command.getExtraHosts());
}
LOGGER.trace("POST: {}", webTarget);
InvocationBuilder builder = resourceWithOptionalAuthConfig(command, webTarget.request())
.accept(MediaType.APPLICATION_JSON)
.header("Content-Type", "application/tar")
.header("encoding", "gzip");
builder.post(new TypeReference<BuildResponseItem>() {
}, resultCallback, command.getTarInputStream());
return null;
}