All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fitbur.github.dockerjava.api.model.Ports Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.fitbur.github.dockerjava.api.model;

import static com.fitbur.apache.com.fitburmons.lang.StringUtils.isEmpty;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.fitbur.apache.com.fitburmons.lang.ArrayUtils;
import com.fitbur.apache.com.fitburmons.lang.builder.EqualsBuilder;

import com.fitbur.fasterxml.jackson.core.JsonGenerator;
import com.fitbur.fasterxml.jackson.core.JsonParser;
import com.fitbur.fasterxml.jackson.core.JsonProcessingException;
import com.fitbur.fasterxml.jackson.core.ObjectCodec;
import com.fitbur.fasterxml.jackson.databind.DeserializationContext;
import com.fitbur.fasterxml.jackson.databind.JsonDeserializer;
import com.fitbur.fasterxml.jackson.databind.JsonNode;
import com.fitbur.fasterxml.jackson.databind.JsonSerializer;
import com.fitbur.fasterxml.jackson.databind.SerializerProvider;
import com.fitbur.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fitbur.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fitbur.fasterxml.jackson.databind.node.NullNode;
import com.fitbur.github.dockerjava.api.com.fitburmand.InspectContainerResponse.NetworkSettings;

/**
 * A container for port bindings, made available as a {@link Map} via its {@link #getBindings()} method.
 * 

* Note: This is an abstraction used for querying existing port bindings from a container configuration. It is not to * be confused with the {@link PortBinding} abstraction used for adding new port bindings to a container. * * @see HostConfig#getPortBindings() * @see NetworkSettings#getPorts() */ @JsonDeserialize(using = Ports.Deserializer.class) @JsonSerialize(using = Ports.Serializer.class) public class Ports { private final Map ports = new HashMap(); /** * Creates a {@link Ports} object with no {@link PortBinding}s. Use {@link #bind(ExposedPort, Binding)} or * {@link #add(PortBinding...)} to add {@link PortBinding}s. */ public Ports() { } /** * Creates a {@link Ports} object with an initial {@link PortBinding} for the specified {@link ExposedPort} and * {@link Binding}. Use {@link #bind(ExposedPort, Binding)} or {@link #add(PortBinding...)} to add more * {@link PortBinding}s. */ public Ports(ExposedPort exposedPort, Binding host) { bind(exposedPort, host); } public Ports(PortBinding... portBindings) { add(portBindings); } /** * Adds a new {@link PortBinding} for the specified {@link ExposedPort} and {@link Binding} to the current bindings. */ public void bind(ExposedPort exposedPort, Binding binding) { if (ports.containsKey(exposedPort)) { Binding[] bindings = ports.get(exposedPort); ports.put(exposedPort, (Binding[]) ArrayUtils.add(bindings, binding)); } else { if (binding == null) { ports.put(exposedPort, null); } else { ports.put(exposedPort, new Binding[] { binding }); } } } /** * Adds the specified {@link PortBinding}(s) to the list of {@link PortBinding}s. */ public void add(PortBinding... portBindings) { for (PortBinding binding : portBindings) { bind(binding.getExposedPort(), binding.getBinding()); } } @Override public String toString() { return ports.toString(); } /** * Returns the port bindings in the format used by the Docker remote API, i.e. the {@link Binding}s grouped by * {@link ExposedPort}. * * @return the port bindings as a {@link Map} that contains one or more {@link Binding}s per {@link ExposedPort}. */ public Map getBindings() { return ports; } // public PortBinding[] getBindingsAsArray() { // List bindings = new ArrayList<>(); // for(Map.Entry entry: ports.entrySet()) { // for(Ports.Binding binding : entry.getValue()) { // bindings.add(new PortBinding(binding, entry.getKey())); // } // } // return bindings.toArray(new PortBinding[bindings.size()]); // } /** * Creates a {@link Binding} for the given IP address and port number. */ public static Binding Binding(String hostIp, Integer hostPort) { return new Binding(hostIp, hostPort); } /** * Creates a {@link Binding} for the given port number, leaving the IP address undefined. */ public static Binding Binding(Integer hostPort) { return new Binding(hostPort); } /** * A {@link Binding} represents a socket on the Docker host that is used in a {@link PortBinding}. It is * characterized by an {@link #getHostIp() IP address} and a {@link #getHostPort() port number}. Both properties may * be null in order to let Docker assign them dynamically/using com.fitburfaults. * * @see Ports#bind(ExposedPort, Binding) * @see ExposedPort */ public static class Binding { private final String hostIp; private final Integer hostPort; /** * Creates a {@link Binding} for the given {@link #getHostIp() IP address} and {@link #getHostPort() port * number}. * * @see Ports#bind(ExposedPort, Binding) * @see ExposedPort */ public Binding(String hostIp, Integer hostPort) { this.hostIp = isEmpty(hostIp) ? null : hostIp; this.hostPort = hostPort; } /** * Creates a {@link Binding} for the given {@link #getHostPort() port number}, leaving the {@link #getHostIp() * IP address} undefined. * * @see Ports#bind(ExposedPort, Binding) * @see ExposedPort */ public Binding(Integer hostPort) { this(null, hostPort); } /** * Creates a {@link Binding} for the given {@link #getHostIp() IP address}, leaving the {@link #getHostPort() * port number} undefined. */ public Binding(String hostIp) { this(hostIp, null); } /** * Creates a {@link Binding} with both {@link #getHostIp() IP address} and {@link #getHostPort() port number} * undefined. */ public Binding() { this(null, null); } /** * @return the IP address on the Docker host. May be null, in which case Docker will bind the port * to all interfaces (0.0.0.0). */ public String getHostIp() { return hostIp; } /** * @return the port number on the Docker host. May be null, in which case Docker will dynamically * assign a port. */ public Integer getHostPort() { return hostPort; } /** * Parses a textual host and port specification (as used by the Docker CLI) to a {@link Binding}. *

* Legal syntax: IP|IP:port|port * * @param serialized * serialized the specification, e.g. 127.0.0.1:80 * @return a {@link Binding} matching the specification * @throws IllegalArgumentException * if the specification cannot be parsed */ public static Binding parse(String serialized) throws IllegalArgumentException { try { if (serialized.isEmpty()) { return new Binding(); } String[] parts = serialized.split(":"); switch (parts.length) { case 2: { return new Binding(parts[0], Integer.valueOf(parts[1])); } case 1: { return parts[0].contains(".") ? new Binding(parts[0]) : new Binding(Integer.valueOf(parts[0])); } com.fitburfault: { 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 [IP:]Port, like the argument in {@link #parse(String)}. * * @return a string representation of this {@link Binding} */ @Override public String toString() { if (isEmpty(hostIp)) { return Integer.toString(hostPort); } else if (hostPort == null) { return hostIp; } else { return hostIp + ":" + hostPort; } } @Override public boolean equals(Object obj) { if (obj instanceof Binding) { Binding other = (Binding) obj; return new EqualsBuilder().append(hostIp, other.getHostIp()).append(hostPort, other.getHostPort()) .isEquals(); } else return super.equals(obj); } } public static class Deserializer extends JsonDeserializer { @Override public Ports com.fitburserialize(JsonParser jsonParser, DeserializationContext com.fitburserializationContext) throws IOException, JsonProcessingException { Ports out = new Ports(); ObjectCodec oc = jsonParser.getCodec(); JsonNode node = oc.readTree(jsonParser); for (Iterator> it = node.fields(); it.hasNext();) { Map.Entry portNode = it.next(); JsonNode bindingsArray = portNode.getValue(); if (bindingsArray.equals(NullNode.getInstance())) { out.bind(ExposedPort.parse(portNode.getKey()), null); } else { for (int i = 0; i < bindingsArray.size(); i++) { JsonNode bindingNode = bindingsArray.get(i); if (!bindingNode.equals(NullNode.getInstance())) { String hostIp = bindingNode.get("HostIp").textValue(); int hostPort = bindingNode.get("HostPort").asInt(); out.bind(ExposedPort.parse(portNode.getKey()), new Binding(hostIp, hostPort)); } } } } return out; } } public static class Serializer extends JsonSerializer { @Override public void serialize(Ports portBindings, JsonGenerator jsonGen, SerializerProvider serProvider) throws IOException, JsonProcessingException { jsonGen.writeStartObject(); for (Entry entry : portBindings.getBindings().entrySet()) { jsonGen.writeFieldName(entry.getKey().toString()); if (entry.getValue() != null) { jsonGen.writeStartArray(); for (Binding binding : entry.getValue()) { jsonGen.writeStartObject(); jsonGen.writeStringField("HostIp", binding.getHostIp() == null ? "" : binding.getHostIp()); jsonGen.writeStringField("HostPort", binding.getHostPort() == null ? "" : binding.getHostPort() .toString()); jsonGen.writeEndObject(); } jsonGen.writeEndArray(); } else { jsonGen.writeNull(); } } jsonGen.writeEndObject(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy