Skip to content

Commit

Permalink
Switch to apache5 connector (fixes #817)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmandalidis committed Dec 21, 2024
1 parent e13881a commit c6d64af
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 50 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ to achieve JAX-RS version compatibility
* **breaking** Google OAuth2 support was dropped
* Users are advised to copy `ContainerRegistryAuthSupplier` from a `docker-client` 8.x version
and maintain it on their own side.
* Switch to apache5 connector (fixes #817)
* Bump org.bouncycastle:bcpkix-jdk18on from 1.78.1 to 1.79
* Bump com.fasterxml.jackson:jackson-bom from 2.18.0 to 2.18.2
* Bump ch.qos.logback:logback-classic from 1.5.11 to 1.5.14


## 8.0.3 - notable changes

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
</dependency>
<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-apache-connector</artifactId>
<artifactId>jersey-apache5-connector</artifactId>
<version>${version.jersey}</version>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;

import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.ssl.SSLContexts;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.core5.ssl.SSLContexts;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.URI;

import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.util.TimeValue;

import jnr.unixsocket.UnixSocket;
import jnr.unixsocket.UnixSocketAddress;
import jnr.unixsocket.UnixSocketChannel;

import org.apache.http.HttpHost;
import org.apache.http.annotation.Contract;
import org.apache.http.annotation.ThreadingBehavior;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.protocol.HttpContext;

/**
* Provides a ConnectionSocketFactory for connecting Apache HTTP clients to Unix sockets.
Expand Down Expand Up @@ -70,7 +70,7 @@ public UnixSocket createSocket(final HttpContext context) throws IOException {
}

@Override
public Socket connectSocket(final int connectTimeout,
public Socket connectSocket(final TimeValue connectTimeout,
final Socket socket,
final HttpHost host,
final InetSocketAddress remoteAddress,
Expand All @@ -80,12 +80,8 @@ public Socket connectSocket(final int connectTimeout,
throw new AssertionError("Unexpected socket: " + socket);
}

socket.setSoTimeout(connectTimeout);
try {
socket.getChannel().connect(new UnixSocketAddress(socketFile));
} catch (SocketTimeoutException e) {
throw new ConnectTimeoutException(e, null, remoteAddress.getAddress());
}
socket.setSoTimeout((int) connectTimeout.toDuration().toMillis());
socket.getChannel().connect(new UnixSocketAddress(socketFile));
return socket;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,27 @@
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.glassfish.jersey.apache.connector.ApacheClientProperties;
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.http.config.Registry;
import org.apache.hc.core5.http.config.RegistryBuilder;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
import org.glassfish.jersey.apache5.connector.Apache5ClientProperties;
import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.RequestEntityProcessing;
Expand Down Expand Up @@ -126,9 +131,8 @@ private Client createClient() {
final HttpClientConnectionManager cm = getConnectionManager(uri, schemeRegistry, connectionPoolSize);

final RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout((int) connectTimeoutMillis)
.setConnectTimeout((int) connectTimeoutMillis)
.setSocketTimeout((int) readTimeoutMillis)
.setConnectionRequestTimeout(Timeout.of(Duration.ofMillis(connectTimeoutMillis)))
.setResponseTimeout(Timeout.of(Duration.ofMillis(readTimeoutMillis)))
.build();

ClientConfig config = new ClientConfig(JacksonFeature.class);
Expand All @@ -137,11 +141,14 @@ private Client createClient() {
config = updateProxy(config);
}

DefaultHttpRequestRetryStrategy retryStrategy = new DefaultHttpRequestRetryStrategy(0, TimeValue.ZERO_MILLISECONDS);

config
.connectorProvider(new ApacheConnectorProvider())
.property(ApacheClientProperties.CONNECTION_MANAGER, cm)
.property(ApacheClientProperties.CONNECTION_MANAGER_SHARED, "true")
.property(ApacheClientProperties.REQUEST_CONFIG, requestConfig);
.connectorProvider(new Apache5ConnectorProvider())
.property(Apache5ClientProperties.CONNECTION_MANAGER, cm)
.property(Apache5ClientProperties.CONNECTION_MANAGER_SHARED, "true")
.property(Apache5ClientProperties.REQUEST_CONFIG, requestConfig)
.property(Apache5ClientProperties.RETRY_STRATEGY, retryStrategy);

if (entityProcessing != null) {
switch (entityProcessing) {
Expand Down Expand Up @@ -408,9 +415,15 @@ private HttpClientConnectionManager getConnectionManager(URI uri, Registry<Conne
if (uri.getScheme().equals(NPIPE_SCHEME)) {
return new BasicHttpClientConnectionManager(schemeRegistry);
}

ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setConnectTimeout(Timeout.of(Duration.ofMillis(connectTimeoutMillis)))
.build();

final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(schemeRegistry);
// Use all available connections instead of artificially limiting ourselves to 2 per server.
cm.setMaxTotal(connectionPoolSize);
cm.setConnectionConfigResolver((route) -> connectionConfig);
cm.setDefaultMaxPerRoute(cm.getMaxTotal());
return cm;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@
import java.net.Socket;
import java.net.URI;

import org.apache.http.HttpHost;
import org.apache.http.annotation.Contract;
import org.apache.http.annotation.ThreadingBehavior;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.protocol.HttpContext;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.util.TimeValue;

/**
* Provides a ConnectionSocketFactory for connecting Apache HTTP clients to windows named pipe.
Expand Down Expand Up @@ -64,7 +65,7 @@ public Socket createSocket(final HttpContext context) throws IOException {
}

@Override
public Socket connectSocket(final int connectTimeout,
public Socket connectSocket(final TimeValue connectTimeout,
final Socket socket,
final HttpHost host,
final InetSocketAddress remoteAddress,
Expand All @@ -73,7 +74,7 @@ public Socket connectSocket(final int connectTimeout,
if (!(socket instanceof NamedPipeSocket)) {
throw new AssertionError("Unexpected socket: " + socket);
}
socket.connect(new NpipeSocketAddress(socketFile), connectTimeout);
socket.connect(new NpipeSocketAddress(socketFile), (int) connectTimeout.toDuration().toMillis());
return socket;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@

import javax.net.ssl.SSLSocket;

import org.apache.http.HttpHost;
import org.apache.http.protocol.HttpContext;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.util.TimeValue;
import org.hamcrest.core.IsInstanceOf;
import org.junit.Before;
import org.junit.Test;
Expand Down Expand Up @@ -64,15 +65,15 @@ public void testSanitizeUri() throws Exception {
public void testConnectSocket() throws Exception {
final NamedPipeSocket npipeSocket = mock(NamedPipeSocket.class);
when(npipeSocket.getChannel()).thenReturn(mock(SocketChannel.class));
final Socket socket = sut.connectSocket(10, npipeSocket, HttpHost.create("http://foo.com"),
final Socket socket = sut.connectSocket(TimeValue.ofMilliseconds(10), npipeSocket, HttpHost.create("http://foo.com"),
mock(InetSocketAddress.class), mock(InetSocketAddress.class), mock(HttpContext.class));
assertThat(socket, IsInstanceOf.instanceOf(NamedPipeSocket.class));
assertThat((NamedPipeSocket) socket, equalTo(npipeSocket));
}

@Test(expected = AssertionError.class)
public void testConnectSocketNotUnixSocket() throws Exception {
sut.connectSocket(10, mock(SSLSocket.class), HttpHost.create("http://foo.com"),
sut.connectSocket(TimeValue.ofMilliseconds(10), mock(SSLSocket.class), HttpHost.create("http://foo.com"),
mock(InetSocketAddress.class), mock(InetSocketAddress.class), mock(HttpContext.class));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@

import javax.net.ssl.SSLSocket;

import org.apache.http.HttpHost;
import org.apache.http.protocol.HttpContext;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.util.TimeValue;
import org.hamcrest.core.IsInstanceOf;
import org.junit.Before;
import org.junit.Test;
Expand Down Expand Up @@ -65,7 +66,7 @@ public void testSanitizeUri() throws Exception {
public void testConnectSocket() throws Exception {
final UnixSocket unixSocket = mock(UnixSocket.class);
when(unixSocket.getChannel()).thenReturn(mock(SocketChannel.class));
final Socket socket = sut.connectSocket(10, unixSocket, HttpHost.create("http://foo.com"),
final Socket socket = sut.connectSocket(TimeValue.ofMilliseconds(10), unixSocket, HttpHost.create("http://foo.com"),
mock(InetSocketAddress.class), mock(InetSocketAddress.class), mock(HttpContext.class));
verify(unixSocket).setSoTimeout(10);
assertThat(socket, IsInstanceOf.instanceOf(UnixSocket.class));
Expand All @@ -74,7 +75,7 @@ public void testConnectSocket() throws Exception {

@Test(expected = AssertionError.class)
public void testConnectSocketNotUnixSocket() throws Exception {
sut.connectSocket(10, mock(SSLSocket.class), HttpHost.create("http://foo.com"),
sut.connectSocket(TimeValue.ofMilliseconds(10), mock(SSLSocket.class), HttpHost.create("http://foo.com"),
mock(InetSocketAddress.class), mock(InetSocketAddress.class), mock(HttpContext.class));
}

Expand Down

0 comments on commit c6d64af

Please sign in to comment.