diff --git a/CHANGELOG.md b/CHANGELOG.md
index b76a052d8..808cae3c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,16 @@
Change Log
===
+
Latest SNAPSHOT
---
-* [#248](https://github.com/docker-java/docker-java/pull/233) Removed deprecated start options
+
+* [#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
+---
+* [#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)
diff --git a/README.md b/README.md
index a4c18a0ce..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!
@@ -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
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..9ad44b2c4 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;
@@ -41,6 +43,26 @@ public static interface Exec extends DockerCmdExec labels);
+
/**
* Add link to another container.
*/
@@ -238,4 +282,9 @@ public static interface Exec extends DockerCmdExec getLabels();
+
}
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/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/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/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/api/model/Event.java b/src/main/java/com/github/dockerjava/api/model/Event.java
index 27eb22216..14637d6e7 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.
*/
@@ -22,7 +27,7 @@ public Event() {
/**
* Constructor.
- *
+ *
* @param id
* Container ID
* @param status
@@ -46,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() {
@@ -55,7 +60,7 @@ public String getStatus() {
/**
* Get ID of docker container.
- *
+ *
* @return Container ID
*/
public String getId() {
@@ -64,7 +69,7 @@ public String getId() {
/**
* Get source image of the container.
- *
+ *
* @return Name of the parent container
*/
public String getFrom() {
@@ -73,13 +78,20 @@ 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;
+ }
+
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
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/api/model/Filters.java b/src/main/java/com/github/dockerjava/api/model/Filters.java
new file mode 100644
index 000000000..b912b541a
--- /dev/null
+++ b/src/main/java/com/github/dockerjava/api/model/Filters.java
@@ -0,0 +1,103 @@
+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;
+
+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() {
+ }
+
+ public Filters withFilter(String key, String... value) {
+ filters.put(key, Arrays.asList(value));
+ return this;
+ }
+
+ public List getFilter(String key) {
+ return filters.get(key);
+ }
+
+ public Filters withImages(String... image) {
+ withFilter("image", image);
+ return this;
+ }
+
+ public List getImage() {
+ return getFilter("image");
+ }
+
+ public Filters withContainers(String... container) {
+ withFilter("container", container);
+ return this;
+ }
+
+ public List getContainer() {
+ return getFilter("container");
+ }
+
+ /**
+ * Filter by labels
+ *
+ * @param labels
+ * string array in the form ["key"] or ["key=value"] or a mix of both
+ * @return
+ */
+ 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 {
+ return OBJECT_MAPPER.writeValueAsString(filters);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
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..4bbeeec38
--- /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;
+ }
+}
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..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,15 +8,20 @@
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;
/**
- * 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 static Logger LOGGER = LoggerFactory.getLogger(ResultCallbackTemplate.class);
private final CountDownLatch finished = new CountDownLatch(1);
@@ -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/core/command/CreateContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java
index cc082b61f..32835b301 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;
@@ -53,6 +55,9 @@ public class CreateContainerCmdImpl extends AbstrDockerCmd labels;
+
+ @JsonProperty("CpusetMems")
+ private String cpusetMems;
+
+ @JsonProperty("BlkioWeight")
+ private Integer blkioWeight;
+
+ @JsonProperty("OomKillDisable")
+ private Boolean oomKillDisable;
+
public CreateContainerCmdImpl(CreateContainerCmd.Exec exec, String image) {
super(exec);
checkNotNull(image, "image was not specified");
@@ -155,6 +172,26 @@ public int getCpuShares() {
return cpuShares;
}
+ @Override
+ public Integer getCpuPeriod() {
+ return cpuPeriod;
+ }
+
+ @Override
+ public String getCpusetMems() {
+ return cpusetMems;
+ }
+
+ @Override
+ public Integer getBlkioWeight() {
+ return blkioWeight;
+ }
+
+ @Override
+ public Boolean isOomKillDisable() {
+ return oomKillDisable;
+ }
+
@Override
@JsonIgnore
public Device[] getDevices() {
@@ -221,6 +258,12 @@ public Link[] getLinks() {
return hostConfig.getLinks();
}
+ @Override
+ @JsonIgnore
+ public Map getLabels() {
+ return labels;
+ }
+
@Override
@JsonIgnore
public LxcConf[] getLxcConf() {
@@ -398,6 +441,30 @@ public CreateContainerCmdImpl withCpuShares(int cpuShares) {
return this;
}
+ @Override
+ public CreateContainerCmd withCpuPeriod(Integer cpuPeriod) {
+ this.cpuPeriod = cpuPeriod;
+ return this;
+ }
+
+ @Override
+ public CreateContainerCmd withCpusetMems(String cpusetMems) {
+ this.cpusetMems = cpusetMems;
+ return null;
+ }
+
+ @Override
+ public CreateContainerCmd withBlkioWeight(Integer blkioWeight) {
+ this.blkioWeight = blkioWeight;
+ return null;
+ }
+
+ @Override
+ public CreateContainerCmd withOomKillDisable(Boolean oomKillDisable) {
+ this.oomKillDisable = oomKillDisable;
+ return null;
+ }
+
@Override
public CreateContainerCmd withDevices(Device... devices) {
this.hostConfig.setDevices(devices);
@@ -471,6 +538,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/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/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/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java
index 13bb02cfb..b957a3bd6 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 callbackNotifier = new GETCallbackNotifier(new JsonStreamProcessor(
diff --git a/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java
index 5bb905b56..5feb5bdac 100644
--- a/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java
+++ b/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java
@@ -1,5 +1,7 @@
package com.github.dockerjava.jaxrs;
+import static com.google.common.net.UrlEscapers.*;
+
import java.util.List;
import javax.ws.rs.client.WebTarget;
@@ -32,6 +34,11 @@ protected List 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/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 {
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 {
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 1b372d245..9876e43d5 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;
@@ -488,4 +490,24 @@ public void createContainerWithULimits() throws DockerException {
}
+ @Test(groups = "ignoreInCircleCi")
+ 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)));
+ }
}
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
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..2f052f841 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;
@@ -26,7 +27,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 {
@@ -51,7 +54,6 @@ public void afterMethod(ITestResult result) {
super.afterMethod(result);
}
- @Test
public void testListContainers() throws DockerException {
String testImage = "busybox";
@@ -96,7 +98,74 @@ 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));
+ }
+
+ @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(labels).exec();
+ filteredContainers = dockerClient.listContainersCmd().withShowAll(true)
+ .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().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);
}
}