Skip to content

Commit 35ff3fb

Browse files
committed
Port to Jersey/JAX-RS 2.0
1 parent f6ef1dd commit 35ff3fb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+405
-433
lines changed

pom.xml

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@
5050

5151
<version.slf4j>1.6.1</version.slf4j>
5252

53-
<jersey.version>1.18</jersey.version>
53+
<jersey.version>2.11</jersey.version>
5454
<jersey-apache-client4.version>1.9</jersey-apache-client4.version>
5555

5656
<jackson-jaxrs.version>2.3.3</jackson-jaxrs.version>
5757

5858
<httpclient.version>4.2.5</httpclient.version>
5959
<commons-compress.version>1.5</commons-compress.version>
60+
<commons-codec.version>1.8</commons-codec.version>
6061
<commons-io.version>2.3</commons-io.version>
6162
<commons-lang.version>2.6</commons-lang.version>
6263
<slf4j-api.version>1.7.5</slf4j-api.version>
@@ -87,38 +88,21 @@
8788
<version>${jackson-jaxrs.version}</version>
8889
</dependency>
8990
<dependency>
90-
<groupId>com.sun.jersey</groupId>
91-
<artifactId>jersey-core</artifactId>
92-
<version>${jersey.version}</version>
93-
</dependency>
94-
<dependency>
95-
<groupId>com.sun.jersey</groupId>
96-
<artifactId>jersey-client</artifactId>
91+
<groupId>org.glassfish.jersey.connectors</groupId>
92+
<artifactId>jersey-jetty-connector</artifactId>
9793
<version>${jersey.version}</version>
9894
</dependency>
9995

100-
<dependency>
101-
<groupId>com.sun.jersey.contribs</groupId>
102-
<artifactId>jersey-multipart</artifactId>
103-
<version>${jersey.version}</version>
104-
</dependency>
105-
<dependency>
106-
<groupId>com.sun.jersey.contribs</groupId>
107-
<artifactId>jersey-apache-client4</artifactId>
108-
<version>${jersey-apache-client4.version}</version>
109-
</dependency>
110-
111-
<dependency>
112-
<groupId>org.apache.httpcomponents</groupId>
113-
<artifactId>httpclient</artifactId>
114-
<version>${httpclient.version}</version>
115-
</dependency>
116-
11796
<dependency>
11897
<groupId>org.apache.commons</groupId>
11998
<artifactId>commons-compress</artifactId>
12099
<version>${commons-compress.version}</version>
121100
</dependency>
101+
<dependency>
102+
<groupId>commons-codec</groupId>
103+
<artifactId>commons-codec</artifactId>
104+
<version>${commons-codec.version}</version>
105+
</dependency>
122106
<dependency>
123107
<groupId>commons-lang</groupId>
124108
<artifactId>commons-lang</artifactId>

src/main/java/com/github/dockerjava/client/DockerClient.java

Lines changed: 49 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,21 @@
11
package com.github.dockerjava.client;
22

3-
import static com.google.common.base.Preconditions.checkNotNull;
4-
import static org.apache.commons.io.IOUtils.closeQuietly;
5-
6-
import java.io.*;
7-
3+
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
84
import com.github.dockerjava.client.command.*;
9-
5+
import com.github.dockerjava.client.model.AuthConfig;
6+
import com.github.dockerjava.client.utils.JsonClientFilter;
107
import org.apache.commons.io.IOUtils;
118
import org.apache.commons.io.LineIterator;
12-
import org.apache.http.client.HttpClient;
13-
import org.apache.http.conn.scheme.PlainSocketFactory;
14-
import org.apache.http.conn.scheme.Scheme;
15-
import org.apache.http.conn.scheme.SchemeRegistry;
16-
import org.apache.http.conn.ssl.SSLSocketFactory;
17-
import org.apache.http.impl.client.DefaultHttpClient;
18-
import org.apache.http.impl.conn.PoolingClientConnectionManager;
9+
import org.glassfish.jersey.client.ClientConfig;
10+
import org.glassfish.jersey.client.ClientProperties;
1911

20-
import com.github.dockerjava.client.model.AuthConfig;
12+
import javax.ws.rs.client.Client;
13+
import javax.ws.rs.client.ClientBuilder;
14+
import javax.ws.rs.client.WebTarget;
15+
import javax.ws.rs.core.Response;
16+
import java.io.*;
2117

