From 6d98872847e3f33b534bbc94e6264aad31aaedbf Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 Jun 2015 00:32:06 +0300 Subject: [PATCH 01/18] Update CreateContainer with 1.19 changes --- .../api/command/CreateContainerCmd.java | 40 +++++++++++++ .../core/command/CreateContainerCmdImpl.java | 56 +++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java index 3b558b6d9..136b5aecc 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java @@ -41,6 +41,26 @@ public static interface Exec extends DockerCmdExec Date: Sat, 20 Jun 2015 19:35:39 -0700 Subject: [PATCH 02/18] Adding Node type for Swarm support: --- .../github/dockerjava/api/model/Event.java | 9 +++++ .../com/github/dockerjava/api/model/Node.java | 37 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/com/github/dockerjava/api/model/Node.java diff --git a/src/main/java/com/github/dockerjava/api/model/Event.java b/src/main/java/com/github/dockerjava/api/model/Event.java index cb961f97d..b68d5b9a6 100644 --- a/src/main/java/com/github/dockerjava/api/model/Event.java +++ b/src/main/java/com/github/dockerjava/api/model/Event.java @@ -1,10 +1,12 @@ package com.github.dockerjava.api.model; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang.builder.ToStringBuilder; /** * Representation of a Docker event. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class Event { private String status; @@ -14,6 +16,9 @@ public class Event { private long time; + @JsonIgnoreProperties + private Node node; + /** * Default constructor for the deserialization. */ @@ -71,6 +76,10 @@ public long getTime() { return time; } + public Node getNode() { + return node; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this); diff --git a/src/main/java/com/github/dockerjava/api/model/Node.java b/src/main/java/com/github/dockerjava/api/model/Node.java new file mode 100644 index 000000000..4fcf04e69 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Node.java @@ -0,0 +1,37 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * A node as returned by the /events API, for instance, when Swarm is used. + */ +public class Node { + + @JsonProperty("Name") + private String name; + + @JsonProperty("Id") + private String id; + + @JsonProperty("Addr") + private String addr; + + @JsonProperty("Ip") + private String ip; + + public String getName() { + return name; + } + + public String getId() { + return id; + } + + public String getAddr() { + return addr; + } + + public String getIp() { + return ip; + } +} From 2d3174528c59d2ebe2255fc3596fc1d1adac2cdb Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Mon, 6 Jul 2015 20:11:45 +0200 Subject: [PATCH 03/18] Add labels to create and inspect container --- .../api/command/CreateContainerCmd.java | 9 ++++++++ .../dockerjava/api/model/ContainerConfig.java | 7 ++++++ .../core/command/CreateContainerCmdImpl.java | 18 +++++++++++++++ .../command/CreateContainerCmdImplTest.java | 22 +++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java index 3b558b6d9..3e31321ee 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java @@ -1,5 +1,7 @@ package com.github.dockerjava.api.command; +import java.util.Map; + import com.github.dockerjava.api.ConflictException; import com.github.dockerjava.api.NotFoundException; import com.github.dockerjava.api.model.Bind; @@ -173,6 +175,8 @@ public static interface Exec extends DockerCmdExec labels); + /** * Add link to another container. */ @@ -238,4 +242,9 @@ public static interface Exec extends DockerCmdExec getLabels(); + } diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java index 8ea673a36..0478e5ef0 100644 --- a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java @@ -51,6 +51,9 @@ public class ContainerConfig { @JsonProperty("Image") private String image; + @JsonProperty("Labels") + private Map labels; + @JsonProperty("MacAddress") private String macAddress; @@ -184,6 +187,10 @@ public String[] getOnBuild() { return onBuild; } + public Map getLabels() { + return labels; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this); diff --git a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java index cc082b61f..3caf3c1bc 100644 --- a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java @@ -2,6 +2,8 @@ import static com.google.common.base.Preconditions.checkNotNull; +import java.util.Map; + import org.apache.commons.lang.builder.ToStringBuilder; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -107,6 +109,9 @@ public class CreateContainerCmdImpl extends AbstrDockerCmd labels; + public CreateContainerCmdImpl(CreateContainerCmd.Exec exec, String image) { super(exec); checkNotNull(image, "image was not specified"); @@ -221,6 +226,12 @@ public Link[] getLinks() { return hostConfig.getLinks(); } + @Override + @JsonIgnore + public Map getLabels() { + return labels; + } + @Override @JsonIgnore public LxcConf[] getLxcConf() { @@ -471,6 +482,13 @@ public CreateContainerCmdImpl withImage(String image) { return this; } + @Override + public CreateContainerCmdImpl withLabels(Map labels) { + checkNotNull(labels, "labels was not specified"); + this.labels = labels; + return this; + } + @Override public CreateContainerCmdImpl withLinks(Link... links) { checkNotNull(links, "links was not specified"); diff --git a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java index a33cfddfe..efeed530a 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -13,6 +13,8 @@ import java.lang.reflect.Method; import java.security.SecureRandom; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; import static com.github.dockerjava.api.model.Capability.MKNOD; @@ -490,4 +492,24 @@ public void createContainerWithULimits() throws DockerException { } + @Test + public void createContainerWithLabels() throws DockerException { + + Map labels = new HashMap(); + labels.put("com.github.dockerjava.null", null); + labels.put("com.github.dockerjava.boolean", "true"); + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + .withLabels(labels).exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + + // null becomes empty string + labels.put("com.github.dockerjava.null", ""); + assertThat(inspectContainerResponse.getConfig().getLabels(), is(equalTo(labels))); + } } From 9419799ebc60650684e93aa47fe845a8d0917167 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 7 Jul 2015 08:15:15 +0200 Subject: [PATCH 04/18] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b76a052d8..506a18250 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,11 @@ Change Log === + Latest SNAPSHOT --- + +v.1.4.0 +--- * [#248](https://github.com/docker-java/docker-java/pull/233) Removed deprecated start options * [#247](https://github.com/docker-java/docker-java/pull/247) Add Domainname attribute on create command * [#245](https://github.com/docker-java/docker-java/pull/245) Added ReadonlyRootfs option From 8f3de2109103f665b59cd663c2f290e4491dce4b Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 7 Jul 2015 08:15:47 +0200 Subject: [PATCH 05/18] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a4c18a0ce..52d791923 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Run build without integration tests: com.github.docker-java docker-java - 1.3.0 + 1.4.0 ### Latest SNAPSHOT version @@ -74,7 +74,7 @@ You can find the latest SNAPSHOT version including javadoc and source files on [ com.github.docker-java docker-java - 1.3.1-SNAPSHOT + 1.4.1-SNAPSHOT ## Documentation From 4725809a72ab5c95a44888085193caa420e8c33a Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Tue, 7 Jul 2015 12:09:49 +0200 Subject: [PATCH 06/18] Add filters option to list containers --- .../api/command/ListContainersCmd.java | 5 ++ .../github/dockerjava/api/model/Filters.java | 90 +++++++++++++++++++ .../core/command/ListContainersCmdImpl.java | 20 ++++- .../jaxrs/ListContainersCmdExec.java | 7 ++ .../command/ListContainersCmdImplTest.java | 22 ++++- 5 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/github/dockerjava/api/model/Filters.java diff --git a/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java b/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java index 6d641f2e3..c2a116bed 100644 --- a/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java @@ -3,6 +3,7 @@ import java.util.List; import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.api.model.Filters; /** * List containers @@ -31,6 +32,8 @@ public interface ListContainersCmd extends DockerCmd> { public String getBeforeId(); + public Filters getFilters(); + public ListContainersCmd withShowAll(boolean showAll); public ListContainersCmd withShowSize(boolean showSize); @@ -41,6 +44,8 @@ public interface ListContainersCmd extends DockerCmd> { public ListContainersCmd withBefore(String before); + public ListContainersCmd withFilters(Filters filters); + public static interface Exec extends DockerCmdExec> { } diff --git a/src/main/java/com/github/dockerjava/api/model/Filters.java b/src/main/java/com/github/dockerjava/api/model/Filters.java new file mode 100644 index 000000000..4555acdbf --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Filters.java @@ -0,0 +1,90 @@ +package com.github.dockerjava.api.model; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.MediaType; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; + +/** + * Representation of Docker filters. + * + * @author Carlos Sanchez + * + */ +public class Filters { + + private static ObjectMapper OBJECT_MAPPER = new JacksonJaxbJsonProvider().locateMapper(Map.class, + MediaType.APPLICATION_JSON_TYPE); + + private Map filters = new HashMap(); + + public Filters() { + } + + /** + * Constructor. + * + * @param image + * image to filter + * @param container + * container to filter + */ + public Filters(String image, String container) { + withImage(image); + withContainer(container); + } + + public Filters withFilter(String key, String... value) { + filters.put(key, value); + return this; + } + + public String[] getFilter(String key) { + return filters.get(key); + } + + public Filters withImage(String... image) { + filters.put("image", image); + return this; + } + + public String[] getImage() { + return getFilter("image"); + } + + public Filters withContainer(String... container) { + filters.put("container", container); + return this; + } + + public String[] getContainer() { + return getFilter("container"); + } + + public Filters withLabel(String label) { + return withLabel(label, (String[]) null); + } + + public Filters withLabel(String label, String... value) { + if (value != null) { + filters.put(label, value); + } else { + filters.put("label", new String[] { label }); + } + return this; + } + + @Override + public String toString() { + try { + return OBJECT_MAPPER.writeValueAsString(filters); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java index 13bb02cfb..f810798cf 100644 --- a/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java @@ -1,12 +1,12 @@ package com.github.dockerjava.core.command; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.*; import java.util.List; import com.github.dockerjava.api.command.ListContainersCmd; import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.api.model.Filters; /** * List containers @@ -32,6 +32,8 @@ public class ListContainersCmdImpl extends AbstrDockerCmd execute(ListContainersCmd command) { webResource = webResource.queryParam("limit", String.valueOf(command.getLimit())); } + if (command.getFilters() != null) { + webResource = webResource.queryParam("filters", + urlPathSegmentEscaper().escape(command.getFilters().toString())); + } + LOGGER.trace("GET: {}", webResource); List containers = webResource.request().accept(MediaType.APPLICATION_JSON) .get(new GenericType>() { diff --git a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java index b074409bd..f99abaa94 100644 --- a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java @@ -26,7 +26,9 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.api.model.Filters; import com.github.dockerjava.client.AbstractDockerClientTest; +import com.google.common.collect.ImmutableMap; @Test(groups = "integration") public class ListContainersCmdImplTest extends AbstractDockerClientTest { @@ -65,7 +67,8 @@ public void testListContainers() throws DockerException { int size = containers.size(); - CreateContainerResponse container1 = dockerClient.createContainerCmd(testImage).withCmd("echo").exec(); + CreateContainerResponse container1 = dockerClient.createContainerCmd(testImage).withCmd("echo") + .withLabels(ImmutableMap.of("test", "docker-java")).exec(); assertThat(container1.getId(), not(isEmptyString())); @@ -96,7 +99,22 @@ public void testListContainers() throws DockerException { Container container2 = filteredContainers.get(0); assertThat(container2.getCommand(), not(isEmptyString())); - assertThat(container2.getImage(), startsWith(testImage + ":")); + assertThat(container2.getImage(), startsWith(testImage)); + + // list with filter by label + filteredContainers = dockerClient.listContainersCmd().withShowAll(true) + .withFilters(new Filters().withLabel("test", "docker-java")).exec(); + assertThat(filteredContainers.size(), is(equalTo(1))); + Container container3 = filteredContainers.get(0); + assertThat(container3.getCommand(), not(isEmptyString())); + assertThat(container3.getImage(), startsWith(testImage)); + + filteredContainers = dockerClient.listContainersCmd().withShowAll(true) + .withFilters(new Filters().withLabel("test")).exec(); + assertThat(filteredContainers.size(), is(equalTo(1))); + container3 = filteredContainers.get(0); + assertThat(container3.getCommand(), not(isEmptyString())); + assertThat(container3.getImage(), startsWith(testImage)); } } From 6f54ec40a750d40432db40ae79e9bfb5e13c754c Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Tue, 7 Jul 2015 21:55:37 +0200 Subject: [PATCH 07/18] Make callback template abstract --- .../github/dockerjava/core/async/ResultCallbackTemplate.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java b/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java index d9a408c35..50cc1fd91 100644 --- a/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java +++ b/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java @@ -11,12 +11,12 @@ import com.github.dockerjava.api.async.ResultCallback; /** - * Template implementation of {@link ResultCallback} + * Abstract template implementation of {@link ResultCallback} * * @author marcus * */ -public class ResultCallbackTemplate implements ResultCallback { +public abstract class ResultCallbackTemplate implements ResultCallback { private final CountDownLatch finished = new CountDownLatch(1); From b23d858dca7faf1a8b0d4eb838f369cf8f2607b2 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 7 Jul 2015 23:17:20 +0200 Subject: [PATCH 08/18] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 506a18250..ab3c373e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ Change Log Latest SNAPSHOT --- +* [#263](https://github.com/docker-java/docker-java/pull/263) Refactoring of streaming commands APIs (event, stats, log, attach) +* [#260](https://github.com/docker-java/docker-java/pull/260) Add labels to create and inspect container + v.1.4.0 --- * [#248](https://github.com/docker-java/docker-java/pull/233) Removed deprecated start options From 299fa5e4e825a0abff8ddc32707c46f7cb11a7be Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Tue, 7 Jul 2015 23:23:17 +0200 Subject: [PATCH 09/18] Added comment about Event node --- .../java/com/github/dockerjava/api/model/Event.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/Event.java b/src/main/java/com/github/dockerjava/api/model/Event.java index c4050e93f..14637d6e7 100644 --- a/src/main/java/com/github/dockerjava/api/model/Event.java +++ b/src/main/java/com/github/dockerjava/api/model/Event.java @@ -27,7 +27,7 @@ public Event() { /** * Constructor. - * + * * @param id * Container ID * @param status @@ -51,7 +51,7 @@ public Event(String status, String id, String from, long time) { * Status of docker image or container. List of statuses is available in Docker API * v.1.16 - * + * * @return Status string */ public String getStatus() { @@ -60,7 +60,7 @@ public String getStatus() { /** * Get ID of docker container. - * + * * @return Container ID */ public String getId() { @@ -69,7 +69,7 @@ public String getId() { /** * Get source image of the container. - * + * * @return Name of the parent container */ public String getFrom() { @@ -78,13 +78,16 @@ public String getFrom() { /** * Get the event time. The time is specified in milliseconds since January 1, 1970, 00:00:00 GMT - * + * * @return Event time in the specified format. */ public long getTime() { return time; } + /** + * Returns the node when working against docker swarm + */ public Node getNode() { return node; } From 9366a9d9c7b1cf19a986e94c980595fe84773dc5 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Tue, 7 Jul 2015 23:30:39 +0200 Subject: [PATCH 10/18] Ignore test in CircleCI --- .../dockerjava/core/command/CreateContainerCmdImplTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java index 09d184061..9876e43d5 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -490,7 +490,7 @@ public void createContainerWithULimits() throws DockerException { } - @Test + @Test(groups = "ignoreInCircleCi") public void createContainerWithLabels() throws DockerException { Map labels = new HashMap(); From 769f176777d878b7872f715da73bce1eef75f157 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Fri, 10 Jul 2015 11:36:30 +0200 Subject: [PATCH 11/18] Filtering by labels always needs the "label" key --- .../github/dockerjava/api/model/Filters.java | 36 +++++++++---------- .../core/command/ListContainersCmdImpl.java | 6 ++-- .../command/ListContainersCmdImplTest.java | 7 ++-- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/Filters.java b/src/main/java/com/github/dockerjava/api/model/Filters.java index 4555acdbf..a226c60c2 100644 --- a/src/main/java/com/github/dockerjava/api/model/Filters.java +++ b/src/main/java/com/github/dockerjava/api/model/Filters.java @@ -1,5 +1,6 @@ package com.github.dockerjava.api.model; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -21,7 +22,7 @@ public class Filters { private static ObjectMapper OBJECT_MAPPER = new JacksonJaxbJsonProvider().locateMapper(Map.class, MediaType.APPLICATION_JSON_TYPE); - private Map filters = new HashMap(); + private Map> filters = new HashMap>(); public Filters() { } @@ -40,42 +41,41 @@ public Filters(String image, String container) { } public Filters withFilter(String key, String... value) { - filters.put(key, value); + filters.put(key, Arrays.asList(value)); return this; } - public String[] getFilter(String key) { + public List getFilter(String key) { return filters.get(key); } public Filters withImage(String... image) { - filters.put("image", image); + filters.put("image", Arrays.asList(image)); return this; } - public String[] getImage() { + public List getImage() { return getFilter("image"); } public Filters withContainer(String... container) { - filters.put("container", container); + filters.put("container", Arrays.asList(container)); return this; } - public String[] getContainer() { + public List getContainer() { return getFilter("container"); } - public Filters withLabel(String label) { - return withLabel(label, (String[]) null); - } - - public Filters withLabel(String label, String... value) { - if (value != null) { - filters.put(label, value); - } else { - filters.put("label", new String[] { label }); - } + /** + * Filter by labels + * + * @param labels + * string array in the form ["key"] or ["key=value"] or a mix of both + * @return + */ + public Filters withLabel(String... labels) { + filters.put("label", Arrays.asList(labels)); return this; } @@ -87,4 +87,4 @@ public String toString() { throw new RuntimeException(e); } } -} \ No newline at end of file +} diff --git a/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java index f810798cf..b957a3bd6 100644 --- a/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java @@ -111,8 +111,8 @@ public ListContainersCmd withFilters(Filters filters) { @Override public String toString() { return new StringBuilder("ps ").append(showAll ? "--all=true" : "").append(showSize ? "--size=true" : "") - .append(sinceId != null ? "--since " + sinceId : "") - .append(beforeId != null ? "--before " + beforeId : "").append(limit != -1 ? "-n " + limit : "") - .append(filters != null ? "--filters " + filters : "").toString(); + .append(sinceId != null ? " --since " + sinceId : "") + .append(beforeId != null ? " --before " + beforeId : "").append(limit != -1 ? "-n " + limit : "") + .append(filters != null ? " --filters " + filters : "").toString(); } } diff --git a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java index f99abaa94..da049488b 100644 --- a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java @@ -67,8 +67,7 @@ public void testListContainers() throws DockerException { int size = containers.size(); - CreateContainerResponse container1 = dockerClient.createContainerCmd(testImage).withCmd("echo") - .withLabels(ImmutableMap.of("test", "docker-java")).exec(); + CreateContainerResponse container1 = dockerClient.createContainerCmd(testImage).withCmd("echo").exec(); assertThat(container1.getId(), not(isEmptyString())); @@ -102,8 +101,10 @@ public void testListContainers() throws DockerException { assertThat(container2.getImage(), startsWith(testImage)); // list with filter by label + dockerClient.createContainerCmd(testImage).withCmd("echo").withLabels(ImmutableMap.of("test", "docker-java")) + .exec(); filteredContainers = dockerClient.listContainersCmd().withShowAll(true) - .withFilters(new Filters().withLabel("test", "docker-java")).exec(); + .withFilters(new Filters().withLabel("test=docker-java")).exec(); assertThat(filteredContainers.size(), is(equalTo(1))); Container container3 = filteredContainers.get(0); assertThat(container3.getCommand(), not(isEmptyString())); From d2b618ba96463ae1f51ef23fa0130e8f06ad6322 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Sat, 11 Jul 2015 10:47:34 +0200 Subject: [PATCH 12/18] Add labels to list container command result --- .../dockerjava/api/model/Container.java | 9 +++ .../github/dockerjava/api/model/Filters.java | 54 ++++++++++------- .../command/ListContainersCmdImplTest.java | 60 +++++++++++++++++-- 3 files changed, 99 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/Container.java b/src/main/java/com/github/dockerjava/api/model/Container.java index 6a97e20b9..8152974e3 100644 --- a/src/main/java/com/github/dockerjava/api/model/Container.java +++ b/src/main/java/com/github/dockerjava/api/model/Container.java @@ -1,5 +1,7 @@ package com.github.dockerjava.api.model; +import java.util.Map; + import org.apache.commons.lang.builder.ToStringBuilder; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -31,6 +33,9 @@ public class Container { @JsonProperty("Ports") public Port[] ports; + @JsonProperty("Labels") + public Map labels; + @JsonProperty("Status") private String status; @@ -58,6 +63,10 @@ public Port[] getPorts() { return ports; } + public Map getLabels() { + return labels; + } + public String[] getNames() { return names; } diff --git a/src/main/java/com/github/dockerjava/api/model/Filters.java b/src/main/java/com/github/dockerjava/api/model/Filters.java index a226c60c2..6e29491c3 100644 --- a/src/main/java/com/github/dockerjava/api/model/Filters.java +++ b/src/main/java/com/github/dockerjava/api/model/Filters.java @@ -1,9 +1,11 @@ package com.github.dockerjava.api.model; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import javax.ws.rs.core.MediaType; @@ -27,19 +29,6 @@ public class Filters { public Filters() { } - /** - * Constructor. - * - * @param image - * image to filter - * @param container - * container to filter - */ - public Filters(String image, String container) { - withImage(image); - withContainer(container); - } - public Filters withFilter(String key, String... value) { filters.put(key, Arrays.asList(value)); return this; @@ -49,8 +38,8 @@ public List getFilter(String key) { return filters.get(key); } - public Filters withImage(String... image) { - filters.put("image", Arrays.asList(image)); + public Filters withImages(String... image) { + withFilter("image", image); return this; } @@ -58,8 +47,8 @@ public List getImage() { return getFilter("image"); } - public Filters withContainer(String... container) { - filters.put("container", Arrays.asList(container)); + public Filters withContainers(String... container) { + withFilter("container", container); return this; } @@ -69,16 +58,41 @@ public List getContainer() { /** * Filter by labels - * + * * @param labels * string array in the form ["key"] or ["key=value"] or a mix of both * @return */ - public Filters withLabel(String... labels) { - filters.put("label", Arrays.asList(labels)); + public Filters withLabels(String... labels) { + withFilter("label", labels); return this; } + /** + * Filter by labels + * + * @param labels + * {@link Map} of labels that contains label keys and values + * @return + */ + public Filters withLabels(Map labels) { + withFilter("label", labelsMapToList(labels).toArray(new String[labels.size()])); + return this; + } + + private static List labelsMapToList(Map labels) { + List result = new ArrayList(); + for (Entry entry : labels.entrySet()) { + String rest = (entry.getValue() != null & !entry.getValue().isEmpty()) ? "=" + entry.getValue() + : ""; + + String label = entry.getKey() + rest; + + result.add(label); + } + return result; + } + @Override public String toString() { try { diff --git a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java index da049488b..ae8e52b19 100644 --- a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java @@ -13,6 +13,7 @@ import java.lang.reflect.Method; import java.util.List; +import java.util.Map; import org.hamcrest.Matcher; import org.testng.ITestResult; @@ -53,7 +54,6 @@ public void afterMethod(ITestResult result) { super.afterMethod(result); } - @Test public void testListContainers() throws DockerException { String testImage = "busybox"; @@ -99,23 +99,75 @@ public void testListContainers() throws DockerException { Container container2 = filteredContainers.get(0); assertThat(container2.getCommand(), not(isEmptyString())); assertThat(container2.getImage(), startsWith(testImage)); + } + + @Test + public void testListContainersWithLabelsFilter() throws DockerException { + + String testImage = "busybox"; + + // need to block until image is pulled completely + asString(dockerClient.pullImageCmd(testImage).exec()); + + List containers = dockerClient.listContainersCmd().withShowAll(true).exec(); + assertThat(containers, notNullValue()); + LOG.info("Container List: {}", containers); + + int size = containers.size(); + + CreateContainerResponse container1 = dockerClient.createContainerCmd(testImage).withCmd("echo").exec(); + + assertThat(container1.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container1.getId()).exec(); + + assertThat(inspectContainerResponse.getConfig().getImage(), is(equalTo(testImage))); + + dockerClient.startContainerCmd(container1.getId()).exec(); + + LOG.info("container id: " + container1.getId()); + + List containers2 = dockerClient.listContainersCmd().withShowAll(true).exec(); + + for (Container container : containers2) { + LOG.info("listContainer: id=" + container.getId() + " image=" + container.getImage()); + } + + assertThat(size + 1, is(equalTo(containers2.size()))); + Matcher matcher = hasItem(hasField("id", startsWith(container1.getId()))); + assertThat(containers2, matcher); + + List filteredContainers = filter(hasField("id", startsWith(container1.getId())), containers2); + assertThat(filteredContainers.size(), is(equalTo(1))); + + for (Container container : filteredContainers) { + LOG.info("filteredContainer: " + container); + } + + Container container2 = filteredContainers.get(0); + assertThat(container2.getCommand(), not(isEmptyString())); + assertThat(container2.getImage(), startsWith(testImage)); + + + Map labels = ImmutableMap.of("test", "docker-java"); // list with filter by label - dockerClient.createContainerCmd(testImage).withCmd("echo").withLabels(ImmutableMap.of("test", "docker-java")) + dockerClient.createContainerCmd(testImage).withCmd("echo").withLabels(labels) .exec(); filteredContainers = dockerClient.listContainersCmd().withShowAll(true) - .withFilters(new Filters().withLabel("test=docker-java")).exec(); + .withFilters(new Filters().withLabels(labels)).exec(); assertThat(filteredContainers.size(), is(equalTo(1))); Container container3 = filteredContainers.get(0); assertThat(container3.getCommand(), not(isEmptyString())); assertThat(container3.getImage(), startsWith(testImage)); filteredContainers = dockerClient.listContainersCmd().withShowAll(true) - .withFilters(new Filters().withLabel("test")).exec(); + .withFilters(new Filters().withLabels("test")).exec(); assertThat(filteredContainers.size(), is(equalTo(1))); container3 = filteredContainers.get(0); assertThat(container3.getCommand(), not(isEmptyString())); assertThat(container3.getImage(), startsWith(testImage)); + assertEquals(container3.getLabels(), labels); } } From db06b33fa31f8b294f35cda4a0e43a26ac3c8b76 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Sat, 11 Jul 2015 10:49:48 +0200 Subject: [PATCH 13/18] format sources --- .../com/github/dockerjava/api/model/Node.java | 40 +++++++++---------- .../dockerjava/core/command/FrameReader.java | 3 +- .../client/AbstractDockerClientTest.java | 1 - .../core/command/AuthCmdImplTest.java | 2 +- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/Node.java b/src/main/java/com/github/dockerjava/api/model/Node.java index 4fcf04e69..4bbeeec38 100644 --- a/src/main/java/com/github/dockerjava/api/model/Node.java +++ b/src/main/java/com/github/dockerjava/api/model/Node.java @@ -7,31 +7,31 @@ */ public class Node { - @JsonProperty("Name") - private String name; + @JsonProperty("Name") + private String name; - @JsonProperty("Id") - private String id; + @JsonProperty("Id") + private String id; - @JsonProperty("Addr") - private String addr; + @JsonProperty("Addr") + private String addr; - @JsonProperty("Ip") - private String ip; + @JsonProperty("Ip") + private String ip; - public String getName() { - return name; - } + public String getName() { + return name; + } - public String getId() { - return id; - } + public String getId() { + return id; + } - public String getAddr() { - return addr; - } + public String getAddr() { + return addr; + } - public String getIp() { - return ip; - } + public String getIp() { + return ip; + } } diff --git a/src/main/java/com/github/dockerjava/core/command/FrameReader.java b/src/main/java/com/github/dockerjava/core/command/FrameReader.java index a6db922db..bb5a5d17a 100644 --- a/src/main/java/com/github/dockerjava/core/command/FrameReader.java +++ b/src/main/java/com/github/dockerjava/core/command/FrameReader.java @@ -46,7 +46,6 @@ public Frame readFrame() throws IOException { if (rawStreamDetected) { - int read = inputStream.read(rawBuffer); return new Frame(StreamType.RAW, Arrays.copyOf(rawBuffer, read)); @@ -68,7 +67,7 @@ public Frame readFrame() throws IOException { StreamType streamType = streamType(header[0]); - if(streamType.equals(StreamType.RAW)) { + if (streamType.equals(StreamType.RAW)) { rawStreamDetected = true; return new Frame(StreamType.RAW, Arrays.copyOf(header, HEADER_SIZE)); } diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java index e96e5bcc6..7faca0370 100644 --- a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java +++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java @@ -181,7 +181,6 @@ public static void assertContainerHasVolumes(InspectContainerResponse inspectCon assertThat(volumes, contains(expectedVolumes)); } - public static class CollectFramesCallback extends ResultCallbackTemplate { public final List frames = new ArrayList(); diff --git a/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java index ba8c1dacb..180d835b6 100644 --- a/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java @@ -41,7 +41,7 @@ public void testAuth() throws Exception { } // Disabled because of 500/InternalServerException - @Test(enabled=false) + @Test(enabled = false) public void testAuthInvalid() throws Exception { try { From 4e9aa64c5ec34559f6dcdc13df623e5de065dfa0 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Sat, 11 Jul 2015 10:54:01 +0200 Subject: [PATCH 14/18] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab3c373e4..6cfb35ea0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Latest SNAPSHOT --- * [#263](https://github.com/docker-java/docker-java/pull/263) Refactoring of streaming commands APIs (event, stats, log, attach) +* [#262](https://github.com/docker-java/docker-java/pull/262) Accept filters in list containers * [#260](https://github.com/docker-java/docker-java/pull/260) Add labels to create and inspect container v.1.4.0 From f5f1b6615606542ce71e0da1f2c7c02a404a637a Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Sat, 11 Jul 2015 11:14:25 +0200 Subject: [PATCH 15/18] fix link to issue --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cfb35ea0..808cae3c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Latest SNAPSHOT v.1.4.0 --- -* [#248](https://github.com/docker-java/docker-java/pull/233) Removed deprecated start options +* [#248](https://github.com/docker-java/docker-java/pull/248) Removed deprecated start options * [#247](https://github.com/docker-java/docker-java/pull/247) Add Domainname attribute on create command * [#245](https://github.com/docker-java/docker-java/pull/245) Added ReadonlyRootfs option * [#233](https://github.com/docker-java/docker-java/pull/233) Labels are array of Strings (fixes #232) From c9cdda6ab1aef31d869594775844784775bce17e Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Sat, 11 Jul 2015 14:04:53 +0200 Subject: [PATCH 16/18] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 52d791923..5c6c55d31 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Java API client for [Docker](http://docs.docker.io/ "Docker") -Supports a subset of the Docker Remote API [v1.18](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.18.md), Docker Server version 1.6.x +Supports a subset of the Docker Remote API [v1.19](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.19.md), Docker Server version 1.7.x The current implementation is based on Jersey 2.x and therefore classpath incompatible with older Jersey 1.x dependent libraries! From e3a08471a86036552a311f9a1a521692f0c00601 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Tue, 7 Jul 2015 12:09:49 +0200 Subject: [PATCH 17/18] Add filters option to events operation --- .../dockerjava/api/command/EventsCmd.java | 5 +++ .../dockerjava/api/model/EventFilters.java | 37 +++++++++++++++++++ .../core/command/EventsCmdImpl.java | 20 +++++++++- .../dockerjava/jaxrs/EventsCmdExec.java | 7 ++++ .../core/command/EventsCmdImplTest.java | 20 ++++++++++ 5 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/github/dockerjava/api/model/EventFilters.java diff --git a/src/main/java/com/github/dockerjava/api/command/EventsCmd.java b/src/main/java/com/github/dockerjava/api/command/EventsCmd.java index 057bed644..e691bbc94 100644 --- a/src/main/java/com/github/dockerjava/api/command/EventsCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/EventsCmd.java @@ -1,6 +1,7 @@ package com.github.dockerjava.api.command; import com.github.dockerjava.api.model.Event; +import com.github.dockerjava.api.model.Filters; /** * Get events @@ -19,6 +20,10 @@ public interface EventsCmd extends AsyncDockerCmd { public String getUntil(); + public Filters getFilters(); + + public EventsCmd withFilters(Filters filters); + public static interface Exec extends DockerCmdExec { } } diff --git a/src/main/java/com/github/dockerjava/api/model/EventFilters.java b/src/main/java/com/github/dockerjava/api/model/EventFilters.java new file mode 100644 index 000000000..08cb7ad11 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/EventFilters.java @@ -0,0 +1,37 @@ +package com.github.dockerjava.api.model; + +import java.util.List; + +/** + * Representation of a Docker event filter. + * + * @author Carlos Sanchez + * + */ +public class EventFilters extends Filters { + + /** + * Default constructor for the deserialization. + */ + public EventFilters() { + } + + /** + * Constructor. + * + * @param event + * event to filter + */ + public EventFilters(String... event) { + super(); + withEvent(event); + } + + public Filters withEvent(String... event) { + return withFilter("event", event); + } + + public List getEvent() { + return getFilter("event"); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/EventsCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/EventsCmdImpl.java index d1de2e60f..50cf34ff3 100644 --- a/src/main/java/com/github/dockerjava/core/command/EventsCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/EventsCmdImpl.java @@ -1,8 +1,11 @@ package com.github.dockerjava.core.command; +import static com.google.common.base.Preconditions.*; + import com.github.dockerjava.api.async.ResultCallback; import com.github.dockerjava.api.command.EventsCmd; import com.github.dockerjava.api.model.Event; +import com.github.dockerjava.api.model.Filters; /** * Stream docker events @@ -13,6 +16,8 @@ public class EventsCmdImpl extends AbstrDockerCmd implements Ev private String until; + private Filters filters; + private ResultCallback resultCallback; public EventsCmdImpl(EventsCmd.Exec exec, ResultCallback resultCallback) { @@ -38,6 +43,13 @@ public EventsCmd withResultCallback(ResultCallback resultCallback) { return this; } + @Override + public EventsCmd withFilters(Filters filters) { + checkNotNull(filters, "filters have not been specified"); + this.filters = filters; + return this; + } + @Override public String getSince() { return since; @@ -53,9 +65,15 @@ public ResultCallback getResultCallback() { return resultCallback; } + @Override + public Filters getFilters() { + return filters; + } + @Override public String toString() { return new StringBuilder("events").append(since != null ? " --since=" + since : "") - .append(until != null ? " --until=" + until : "").toString(); + .append(until != null ? " --until=" + until : "") + .append(filters != null ? " --filters=" + filters : "").toString(); } } diff --git a/src/main/java/com/github/dockerjava/jaxrs/EventsCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/EventsCmdExec.java index e6f27ae69..0b3d998ac 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/EventsCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/EventsCmdExec.java @@ -1,5 +1,7 @@ package com.github.dockerjava.jaxrs; +import static com.google.common.net.UrlEscapers.*; + import javax.ws.rs.client.WebTarget; import org.slf4j.Logger; @@ -25,6 +27,11 @@ protected Void execute(EventsCmd command) { WebTarget webTarget = getBaseResource().path("/events").queryParam("since", command.getSince()) .queryParam("until", command.getUntil()); + if (command.getFilters() != null) { + webTarget = webTarget.queryParam("filters", + urlPathSegmentEscaper().escape(command.getFilters().toString())); + } + LOGGER.trace("GET: {}", webTarget); GETCallbackNotifier callbackNotifier = new GETCallbackNotifier(new JsonStreamProcessor( diff --git a/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java index eb490d7e9..7da6a100f 100644 --- a/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java @@ -18,6 +18,7 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.EventsCmd; import com.github.dockerjava.api.model.Event; +import com.github.dockerjava.api.model.EventFilters; import com.github.dockerjava.client.AbstractDockerClientTest; import com.github.dockerjava.core.async.ResultCallbackTemplate; @@ -94,6 +95,25 @@ public void testEventStreaming1() throws InterruptedException, IOException { assertTrue(zeroCount, "Received only: " + eventCallback.getEvents()); } + @Test + public void testEventStreamingWithFilter() throws InterruptedException, IOException { + // Don't include other tests events + TimeUnit.SECONDS.sleep(1); + + CountDownLatch countDownLatch = new CountDownLatch(1); + EventCallbackTest eventCallback = new EventCallbackTest(countDownLatch); + + EventsCmd eventsCmd = dockerClient.eventsCmd(eventCallback).withFilters(new EventFilters().withEvent("start")); + eventsCmd.exec(); + + generateEvents(); + + boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS); + + eventCallback.close(); + assertTrue(zeroCount, "Received only: " + eventCallback.getEvents()); + } + @Test public void testEventStreaming2() throws InterruptedException, IOException { // Don't include other tests events From 87e9c19729a7267f45b2856e6c9c1c861418ba81 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Tue, 7 Jul 2015 12:10:15 +0200 Subject: [PATCH 18/18] Ensure errors in callback are processed and logged --- .../dockerjava/core/async/ResultCallbackTemplate.java | 6 ++++++ .../dockerjava/jaxrs/async/AbstractCallbackNotifier.java | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java b/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java index 50cc1fd91..94d199a6f 100644 --- a/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java +++ b/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java @@ -8,6 +8,9 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.github.dockerjava.api.async.ResultCallback; /** @@ -18,6 +21,8 @@ */ public abstract class ResultCallbackTemplate implements ResultCallback { + private final static Logger LOGGER = LoggerFactory.getLogger(ResultCallbackTemplate.class); + private final CountDownLatch finished = new CountDownLatch(1); private Closeable stream; @@ -34,6 +39,7 @@ public void onNext(T object) { @Override public void onError(Throwable throwable) { try { + LOGGER.error("Error during callback", throwable); throw new RuntimeException(throwable); } finally { try { diff --git a/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java b/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java index 6cfc7a76e..a010a87ad 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java +++ b/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java @@ -48,6 +48,11 @@ public Void call() throws Exception { resultCallback.onError(e.getCause()); } return null; + } catch (Exception e) { + if (resultCallback != null) { + resultCallback.onError(e); + } + return null; } try {