diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java index 8b9880747..9894466d4 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java @@ -2,12 +2,14 @@ import java.io.Closeable; import java.io.IOException; +import java.util.List; import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.http.AbstractHttpFeature; public interface DockerCmdExecFactory extends Closeable { - public void init(DockerClientConfig dockerClientConfig); + public void init(DockerClientConfig dockerClientConfig, List httpFeatures); public AuthCmd.Exec createAuthCmdExec(); diff --git a/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java b/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java index 4aa7d5ac7..bc6ec8dd9 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java @@ -1,10 +1,12 @@ package com.github.dockerjava.core; +import java.util.List; import java.util.ServiceLoader; import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.DockerCmdExecFactory; import com.github.dockerjava.core.DockerClientConfig.DockerClientConfigBuilder; +import com.github.dockerjava.core.http.AbstractHttpFeature; public class DockerClientBuilder { @@ -30,6 +32,11 @@ public static DockerClientBuilder getInstance(DockerClientConfig dockerClientCon .getInstance(dockerClientConfig)); } + public static DockerClientBuilder getInstance(DockerClientConfig dockerClientConfig, List httpFeatures) { + return new DockerClientBuilder(DockerClientImpl + .getInstance(dockerClientConfig, httpFeatures)); + } + public static DockerClientBuilder getInstance(String serverUrl) { return new DockerClientBuilder(DockerClientImpl .getInstance(serverUrl)); diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index 7e96225f8..017733d7d 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -6,6 +6,8 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.*; @@ -13,6 +15,7 @@ import com.github.dockerjava.api.model.AuthConfigurations; import com.github.dockerjava.api.model.Identifier; import com.github.dockerjava.core.command.*; +import com.github.dockerjava.core.http.AbstractHttpFeature; /** * @author Konstantin Pelykh (kpelykh@gmail.com) @@ -22,6 +25,7 @@ public class DockerClientImpl implements Closeable, DockerClient { private final DockerClientConfig dockerClientConfig; + private List httpFeatures = new ArrayList<>(); private DockerCmdExecFactory dockerCmdExecFactory; @@ -39,6 +43,15 @@ private DockerClientImpl(DockerClientConfig dockerClientConfig) { this.dockerClientConfig = dockerClientConfig; } + private DockerClientImpl(DockerClientConfig dockerClientConfig, List httpFeatures) { + checkNotNull(dockerClientConfig, + "config was not specified"); + checkNotNull(httpFeatures, + "http features were not specified"); + this.dockerClientConfig = dockerClientConfig; + this.httpFeatures = httpFeatures; + } + private static DockerClientConfig configWithServerUrl(String serverUrl) { return DockerClientConfig.createDefaultConfigBuilder() .withUri(serverUrl).build(); @@ -53,6 +66,11 @@ public static DockerClientImpl getInstance( return new DockerClientImpl(dockerClientConfig); } + public static DockerClientImpl getInstance( + DockerClientConfig dockerClientConfig, List httpFeatures) { + return new DockerClientImpl(dockerClientConfig, httpFeatures); + } + public static DockerClientImpl getInstance(String serverUrl) { return new DockerClientImpl(serverUrl); } @@ -62,7 +80,7 @@ public DockerClientImpl withDockerCmdExecFactory( checkNotNull(dockerCmdExecFactory, "dockerCmdExecFactory was not specified"); this.dockerCmdExecFactory = dockerCmdExecFactory; - this.dockerCmdExecFactory.init(dockerClientConfig); + this.dockerCmdExecFactory.init(dockerClientConfig, httpFeatures); return this; } diff --git a/src/main/java/com/github/dockerjava/core/http/AbstractHttpFeature.java b/src/main/java/com/github/dockerjava/core/http/AbstractHttpFeature.java new file mode 100644 index 000000000..5ff093369 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/http/AbstractHttpFeature.java @@ -0,0 +1,14 @@ +package com.github.dockerjava.core.http; + +import java.io.IOException; +import java.util.Map; + +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientRequestFilter; + +public abstract class AbstractHttpFeature implements ClientRequestFilter { + + @Override + public abstract void filter(ClientRequestContext requestContext) throws IOException; + public abstract Map getClientConfigurationProperties(); +} diff --git a/src/main/java/com/github/dockerjava/core/http/HttpBasicAuthenticationFeature.java b/src/main/java/com/github/dockerjava/core/http/HttpBasicAuthenticationFeature.java new file mode 100644 index 000000000..0754a4138 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/http/HttpBasicAuthenticationFeature.java @@ -0,0 +1,48 @@ +package com.github.dockerjava.core.http; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Map; +import java.util.TreeMap; + +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.core.MultivaluedMap; +import javax.xml.bind.DatatypeConverter; + +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.client.RequestEntityProcessing; + +public class HttpBasicAuthenticationFeature extends AbstractHttpFeature { + + private final String user; + private final String password; + + public HttpBasicAuthenticationFeature(String user, String password) { + this.user = user; + this.password = password; + } + + @Override + public void filter(ClientRequestContext requestContext) throws IOException { + MultivaluedMap headers = requestContext.getHeaders(); + final String basicAuthentication = getBasicAuthentication(); + headers.add("Authorization", basicAuthentication); + + } + + private String getBasicAuthentication() { + String token = this.user + ":" + this.password; + try { + return "BASIC " + DatatypeConverter.printBase64Binary(token.getBytes("UTF-8")); + } catch (UnsupportedEncodingException ex) { + throw new IllegalStateException("Cannot encode with UTF-8", ex); + } + } + + @Override + public Map getClientConfigurationProperties() { + Map map = new TreeMap(); + map.put(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.BUFFERED); + return map; + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index bc3afecad..30558dae1 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.net.URI; +import java.util.List; +import java.util.Map; import com.github.dockerjava.api.command.*; @@ -29,6 +31,7 @@ import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; import com.github.dockerjava.api.DockerClientException; import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.http.AbstractHttpFeature; import com.github.dockerjava.core.util.FollowRedirectsFilter; import com.github.dockerjava.core.util.JsonClientFilter; import com.github.dockerjava.core.util.ResponseStatusExceptionFilter; @@ -41,8 +44,8 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { private Client client; private WebTarget baseResource; - @Override - public void init(DockerClientConfig dockerClientConfig) { + @Override + public void init(DockerClientConfig dockerClientConfig, List httpFeatures) { checkNotNull(dockerClientConfig, "config was not specified"); ClientConfig clientConfig = new ClientConfig(); @@ -92,6 +95,13 @@ public void init(DockerClientConfig dockerClientConfig) { clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connManager); + + for(AbstractHttpFeature feature : httpFeatures){ + Map properties = feature.getClientConfigurationProperties(); + for(String propertyName : properties.keySet()){ + clientConfig.property(propertyName, properties.get(propertyName)); + } + } ClientBuilder clientBuilder = ClientBuilder.newBuilder().withConfig( clientConfig); @@ -106,6 +116,11 @@ public void init(DockerClientConfig dockerClientConfig) { dockerClientConfig.setUri(UnixConnectionSocketFactory .sanitizeUri(originalUri)); } + + for(AbstractHttpFeature feature : httpFeatures){ + client.register(feature); + } + WebTarget webResource = client.target(dockerClientConfig.getUri()); if (dockerClientConfig.getVersion() == null diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java index 869a12fcf..34a8d4184 100644 --- a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java +++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java @@ -8,6 +8,7 @@ import com.github.dockerjava.api.command.*; import com.github.dockerjava.api.command.AuthCmd.Exec; +import com.github.dockerjava.core.http.AbstractHttpFeature; import com.github.dockerjava.jaxrs.BuildImageCmdExec; /** @@ -31,8 +32,8 @@ public TestDockerCmdExecFactory(DockerCmdExecFactory delegate) { } @Override - public void init(DockerClientConfig dockerClientConfig) { - delegate.init(dockerClientConfig); + public void init(DockerClientConfig dockerClientConfig, List httpFeatures) { + delegate.init(dockerClientConfig, httpFeatures); } @Override