package rules; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.spotify.docker.client.DefaultDockerClient; import com.spotify.docker.client.DockerClient; import com.spotify.docker.client.DockerException; import com.spotify.docker.client.messages.ContainerConfig; import com.spotify.docker.client.messages.ContainerCreation; import com.spotify.docker.client.messages.HostConfig; import com.spotify.docker.client.messages.PortBinding; import org.eclipse.jdt.launching.SocketUtil; import org.junit.rules.ExternalResource; import org.junit.runner.Description; import org.junit.runners.model.Statement; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Created with IntelliJ IDEA. * User: moshe * Date: 9/23/14 * Time: 11:57 AM */ public class DockerContainerRule extends ExternalResource { public static final String DOCKER_SERVICE_URL = "http://localhost:2375"; private final DockerClient dockerClient; private final HostConfig hostConfig; private final Map externalServicePorts = Maps.newHashMap(); private ContainerCreation container; public DockerContainerRule(String imageName, Map> portMapping, String[] cmd) { this(imageName, portMapping, DOCKER_SERVICE_URL, cmd); } public DockerContainerRule(String imageName, Map> portMapping, String dockerServiceUrl, String[] cmd) { List exposedPorts = new ArrayList<>(); for (Map.Entry> entry : portMapping.entrySet()) { exposedPorts.add(entry.getValue().getKey() + "/tcp"); } ContainerConfig containerConfig = ContainerConfig.builder() .image(imageName) .networkDisabled(false) .cmd(cmd) .exposedPorts(exposedPorts.toArray(new String[exposedPorts.size()])) .build(); dockerClient = new DefaultDockerClient(dockerServiceUrl); Map> portBindings = Maps.newHashMap(); // you can leave the host IP empty for the PortBinding.of first parameter for (Map.Entry> entry : portMapping.entrySet()) { String externalPort = isSet(entry.getValue().getValue()) ? entry.getValue().getValue() : Integer.toString(SocketUtil.findFreePort()); externalServicePorts.put(entry.getKey(), externalPort); portBindings.put(entry.getValue().getKey() + "/tcp", Lists.newArrayList(PortBinding.of("0.0.0.0", externalPort))); } hostConfig = HostConfig.builder() .portBindings(portBindings) .build(); try { //dockerClient.pull(imageName); container = dockerClient.createContainer(containerConfig); } catch (DockerException | InterruptedException e) { e.printStackTrace(); } } private boolean isSet(String value) { return value != null && !value.equals(""); } public Map getExternalServicePorts() { return externalServicePorts; } @Override public Statement apply(Statement base, Description description) { return super.apply(base, description); } @Override protected void before() throws Throwable { super.before(); dockerClient.startContainer(container.id(), hostConfig); Thread.sleep(5000); } @Override protected void after() { super.after(); try { dockerClient.killContainer(container.id()); dockerClient.removeContainer(container.id(), true); } catch (DockerException | InterruptedException e) { e.printStackTrace(); } } }