diff --git a/src/main/java/com/amihaiemil/docker/LocalDocker.java b/src/main/java/com/amihaiemil/docker/LocalDocker.java index 3e19efb0..c4ffd457 100644 --- a/src/main/java/com/amihaiemil/docker/LocalDocker.java +++ b/src/main/java/com/amihaiemil/docker/LocalDocker.java @@ -25,7 +25,7 @@ */ package com.amihaiemil.docker; -import org.apache.http.impl.client.HttpClientBuilder; +import java.io.File; /** * Local Docker API. Use this when you want to communicate with the local @@ -43,38 +43,21 @@ public final class LocalDocker extends RtDocker { /** * Local Docker engine. - * @param unixSocket Path to the unix socket - * (e.g. unix:///var/run/docker.sock). + * @param unixSocket Unix socket File on disk. + * (most likely /var/run/docker.sock). */ - public LocalDocker(final String unixSocket){ + public LocalDocker(final File unixSocket){ this(unixSocket, "v1.35"); } /** * Local Docker engine. - * @param unixSocket Path to the unix socket - * (e.g. unix:///var/run/docker.sock). + * @param unixSocket Unix socket File on disk. + * (most likely /var/run/docker.sock). * @param version API version (e.g. v1.30). */ - public LocalDocker(final String unixSocket, final String version){ - super(HttpClientBuilder.create().build()); - } - - - /** - * Sanitize the path to the unix socket. - * @param unixSocket Path to the unix socket. - * @return Sanitized path. - */ - private static String sanitize(final String unixSocket) { - String sanitized = unixSocket; - if(unixSocket.startsWith("unix://")) { - sanitized = unixSocket.substring("unix://".length()); - } - if(!sanitized.startsWith("/")) { - sanitized = "/" + sanitized; - } - return sanitized; + public LocalDocker(final File unixSocket, final String version){ + super(new UnixHttpClient(unixSocket)); } } diff --git a/src/main/java/com/amihaiemil/docker/RtDocker.java b/src/main/java/com/amihaiemil/docker/RtDocker.java index e3dffc02..846d6d5a 100644 --- a/src/main/java/com/amihaiemil/docker/RtDocker.java +++ b/src/main/java/com/amihaiemil/docker/RtDocker.java @@ -36,6 +36,9 @@ * @since 0.0.1 * @todo #11:30min Implement RemoteDocker which will make the requests over * a tcp socket and TLS if certificates are provided. + * @todo #32:30min Reimplement ping() with the new HttpClient architecture. + * It should create an HttpGet method and send it with the encapsulated + * client. */ abstract class RtDocker implements Docker { diff --git a/src/main/java/com/amihaiemil/docker/UnixHttpClient.java b/src/main/java/com/amihaiemil/docker/UnixHttpClient.java index 386a4a3b..2acd3f44 100644 --- a/src/main/java/com/amihaiemil/docker/UnixHttpClient.java +++ b/src/main/java/com/amihaiemil/docker/UnixHttpClient.java @@ -25,17 +25,25 @@ */ package com.amihaiemil.docker; +import jnr.unixsocket.UnixSocketAddress; +import jnr.unixsocket.UnixSocketChannel; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; +import java.io.File; import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; /** * An HttpClient which works over a UnixSocket. @@ -44,10 +52,9 @@ * @version $Id$ * @since 0.0.1 * @checkstyle ParameterNumber (150 lines) - * @todo #29:30min Implement a ConnectionSocketFactory which builds - * UnixSocket objects. + * @checkstyle AnonInnerLength (150 lines) */ -public final class UnixHttpClient implements HttpClient { +final class UnixHttpClient implements HttpClient { /** * Decorated HttpClient. @@ -56,17 +63,51 @@ public final class UnixHttpClient implements HttpClient { /** * Ctor. - * @param socketFile Path to the unix socket on disk. + * @param socketFile Unix socket on disk. */ - public UnixHttpClient(final String socketFile) { - this(HttpClientBuilder.create().build()); + UnixHttpClient(final File socketFile) { + this( + HttpClientBuilder.create().setConnectionManager( + new BasicHttpClientConnectionManager( + RegistryBuilder + .create() + .register( + "unix", + new ConnectionSocketFactory() { + @Override + public Socket createSocket( + final HttpContext httpContext + ) throws IOException { + return UnixSocketChannel.open().socket(); + } + + @Override + public Socket connectSocket( + final int connectionTimeout, + final Socket socket, + final HttpHost host, + final InetSocketAddress remoteAddress, + final InetSocketAddress localAddress, + final HttpContext context + ) throws IOException { + socket.setSoTimeout(connectionTimeout); + socket.getChannel().connect( + new UnixSocketAddress(socketFile) + ); + return socket; + } + }) + .build() + ) + ).build() + ); } /** * Ctor. * @param client Decorated HttpClient. */ - public UnixHttpClient(final HttpClient client) { + UnixHttpClient(final HttpClient client) { this.client = client; } diff --git a/src/test/java/com/amihaiemil/docker/LocalDockerITCase.java b/src/test/java/com/amihaiemil/docker/LocalDockerITCase.java index ac8abb40..68f1ef18 100644 --- a/src/test/java/com/amihaiemil/docker/LocalDockerITCase.java +++ b/src/test/java/com/amihaiemil/docker/LocalDockerITCase.java @@ -29,6 +29,8 @@ import org.hamcrest.Matchers; import org.junit.Test; +import java.io.File; + /** * Integration tests for LocalDocker. * @author Mihai Andronache (amihaiemil@gmail.com) @@ -43,7 +45,9 @@ public final class LocalDockerITCase { */ @Test public void pingsDocker() throws Exception { - final Docker docker = new LocalDocker("/var/run/docker.sock"); + final Docker docker = new LocalDocker( + new File("/var/run/docker.sock") + ); MatcherAssert.assertThat(docker.ping(), Matchers.is(Boolean.TRUE)); } diff --git a/src/test/java/com/amihaiemil/docker/LocalDockerTestCase.java b/src/test/java/com/amihaiemil/docker/LocalDockerTestCase.java index f647e6ae..e0382bb4 100644 --- a/src/test/java/com/amihaiemil/docker/LocalDockerTestCase.java +++ b/src/test/java/com/amihaiemil/docker/LocalDockerTestCase.java @@ -29,6 +29,8 @@ import org.hamcrest.Matchers; import org.junit.Test; +import java.io.File; + /** * Unit tests for LocalDocker. * @author Mihai Andronache (amihaiemil@gmail.com) @@ -42,7 +44,9 @@ public final class LocalDockerTestCase { */ @Test public void canInstantiateWithScheme() { - final Docker docker = new LocalDocker("unix:///var/run/docker.sock"); + final Docker docker = new LocalDocker( + new File("/var/run/docker.sock") + ); MatcherAssert.assertThat(docker, Matchers.notNullValue()); } @@ -51,7 +55,9 @@ public void canInstantiateWithScheme() { */ @Test public void canInstantiateWithoutScheme() { - final Docker docker = new LocalDocker("/var/run/docker.sock"); + final Docker docker = new LocalDocker( + new File("/var/run/docker.sock") + ); MatcherAssert.assertThat(docker, Matchers.notNullValue()); } } diff --git a/src/test/java/com/amihaiemil/docker/UnixHttpClientTestCase.java b/src/test/java/com/amihaiemil/docker/UnixHttpClientTestCase.java index f02899b6..f7728d54 100644 --- a/src/test/java/com/amihaiemil/docker/UnixHttpClientTestCase.java +++ b/src/test/java/com/amihaiemil/docker/UnixHttpClientTestCase.java @@ -38,6 +38,8 @@ import org.hamcrest.Matchers; import org.junit.Test; import org.mockito.Mockito; + +import java.io.File; import java.io.IOException; /** @@ -49,7 +51,18 @@ public final class UnixHttpClientTestCase { /** - * UnixHttoClient returns its HttpParams. + * UnixHttpClient can be instantiated with a socket File. + */ + @Test + public void instantiatesWithSocket() { + MatcherAssert.assertThat( + new UnixHttpClient(new File("/var/run/docker.sock")), + Matchers.notNullValue() + ); + } + + /** + * UnixHttpClient returns its HttpParams. */ @Test public void getsHttpParams() { @@ -65,7 +78,7 @@ public void getsHttpParams() { } /** - * UnixHttoClient returns its ClientConnectionManager. + * UnixHttpClient returns its ClientConnectionManager. */ @Test public void getsClientConnectionManager() {