Skip to content

Commit 341c7de

Browse files
committed
Merge pull request #147 from shabtaisharon/networkPerformance
add connectionManager with 50 defualt connection per route and 100 co…
2 parents 868d05b + 9fb316c commit 341c7de

File tree

1 file changed

+53
-24
lines changed

1 file changed

+53
-24
lines changed

ds3-sdk/src/main/java/com/spectralogic/ds3client/NetworkClientImpl.java

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,20 @@
2626
import com.spectralogic.ds3client.utils.DateFormatter;
2727
import com.spectralogic.ds3client.utils.SSLSetupException;
2828
import com.spectralogic.ds3client.utils.Signature;
29-
3029
import org.apache.http.HttpHost;
3130
import org.apache.http.HttpRequest;
3231
import org.apache.http.HttpStatus;
3332
import org.apache.http.client.config.RequestConfig;
3433
import org.apache.http.client.methods.CloseableHttpResponse;
3534
import org.apache.http.client.protocol.HttpClientContext;
36-
import org.apache.http.conn.ssl.*;
35+
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
36+
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
37+
import org.apache.http.conn.ssl.SSLContexts;
38+
import org.apache.http.conn.ssl.TrustStrategy;
3739
import org.apache.http.entity.ContentType;
3840
import org.apache.http.impl.client.CloseableHttpClient;
3941
import org.apache.http.impl.client.HttpClients;
42+
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
4043
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
4144
import org.apache.http.message.BasicHttpRequest;
4245
import org.slf4j.Logger;
@@ -46,11 +49,13 @@
4649
import java.io.Closeable;
4750
import java.io.IOException;
4851
import java.io.InputStream;
49-
import java.lang.AssertionError;
5052
import java.net.MalformedURLException;
5153
import java.net.URI;
5254
import java.net.URL;
53-
import java.security.*;
55+
import java.security.KeyManagementException;
56+
import java.security.KeyStoreException;
57+
import java.security.NoSuchAlgorithmException;
58+
import java.security.SignatureException;
5459
import java.security.cert.CertificateException;
5560
import java.security.cert.X509Certificate;
5661
import java.util.Collection;
@@ -67,25 +72,44 @@ public class NetworkClientImpl implements NetworkClient {
6772
final static private String CONTENT_SHA512 = "Content-SHA512";
6873
final static private String CONTENT_CRC32 = "Content-CRC32";
6974
final static private String CONTENT_CRC32C = "Content-CRC32C";
75+
final static private int MAX_CONNECTION_PER_ROUTE = 50;
76+
final static private int MAX_CONNECTION_TOTAL = 100;
7077

7178
final private ConnectionDetails connectionDetails;
7279

7380
final private CloseableHttpClient client;
81+
final private HttpHost host;
7482

7583
public NetworkClientImpl(final ConnectionDetails connectionDetails) {
7684
if (connectionDetails == null) throw new AssertionError("ConnectionDetails cannot be null");
77-
this.connectionDetails = connectionDetails;
78-
this.client = createDefaultClient(connectionDetails);
85+
try {
86+
this.connectionDetails = connectionDetails;
87+
this.host = buildHost(connectionDetails);
88+
this.client = createDefaultClient(connectionDetails, host);
89+
} catch (final MalformedURLException e) {
90+
throw new RuntimeException(e);
91+
}
7992
}
8093

94+
8195
public NetworkClientImpl(final ConnectionDetails connectionDetails, final CloseableHttpClient client) {
8296
if (connectionDetails == null) throw new AssertionError("ConnectionDetails cannot be null");
8397
if (client == null) throw new AssertionError("CloseableHttpClient cannot be null");
84-
this.connectionDetails = connectionDetails;
85-
this.client = client;
98+
try {
99+
this.connectionDetails = connectionDetails;
100+
this.host = buildHost(connectionDetails);
101+
this.client = client;
102+
} catch (final MalformedURLException e) {
103+
throw new RuntimeException(e);
104+
}
86105
}
87106

88-
private static CloseableHttpClient createDefaultClient(final ConnectionDetails connectionDetails) {
107+
108+
private static CloseableHttpClient createDefaultClient(final ConnectionDetails connectionDetails, final HttpHost host) {
109+
final PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
110+
connectionManager.setDefaultMaxPerRoute(MAX_CONNECTION_PER_ROUTE);
111+
connectionManager.setMaxTotal(MAX_CONNECTION_TOTAL);
112+
89113
if (connectionDetails.isHttps() && !connectionDetails.isCertificateVerification()) {
90114
try {
91115

@@ -97,15 +121,29 @@ public boolean isTrusted(final X509Certificate[] chain, final String authType) t
97121
}).useTLS().build();
98122

99123
final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
100-
return HttpClients.custom().setSSLSocketFactory(
124+
return HttpClients.custom()
125+
.setConnectionManager(connectionManager)
126+
.setSSLSocketFactory(
101127
sslsf).build();
102128

103129
} catch (final NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
104130
throw new SSLSetupException(e);
105131
}
106132
}
107133
else {
108-
return HttpClients.createDefault();
134+
return HttpClients.custom()
135+
.setConnectionManager(connectionManager)
136+
.build();
137+
}
138+
}
139+
140+
private static HttpHost buildHost(final ConnectionDetails connectionDetails) throws MalformedURLException {
141+
final URI proxyUri = connectionDetails.getProxy();
142+
if (proxyUri != null) {
143+
return new HttpHost(proxyUri.getHost(), proxyUri.getPort(), proxyUri.getScheme());
144+
} else {
145+
final URL url = NetUtils.buildUrl(connectionDetails, "/");
146+
return new HttpHost(url.getHost(), NetUtils.getPort(url), url.getProtocol());
109147
}
110148
}
111149

@@ -116,12 +154,13 @@ public ConnectionDetails getConnectionDetails() {
116154

117155
@Override
118156
public WebResponse getResponse(final Ds3Request request) throws IOException, SignatureException {
119-
try (final RequestExecutor requestExecutor = new RequestExecutor(this.client, request)) {
157+
try (final RequestExecutor requestExecutor = new RequestExecutor(this.client, host, request)) {
120158
int redirectCount = 0;
121159
do {
122160
final CloseableHttpResponse response = requestExecutor.execute();
123161
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_TEMPORARY_REDIRECT) {
124162
redirectCount++;
163+
response.close();
125164
LOG.info("Performing retry - attempt: " + redirectCount);
126165
}
127166
else {
@@ -147,10 +186,10 @@ private class RequestExecutor implements Closeable {
147186
private final Checksum.Type checksumType;
148187
private final CloseableHttpClient client;
149188

150-
public RequestExecutor(final CloseableHttpClient client, final Ds3Request ds3Request) throws IOException {
189+
public RequestExecutor(final CloseableHttpClient client, final HttpHost host, final Ds3Request ds3Request) throws IOException {
151190
this.client = client;
152191
this.ds3Request = ds3Request;
153-
this.host = this.buildHost();
192+
this.host = host;
154193
this.content = ds3Request.getStream();
155194
if (this.content != null && !this.content.markSupported()) {
156195
throw new RequiresMarkSupportedException();
@@ -171,16 +210,6 @@ public CloseableHttpResponse execute() throws IOException, SignatureException {
171210
return client.execute(this.host, httpRequest, this.getContext());
172211
}
173212

174-
private HttpHost buildHost() throws MalformedURLException {
175-
final URI proxyUri = NetworkClientImpl.this.connectionDetails.getProxy();
176-
if (proxyUri != null) {
177-
return new HttpHost(proxyUri.getHost(), proxyUri.getPort(), proxyUri.getScheme());
178-
} else {
179-
final URL url = NetUtils.buildUrl(NetworkClientImpl.this.connectionDetails, "/");
180-
return new HttpHost(url.getHost(), NetUtils.getPort(url), url.getProtocol());
181-
}
182-
}
183-
184213
private HttpRequest buildHttpRequest() throws IOException {
185214
final String verb = this.ds3Request.getVerb().toString();
186215
final String path = this.buildPath();

0 commit comments

Comments
 (0)