22-
import com.github.dockerjava.client.utils.JsonClientFilter;
23-
import com.sun.jersey.api.client.Client;
24-
import com.sun.jersey.api.client.ClientResponse;
25-
import com.sun.jersey.api.client.WebResource;
26-
import com.sun.jersey.api.client.config.ClientConfig;
27-
import com.sun.jersey.api.client.config.DefaultClientConfig;
28-
import com.sun.jersey.client.apache4.ApacheHttpClient4;
29-
import com.sun.jersey.client.apache4.ApacheHttpClient4Handler;
18+
import static com.google.common.base.Preconditions.checkNotNull;
3019

3120
/**
3221
* @author Konstantin Pelykh (kpelykh@gmail.com)
@@ -36,7 +25,7 @@ public class DockerClient implements Closeable {
3625
private final Client client;
3726

3827
private final CommandFactory cmdFactory;
39-
private final WebResource baseResource;
28+
private final WebTarget baseResource;
4029
private final DockerClientConfig dockerClientConfig;
4130

4231
public DockerClient() {
@@ -61,51 +50,35 @@ public DockerClient(DockerClientConfig dockerClientConfig, CommandFactory cmdFac
6150
this.cmdFactory = cmdFactory;
6251
this.dockerClientConfig = dockerClientConfig;
6352

64-
HttpClient httpClient = getPoolingHttpClient(dockerClientConfig);
65-
ClientConfig clientConfig = new DefaultClientConfig();
66-
client = new ApacheHttpClient4(new ApacheHttpClient4Handler(httpClient,
67-
null, false), clientConfig);
68-
69-
if(dockerClientConfig.getReadTimeout() != null) {
70-
client.setReadTimeout(dockerClientConfig.getReadTimeout());
71-
}
72-
73-
client.addFilter(new JsonClientFilter());
53+
ClientConfig clientConfig = new ClientConfig();
7454

75-
if (dockerClientConfig.isLoggingFilterEnabled())
76-
client.addFilter(new SelectiveLoggingFilter());
55+
if (dockerClientConfig.getReadTimeout() != null) {
56+
clientConfig.property(ClientProperties.READ_TIMEOUT, dockerClientConfig.getReadTimeout());
57+
}
7758

78-
WebResource webResource = client.resource(dockerClientConfig.getUri());
79-
80-
if(dockerClientConfig.getVersion() != null) {
81-
baseResource = webResource.path("v" + dockerClientConfig.getVersion());
82-
} else {
83-
baseResource = webResource;
84-
}
85-
}
59+
clientConfig.register(JsonClientFilter.class);
60+
clientConfig.register(JacksonJsonProvider.class);
8661

87-
private HttpClient getPoolingHttpClient(DockerClientConfig dockerClientConfig) {
88-
SchemeRegistry schemeRegistry = new SchemeRegistry();
89-
schemeRegistry.register(new Scheme("http", dockerClientConfig.getUri().getPort(),
90-
PlainSocketFactory.getSocketFactory()));
91-
schemeRegistry.register(new Scheme("https", 443, SSLSocketFactory
92-
.getSocketFactory()));
62+
if (dockerClientConfig.isLoggingFilterEnabled()) {
63+
clientConfig.register(SelectiveLoggingFilter.class);
64+
}
9365

94-
PoolingClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry);
95-
// Increase max total connection
96-
cm.setMaxTotal(1000);
97-
// Increase default max connection per route
98-
cm.setDefaultMaxPerRoute(1000);
66+
client = ClientBuilder.newBuilder().withConfig(clientConfig).build();
67+
WebTarget webResource = client.target(dockerClientConfig.getUri());
9968

100-
return new DefaultHttpClient(cm);
69+
if (dockerClientConfig.getVersion() != null) {
70+
baseResource = webResource.path("v" + dockerClientConfig.getVersion());
71+
} else {
72+
baseResource = webResource;
73+
}
10174
}
10275

10376
public <RES_T> RES_T execute(AbstrDockerCmd<?, RES_T> command)
10477
throws DockerException {
10578
return command.withBaseResource(baseResource).exec();
10679
}
10780

108-
public AuthConfig authConfig() throws DockerException {
81+
public AuthConfig authConfig() throws DockerException {
10982
checkNotNull(dockerClientConfig.getUsername(), "Configured username is null.");
11083
checkNotNull(dockerClientConfig.getPassword(), "Configured password is null.");
11184
checkNotNull(dockerClientConfig.getEmail(), "Configured email is null.");
@@ -263,28 +236,29 @@ public TagImageCmd tagImageCmd(String imageId, String repository, String tag) {
263236
}
264237

265238
// TODO This is only being used by the test code for logging. Is it really necessary?
266-
/**
267-
* @return The output slurped into a string.
268-
*/
269-
public static String asString(ClientResponse response) throws IOException {
270-
271-
StringWriter out = new StringWriter();
272-
try {
273-
LineIterator itr = IOUtils.lineIterator(
274-
response.getEntityInputStream(), "UTF-8");
275-
while (itr.hasNext()) {
276-
String line = itr.next();
277-
out.write(line + (itr.hasNext() ? "\n" : ""));
278-
}
279-
} finally {
280-
closeQuietly(response.getEntityInputStream());
281-
}
282-
return out.toString();
283-
}
239+
240+
/**
241+
* @return The output slurped into a string.
242+
*/
243+
public static String asString(Response response) throws IOException {
244+
245+
StringWriter out = new StringWriter();
246+
InputStream is = response.readEntity(InputStream.class);
247+
try {
248+
LineIterator itr = IOUtils.lineIterator(is, "UTF-8");
249+
while (itr.hasNext()) {
250+
String line = itr.next();
251+
out.write(line + (itr.hasNext() ? "\n" : ""));
252+
}
253+
} finally {
254+
IOUtils.closeQuietly(is);
255+
}
256+
return out.toString();
257+
}
284258

