Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Parser for PortBinding and Binding
This allows you to use textual port binding specifications in the format
used by the Docker CLI in docker-java:

StartContainerCmd.withPortBindings(PortBinding.parse("80:8080/tcp"));
  • Loading branch information
albers committed Oct 31, 2014
commit 0ee67be7ac04bc50ce858e9525462e4a9bc5aa34
47 changes: 47 additions & 0 deletions src/main/java/com/github/dockerjava/api/model/PortBinding.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.github.dockerjava.api.model;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

import com.github.dockerjava.api.command.InspectContainerResponse.HostConfig;
import com.github.dockerjava.api.command.InspectContainerResponse.NetworkSettings;
import com.github.dockerjava.api.model.Ports.Binding;
Expand Down Expand Up @@ -33,4 +37,47 @@ public Binding getBinding() {
public ExposedPort getExposedPort() {
return exposedPort;
}

public static PortBinding parse(String serialized) throws IllegalArgumentException {
try {
String[] parts = StringUtils.splitByWholeSeparator(serialized, ":");
switch (parts.length) {
case 3:
// 127.0.0.1:80:8080/tcp
return createFromSubstrings(parts[0] + ":" + parts[1], parts[2]);
case 2:
// 80:8080 // 127.0.0.1::8080
return createFromSubstrings(parts[0], parts[1]);
case 1:
// 8080
return createFromSubstrings("", parts[0]);
default:
throw new IllegalArgumentException();
}
} catch (Exception e) {
throw new IllegalArgumentException("Error parsing PortBinding '"
+ serialized + "'", e);
}
}

private static PortBinding createFromSubstrings(String binding, String exposedPort)
throws IllegalArgumentException {
return new PortBinding(Binding.parse(binding), ExposedPort.parse(exposedPort));
}

@Override
public boolean equals(Object obj) {
if (obj instanceof PortBinding) {
PortBinding other = (PortBinding) obj;
return new EqualsBuilder().append(binding, other.getBinding())
.append(exposedPort, other.getExposedPort()).isEquals();
} else
return super.equals(obj);
}

@Override
public int hashCode() {
return new HashCodeBuilder().append(binding).append(exposedPort).toHashCode();
}

}
47 changes: 45 additions & 2 deletions src/main/java/com/github/dockerjava/api/model/Ports.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.github.dockerjava.api.model;

import static org.apache.commons.lang.StringUtils.isEmpty;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
Expand All @@ -8,7 +10,6 @@

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
Expand Down Expand Up @@ -152,9 +153,51 @@ public int getHostPort() {
return hostPort;
}

/**
* Parses a textual host and port specification (as used by the Docker CLI)
* to a {@link Binding}.
* <p>
* Legal syntax: <code>[IP:]Port</code>
*
* @param serialized serialized the specification, e.g.
* <code>127.0.0.1:80</code>
* @return a {@link Binding} matching the specification
* @throws IllegalArgumentException if the specification cannot be parsed
*/
public static Binding parse(String serialized) throws IllegalArgumentException {
try {
String[] parts = serialized.split(":");
switch (parts.length) {
case 2: {
return new Binding(parts[0], Integer.valueOf(parts[1]));
}
case 1: {
return new Binding(Integer.valueOf(parts[0]));
}
default: {
throw new IllegalArgumentException();
}
}
} catch (Exception e) {
throw new IllegalArgumentException("Error parsing Binding '"
+ serialized + "'");
}
}

/**
* Returns a string representation of this {@link Binding} suitable
* for inclusion in a JSON message.
* The format is <code>[IP:]Port</code>, like the argument in {@link #parse(String)}.
*
* @return a string representation of this {@link Binding}
*/
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
if (isEmpty(hostIp)) {
return Integer.toString(hostPort);
} else {
return hostIp + ":" + hostPort;
}
}

@Override
Expand Down
43 changes: 43 additions & 0 deletions src/test/java/com/github/dockerjava/api/model/BindingTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.github.dockerjava.api.model;

import static org.testng.Assert.assertEquals;

import org.testng.annotations.Test;

import com.github.dockerjava.api.model.Ports.Binding;

public class BindingTest {

@Test
public void parseIpAndPort() {
assertEquals(Binding.parse("127.0.0.1:80"), Ports.Binding("127.0.0.1", 80));
}

@Test
public void parsePortOnly() {
assertEquals(Binding.parse("80"), Ports.Binding("", 80));
}

@Test(expectedExceptions = IllegalArgumentException.class,
expectedExceptionsMessageRegExp = "Error parsing Binding 'nonsense'")
public void parseInvalidInput() {
Binding.parse("nonsense");
}

@Test(expectedExceptions = IllegalArgumentException.class,
expectedExceptionsMessageRegExp = "Error parsing Binding 'null'")
public void parseNull() {
Binding.parse(null);
}

@Test
public void toStringIpAndHost() {
assertEquals(Binding.parse("127.0.0.1:80").toString(), "127.0.0.1:80");
}

@Test
public void toStringPortOnly() {
assertEquals(Binding.parse("80").toString(), "80");
}

}
49 changes: 49 additions & 0 deletions src/test/java/com/github/dockerjava/api/model/PortBindingTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.github.dockerjava.api.model;

import static org.testng.Assert.assertEquals;

import org.testng.annotations.Test;

import com.github.dockerjava.api.model.Ports.Binding;

public class PortBindingTest {

private static final ExposedPort TCP_8080 = ExposedPort.tcp(8080);

@Test
public void fullDefinition() {
assertEquals(PortBinding.parse("127.0.0.1:80:8080/tcp"),
new PortBinding(new Binding("127.0.0.1", 80), TCP_8080));
}

@Test
public void noProtocol() {
assertEquals(PortBinding.parse("127.0.0.1:80:8080"),
new PortBinding(new Binding("127.0.0.1", 80), TCP_8080));
}

@Test
public void noHostIp() {
assertEquals(PortBinding.parse("80:8080/tcp"),
new PortBinding(new Binding(80), TCP_8080));
}

@Test
public void portsOnly() {
assertEquals(PortBinding.parse("80:8080"),
new PortBinding(new Binding(80), TCP_8080));
}

@Test(expectedExceptions = IllegalArgumentException.class,
expectedExceptionsMessageRegExp = "Error parsing PortBinding 'nonsense'")
public void parseInvalidInput() {
PortBinding.parse("nonsense");
}

@Test(expectedExceptions = IllegalArgumentException.class,
expectedExceptionsMessageRegExp = "Error parsing PortBinding 'null'")
public void parseNull() {
PortBinding.parse(null);
}

}