Skip to content

Commit eb5db45

Browse files
committed
Merge pull request #75 from albers/exposed-port
Use ExposedPort.toString() in serialization
2 parents 51429d2 + 8e31899 commit eb5db45

File tree

4 files changed

+108
-10
lines changed

4 files changed

+108
-10
lines changed

src/main/java/com/github/dockerjava/api/model/ExposedPort.java

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,38 @@
1818
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
1919
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
2020
import com.fasterxml.jackson.databind.node.NullNode;
21-
21+
import com.github.dockerjava.api.model.Ports.Binding;
22+
23+
/**
24+
* Represents a container port that Docker exposes to external clients.
25+
* The port is defined by its {@link #getPort() port number} and a
26+
* {@link #getScheme() scheme}, e.g. <code>tcp</code>.
27+
* It can be published by Docker by {@link Ports#bind(ExposedPort, Binding) binding}
28+
* it to a host port, represented by a {@link Binding}.
29+
*/
2230
@JsonDeserialize(using = ExposedPort.Deserializer.class)
2331
@JsonSerialize(using = ExposedPort.Serializer.class)
2432
public class ExposedPort {
2533

26-
private String scheme;
34+
private final String scheme;
2735

28-
private int port;
36+
private final int port;
2937

38+
/**
39+
* Creates an {@link ExposedPort} for the given parameters.
40+
*
41+
* @param scheme the {@link #getScheme() scheme}, <code>tcp</code> or
42+
* <code>udp</code>
43+
* @param port the {@link #getPort() port number}
44+
*/
3045
public ExposedPort(String scheme, int port) {
3146
this.scheme = scheme;
3247
this.port = port;
3348
}
3449

50+
/**
51+
* @return the scheme (IP protocol), <code>tcp</code> or <code>udp</code>
52+
*/
3553
public String getScheme() {
3654
return scheme;
3755
}
@@ -40,27 +58,50 @@ public int getPort() {
4058
return port;
4159
}
4260

61+
/**
62+
* Creates an {@link ExposedPort} for the TCP scheme.
63+
* This is a shortcut for <code>new ExposedPort("tcp", port)</code>
64+
*/
4365
public static ExposedPort tcp(int port) {
4466
return new ExposedPort("tcp", port);
4567
}
4668

69+
/**
70+
* Creates an {@link ExposedPort} for the UDP scheme.
71+
* This is a shortcut for <code>new ExposedPort("udp", port)</code>
72+
*/
4773
public static ExposedPort udp(int port) {
4874
return new ExposedPort("udp", port);
4975
}
5076

51-
public static ExposedPort parse(String serialized) {
77+
/**
78+
* Parses a textual port specification (as used by the Docker CLI) to an
79+
* {@link ExposedPort}.
80+
*
81+
* @param serialized the specification, e.g. <code>80/tcp</code>
82+
* @return an {@link ExposedPort} matching the specification
83+
* @throws IllegalArgumentException if the specification cannot be parsed
84+
*/
85+
public static ExposedPort parse(String serialized) throws IllegalArgumentException {
5286
try {
5387
String[] parts = serialized.split("/");
5488
ExposedPort out = new ExposedPort(parts[1], Integer.valueOf(parts[0]));
5589
return out;
5690
} catch (Exception e) {
57-
throw new RuntimeException("Error parsing ExposedPort '" + serialized + "'");
91+
throw new IllegalArgumentException("Error parsing ExposedPort '" + serialized + "'");
5892
}
5993
}
6094

95+
/**
96+
* Returns a string representation of this {@link ExposedPort} suitable
97+
* for inclusion in a JSON message.
98+
* The format is <code>port/scheme</code>, like the argument in {@link #parse(String)}.
99+
*
100+
* @return a string representation of this {@link ExposedPort}
101+
*/
61102
@Override
62103
public String toString() {
63-
return getPort() + "/" + getScheme();
104+
return port + "/" + scheme;
64105
}
65106

66107
@Override

src/main/java/com/github/dockerjava/api/model/ExposedPorts.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ public void serialize(ExposedPorts exposedPorts, JsonGenerator jsonGen,
4343

4444
jsonGen.writeStartObject();
4545
for (ExposedPort exposedPort : exposedPorts.getExposedPorts()) {
46-
jsonGen.writeFieldName(exposedPort.getPort() + "/"
47-
+ exposedPort.getScheme());
46+
jsonGen.writeFieldName(exposedPort.toString());
4847
jsonGen.writeStartObject();
4948
jsonGen.writeEndObject();
5049
}

src/main/java/com/github/dockerjava/api/model/Ports.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,18 @@
2020
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
2121
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
2222
import com.fasterxml.jackson.databind.node.NullNode;
23+
import com.github.dockerjava.api.command.InspectContainerResponse.HostConfig;
24+
import com.github.dockerjava.api.command.InspectContainerResponse.NetworkSettings;
25+
2326
import org.apache.commons.lang.builder.ToStringBuilder;
2427

28+
/**
29+
* A container for port bindings, made available as a {@link Map} via its
30+
* {@link #getBindings()} method.
31+
*
32+
* @see HostConfig#getPortBindings()
33+
* @see NetworkSettings#getPorts()
34+
*/
2535
@JsonDeserialize(using = Ports.Deserializer.class)
2636
@JsonSerialize(using = Ports.Serializer.class)
2737
public class Ports {
@@ -43,6 +53,10 @@ public String toString(){
4353
return ports.toString();
4454
}
4555

56+
/**
57+
* @return the port bindings as a {@link Map} that contains one
58+
* {@link Binding} per {@link ExposedPort}.
59+
*/
4660
public Map<ExposedPort, Binding> getBindings(){
4761
return ports;
4862
}
@@ -55,13 +69,25 @@ public static Binding Binding(int hostPort) {
5569
}
5670

5771

72+
/**
73+
* The host part of a port binding.
74+
* In a port binding a container port, expressed as an {@link ExposedPort},
75+
* is published as a port of the Docker host.
76+
*
77+
* @see ExposedPort
78+
*/
5879
public static class Binding {
5980

60-
6181
private final String hostIp;
6282

6383
private final int hostPort;
6484

85+
/**
86+
* Creates the host part of a port binding.
87+
*
88+
* @see Ports#bind(ExposedPort, Binding)
89+
* @see ExposedPort
90+
*/
6591
public Binding(String hostIp, int hostPort) {
6692
this.hostIp = hostIp;
6793
this.hostPort = hostPort;
@@ -125,7 +151,7 @@ public void serialize(Ports portBindings, JsonGenerator jsonGen,
125151

126152
jsonGen.writeStartObject();
127153
for(Entry<ExposedPort, Binding> entry : portBindings.getBindings().entrySet()){
128-
jsonGen.writeFieldName(entry.getKey().getPort() + "/" + entry.getKey().getScheme());
154+
jsonGen.writeFieldName(entry.getKey().toString());
129155
jsonGen.writeStartArray();
130156
jsonGen.writeStartObject();
131157
jsonGen.writeStringField("HostIp", entry.getValue().getHostIp());
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.github.dockerjava.api.model;
2+
3+
import static org.testng.Assert.assertEquals;
4+
5+
import org.testng.annotations.Test;
6+
7+
public class ExposedPortTest {
8+
9+
@Test
10+
public void parse() {
11+
ExposedPort exposedPort = ExposedPort.parse("80/tcp");
12+
assertEquals(exposedPort.getPort(), 80);
13+
}
14+
15+
@Test(expectedExceptions = IllegalArgumentException.class,
16+
expectedExceptionsMessageRegExp = "Error parsing ExposedPort 'nonsense'")
17+
public void parseInvalidInput() {
18+
ExposedPort.parse("nonsense");
19+
}
20+
21+
@Test(expectedExceptions = IllegalArgumentException.class,
22+
expectedExceptionsMessageRegExp = "Error parsing ExposedPort 'null'")
23+
public void parseNull() {
24+
ExposedPort.parse(null);
25+
}
26+
27+
@Test
28+
public void stringify() {
29+
assertEquals(ExposedPort.parse("80/tcp").toString(), "80/tcp");
30+
}
31+
32+
}

0 commit comments

Comments
 (0)