285259
@Override
286260
public void close() throws IOException {
287-
client.destroy();
261+
client.close();
288262
}
289263

290264
}
Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package com.github.dockerjava.client;
22

3+
import java.io.IOException;
34
import java.util.Set;
45

6+
import javax.ws.rs.client.ClientRequestContext;
57
import javax.ws.rs.core.HttpHeaders;
68
import javax.ws.rs.core.MediaType;
79

810
import com.google.common.collect.ImmutableSet;
9-
import com.sun.jersey.api.client.ClientHandlerException;
10-
import com.sun.jersey.api.client.ClientRequest;
11-
import com.sun.jersey.api.client.ClientResponse;
12-
import com.sun.jersey.api.client.filter.LoggingFilter;
11+
12+
import org.glassfish.jersey.filter.LoggingFilter;
1313

1414
/**
1515
* A version of the logging filter that will avoid trying to log entities which can cause
@@ -26,22 +26,13 @@ public class SelectiveLoggingFilter extends LoggingFilter {
2626
.build();
2727

2828
@Override
29-
public ClientResponse handle(ClientRequest request) throws ClientHandlerException {
29+
public void filter(ClientRequestContext context) throws IOException {
3030
// Unless the content type is in the list of those we want to ellide, then just have
3131
// our super-class handle things.
32-
Object contentType = request.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
33-
if (contentType != null && SKIPPED_CONTENT.contains(contentType.toString())) {
34-
// Skip logging this.
35-
//
36-
// N.B. -- I'd actually love to reproduce (or better yet just use) the logging code from
37-
// our super-class. However, everything is private (so we can't use it) and the code
38-
// is under a modified GPL which means we can't pull it into an ASL project. Right now
39-
// I don't have the energy to do a clean implementation.
40-
return getNext().handle(request);
32+
Object contentType = context.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
33+
if (contentType == null || !SKIPPED_CONTENT.contains(contentType.toString())) {
34+
super.filter(context);
4135
}
42-
43-
// Do what we normally would
44-
return super.handle(request);
4536
}
4637

4738
}

src/main/java/com/github/dockerjava/client/command/AbstrAuthCfgDockerCmd.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
import java.io.IOException;
44

5-
import org.apache.commons.codec.binary.Base64;
6-
75
import com.fasterxml.jackson.databind.ObjectMapper;
86
import com.github.dockerjava.client.DockerException;
97
import com.github.dockerjava.client.model.AuthConfig;
108
import com.google.common.base.Preconditions;
9+
import org.apache.commons.codec.binary.Base64;
1110

1211
public abstract class AbstrAuthCfgDockerCmd<T extends AbstrDockerCmd<T, RES_T>, RES_T> extends
1312
AbstrDockerCmd<T, RES_T> {

src/main/java/com/github/dockerjava/client/command/AbstrDockerCmd.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44
import org.slf4j.LoggerFactory;
55

66
import com.google.common.base.Preconditions;
7-
import com.sun.jersey.api.client.WebResource;
7+
8+
import javax.ws.rs.client.WebTarget;
89

910
public abstract class AbstrDockerCmd<T extends AbstrDockerCmd<T, RES_T>, RES_T> implements DockerCmd<RES_T> {
1011

1112
private final static Logger LOGGER = LoggerFactory.getLogger(AbstrDockerCmd.class);
1213

13-
protected WebResource baseResource;
14+
protected WebTarget baseResource;
1415

1516
@SuppressWarnings("unchecked")
16-
public T withBaseResource(WebResource baseResource) {
17+
public T withBaseResource(WebTarget baseResource) {
1718
this.baseResource = baseResource;
1819
return (T)this;
1920
}

src/main/java/com/github/dockerjava/client/command/AttachContainerCmd.java

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.github.dockerjava.client.command;
22

3+
import javax.ws.rs.ClientErrorException;
34
import javax.ws.rs.core.MediaType;
45
import javax.ws.rs.core.MultivaluedMap;
56

@@ -9,10 +10,10 @@
910
import com.github.dockerjava.client.DockerException;
1011
import com.github.dockerjava.client.NotFoundException;
1112
import com.google.common.base.Preconditions;
12-
import com.sun.jersey.api.client.ClientResponse;
13-
import com.sun.jersey.api.client.UniformInterfaceException;
14-
import com.sun.jersey.api.client.WebResource;
15-
import com.sun.jersey.core.util.MultivaluedMapImpl;
13+
import javax.ws.rs.client.WebTarget;
14+
import javax.ws.rs.core.Response;
15+
16+
import static javax.ws.rs.client.Entity.entity;
1617

1718
/**
1819
* Attach to container
@@ -29,7 +30,7 @@
2930
* - true or false, if true, print timestamps for every log line.
3031
* Defaults to false.
3132
*/
32-
public class AttachContainerCmd extends AbstrDockerCmd<AttachContainerCmd, ClientResponse> {
33+
public class AttachContainerCmd extends AbstrDockerCmd<AttachContainerCmd, Response> {
3334

3435
private static final Logger LOGGER = LoggerFactory
3536
.getLogger(AttachContainerCmd.class);
@@ -109,23 +110,20 @@ public AttachContainerCmd withLogs(boolean logs) {
109110
return this;
110111
}
111112

112-
protected ClientResponse impl() throws DockerException {
113-
MultivaluedMap<String, String> params = new MultivaluedMapImpl();
114-
params.add("logs", logs ? "1" : "0");
115-
params.add("timestamps", timestamps ? "1" : "0");
116-
params.add("stdout", stdout ? "1" : "0");
117-
params.add("stderr", stderr ? "1" : "0");
118-
params.add("follow", followStream ? "1" : "0");
119-
120-
WebResource webResource = baseResource.path(
121-
String.format("/containers/%s/attach", containerId))
122-
.queryParams(params);
113+
protected Response impl() throws DockerException {
114+
WebTarget webResource = baseResource.path("/containers/{id}/attach")
115+
.resolveTemplate("{id}", containerId)
116+
.queryParam("logs", logs ? "1" : "0")
117+
.queryParam("timestamps", timestamps ? "1" : "0")
118+
.queryParam("stdout", stdout ? "1" : "0")
119+
.queryParam("stderr", stderr ? "1" : "0")
120+
.queryParam("follow", followStream ? "1" : "0");
123121

124122
try {
125123
LOGGER.trace("POST: {}", webResource);
126-
return webResource.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE)
127-
.post(ClientResponse.class);
128-
} catch (UniformInterfaceException exception) {
124+
return webResource.request().accept(MediaType.APPLICATION_OCTET_STREAM_TYPE)
125+
.post(entity(null, MediaType.APPLICATION_JSON), Response.class);
126+
} catch (ClientErrorException exception) {
129127
if (exception.getResponse().getStatus() == 400) {
130128
throw new DockerException("bad parameter");
131129
} else if (exception.getResponse().getStatus() == 404) {

0 commit comments

Comments
 (0)