From 8e31899b8543a051ef938cce5b500aacb043fe4b Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Wed, 15 Oct 2014 19:05:19 +0200 Subject: [PATCH] Use ExposedPort.toString() in serialization Changed type of parsing exception, added test and javadoc. --- .../dockerjava/api/model/ExposedPort.java | 53 ++++++++++++++++--- .../dockerjava/api/model/ExposedPorts.java | 3 +- .../github/dockerjava/api/model/Ports.java | 30 ++++++++++- .../dockerjava/api/model/ExposedPortTest.java | 32 +++++++++++ 4 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 src/test/java/com/github/dockerjava/api/model/ExposedPortTest.java diff --git a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java index 875a571a8..d085f6c4f 100644 --- a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java +++ b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java @@ -18,20 +18,38 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.node.NullNode; - +import com.github.dockerjava.api.model.Ports.Binding; + +/** + * Represents a container port that Docker exposes to external clients. + * The port is defined by its {@link #getPort() port number} and a + * {@link #getScheme() scheme}, e.g. tcp. + * It can be published by Docker by {@link Ports#bind(ExposedPort, Binding) binding} + * it to a host port, represented by a {@link Binding}. + */ @JsonDeserialize(using = ExposedPort.Deserializer.class) @JsonSerialize(using = ExposedPort.Serializer.class) public class ExposedPort { - private String scheme; + private final String scheme; - private int port; + private final int port; + /** + * Creates an {@link ExposedPort} for the given parameters. + * + * @param scheme the {@link #getScheme() scheme}, tcp or + * udp + * @param port the {@link #getPort() port number} + */ public ExposedPort(String scheme, int port) { this.scheme = scheme; this.port = port; } + /** + * @return the scheme (IP protocol), tcp or udp + */ public String getScheme() { return scheme; } @@ -40,27 +58,50 @@ public int getPort() { return port; } + /** + * Creates an {@link ExposedPort} for the TCP scheme. + * This is a shortcut for new ExposedPort("tcp", port) + */ public static ExposedPort tcp(int port) { return new ExposedPort("tcp", port); } + /** + * Creates an {@link ExposedPort} for the UDP scheme. + * This is a shortcut for new ExposedPort("udp", port) + */ public static ExposedPort udp(int port) { return new ExposedPort("udp", port); } - public static ExposedPort parse(String serialized) { + /** + * Parses a textual port specification (as used by the Docker CLI) to an + * {@link ExposedPort}. + * + * @param serialized the specification, e.g. 80/tcp + * @return an {@link ExposedPort} matching the specification + * @throws IllegalArgumentException if the specification cannot be parsed + */ + public static ExposedPort parse(String serialized) throws IllegalArgumentException { try { String[] parts = serialized.split("/"); ExposedPort out = new ExposedPort(parts[1], Integer.valueOf(parts[0])); return out; } catch (Exception e) { - throw new RuntimeException("Error parsing ExposedPort '" + serialized + "'"); + throw new IllegalArgumentException("Error parsing ExposedPort '" + serialized + "'"); } } + /** + * Returns a string representation of this {@link ExposedPort} suitable + * for inclusion in a JSON message. + * The format is port/scheme, like the argument in {@link #parse(String)}. + * + * @return a string representation of this {@link ExposedPort} + */ @Override public String toString() { - return getPort() + "/" + getScheme(); + return port + "/" + scheme; } @Override diff --git a/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java b/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java index c9e15758c..924d1300e 100644 --- a/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java +++ b/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java @@ -43,8 +43,7 @@ public void serialize(ExposedPorts exposedPorts, JsonGenerator jsonGen, jsonGen.writeStartObject(); for (ExposedPort exposedPort : exposedPorts.getExposedPorts()) { - jsonGen.writeFieldName(exposedPort.getPort() + "/" - + exposedPort.getScheme()); + jsonGen.writeFieldName(exposedPort.toString()); jsonGen.writeStartObject(); jsonGen.writeEndObject(); } diff --git a/src/main/java/com/github/dockerjava/api/model/Ports.java b/src/main/java/com/github/dockerjava/api/model/Ports.java index 5a182c044..fe7904689 100644 --- a/src/main/java/com/github/dockerjava/api/model/Ports.java +++ b/src/main/java/com/github/dockerjava/api/model/Ports.java @@ -20,8 +20,18 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.node.NullNode; +import com.github.dockerjava.api.command.InspectContainerResponse.HostConfig; +import com.github.dockerjava.api.command.InspectContainerResponse.NetworkSettings; + import org.apache.commons.lang.builder.ToStringBuilder; +/** + * A container for port bindings, made available as a {@link Map} via its + * {@link #getBindings()} method. + * + * @see HostConfig#getPortBindings() + * @see NetworkSettings#getPorts() + */ @JsonDeserialize(using = Ports.Deserializer.class) @JsonSerialize(using = Ports.Serializer.class) public class Ports { @@ -43,6 +53,10 @@ public String toString(){ return ports.toString(); } + /** + * @return the port bindings as a {@link Map} that contains one + * {@link Binding} per {@link ExposedPort}. + */ public Map getBindings(){ return ports; } @@ -55,13 +69,25 @@ public static Binding Binding(int hostPort) { } + /** + * The host part of a port binding. + * In a port binding a container port, expressed as an {@link ExposedPort}, + * is published as a port of the Docker host. + * + * @see ExposedPort + */ public static class Binding { - private final String hostIp; private final int hostPort; + /** + * Creates the host part of a port binding. + * + * @see Ports#bind(ExposedPort, Binding) + * @see ExposedPort + */ public Binding(String hostIp, int hostPort) { this.hostIp = hostIp; this.hostPort = hostPort; @@ -125,7 +151,7 @@ public void serialize(Ports portBindings, JsonGenerator jsonGen, jsonGen.writeStartObject(); for(Entry entry : portBindings.getBindings().entrySet()){ - jsonGen.writeFieldName(entry.getKey().getPort() + "/" + entry.getKey().getScheme()); + jsonGen.writeFieldName(entry.getKey().toString()); jsonGen.writeStartArray(); jsonGen.writeStartObject(); jsonGen.writeStringField("HostIp", entry.getValue().getHostIp()); diff --git a/src/test/java/com/github/dockerjava/api/model/ExposedPortTest.java b/src/test/java/com/github/dockerjava/api/model/ExposedPortTest.java new file mode 100644 index 000000000..052e44ff8 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/ExposedPortTest.java @@ -0,0 +1,32 @@ +package com.github.dockerjava.api.model; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +public class ExposedPortTest { + + @Test + public void parse() { + ExposedPort exposedPort = ExposedPort.parse("80/tcp"); + assertEquals(exposedPort.getPort(), 80); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing ExposedPort 'nonsense'") + public void parseInvalidInput() { + ExposedPort.parse("nonsense"); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing ExposedPort 'null'") + public void parseNull() { + ExposedPort.parse(null); + } + + @Test + public void stringify() { + assertEquals(ExposedPort.parse("80/tcp").toString(), "80/tcp"); + } + +}