Skip to content

Commit 554bb08

Browse files
Add configuration setting for TTL of HTTP connections to IRestfulClientFactory (hapifhir#6204)
* Add configuration setting for TTL of HTTP connections to IRestfulClientFactory * Update changelog and pom.xml * Modify changelog --------- Co-authored-by: James Agnew <[email protected]>
1 parent 19af077 commit 554bb08

File tree

10 files changed

+98
-12
lines changed

10 files changed

+98
-12
lines changed

Diff for: hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IRestfulClientFactory.java

+25
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ public interface IRestfulClientFactory {
3737
*/
3838
public static final int DEFAULT_CONNECTION_REQUEST_TIMEOUT = 10000;
3939

40+
41+
/**
42+
* Default value for {@link #getConnectionTimeToLive()}
43+
*/
44+
public static final int DEFAULT_CONNECTION_TTL = 5000;
45+
4046
/**
4147
* Default value for {@link #getServerValidationModeEnum()}
4248
*/
@@ -75,6 +81,17 @@ public interface IRestfulClientFactory {
7581
*/
7682
int getConnectTimeout();
7783

84+
85+
/**
86+
* Gets the connection time to live, in milliseconds. This is the amount of time to keep connections alive for reuse.
87+
* <p>
88+
* The default value for this setting is defined by {@link #DEFAULT_CONNECTION_TTL}
89+
* </p>
90+
*/
91+
default int getConnectionTimeToLive() {
92+
return DEFAULT_CONNECTION_TTL;
93+
}
94+
7895
/**
7996
* Returns the HTTP client instance. This method will not return null.
8097
* @param theUrl
@@ -179,6 +196,14 @@ IHttpClient getHttpClient(
179196
*/
180197
void setConnectTimeout(int theConnectTimeout);
181198

199+
/**
200+
* Sets the connection time to live, in milliseconds. This is the amount of time to keep connections alive for reuse.
201+
* <p>
202+
* The default value for this setting is defined by {@link #DEFAULT_CONNECTION_TTL}
203+
* </p>
204+
*/
205+
default void setConnectionTimeToLive(int theConnectionTimeToLive) {}
206+
182207
/**
183208
* Sets the Apache HTTP client instance to be used by any new restful clients created by this factory. If set to
184209
* <code>null</code>, a new HTTP client with default settings will be created.

Diff for: hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/client/HapiFhirCliRestfulClientFactory.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ public HttpClient getNativeHttpClient() {
106106
.register("https", sslConnectionSocketFactory)
107107
.build();
108108
connectionManager =
109-
new PoolingHttpClientConnectionManager(registry, null, null, null, 5000, TimeUnit.MILLISECONDS);
109+
new PoolingHttpClientConnectionManager(registry, null, null, null, getConnectionTimeToLive(), TimeUnit.MILLISECONDS);
110110
} else {
111-
connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
111+
connectionManager = new PoolingHttpClientConnectionManager(getConnectionTimeToLive(), TimeUnit.MILLISECONDS);
112112
}
113113

114114
connectionManager.setMaxTotal(getPoolMaxTotal());

Diff for: hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/ApacheRestfulClientFactoryTest.java

+11
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
import ca.uhn.fhir.context.FhirContext;
44
import ca.uhn.fhir.context.FhirVersionEnum;
55
import ca.uhn.fhir.rest.client.apache.ApacheRestfulClientFactory;
6+
import ca.uhn.fhir.rest.client.api.IRestfulClientFactory;
67
import ca.uhn.fhir.test.BaseFhirVersionParameterizedTest;
78
import org.apache.http.HttpResponse;
89
import org.apache.http.client.HttpClient;
910
import org.apache.http.client.methods.HttpGet;
1011
import org.apache.http.client.methods.HttpUriRequest;
1112
import org.apache.http.util.EntityUtils;
1213
import org.hl7.fhir.instance.model.api.IBaseResource;
14+
import org.junit.jupiter.api.Test;
1315
import org.junit.jupiter.params.ParameterizedTest;
1416
import org.junit.jupiter.params.provider.MethodSource;
1517

@@ -79,4 +81,13 @@ public void testGenericClientHttpsNoCredentials(FhirVersionEnum theFhirVersion)
7981
assertEquals(SSLHandshakeException.class, e.getCause().getCause().getClass());
8082
}
8183
}
84+
85+
@Test
86+
public void testConnectionTimeToLive() {
87+
ApacheRestfulClientFactory clientFactory = new ApacheRestfulClientFactory();
88+
89+
assertEquals(IRestfulClientFactory.DEFAULT_CONNECTION_TTL, clientFactory.getConnectionTimeToLive());
90+
clientFactory.setConnectionTimeToLive(25000);
91+
assertEquals(25000, clientFactory.getConnectionTimeToLive());
92+
}
8293
}

Diff for: hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/client/HapiFhirCliRestfulClientFactoryTest.java

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import ca.uhn.fhir.context.FhirContext;
44
import ca.uhn.fhir.context.FhirVersionEnum;
55
import ca.uhn.fhir.i18n.Msg;
6+
import ca.uhn.fhir.rest.client.api.IRestfulClientFactory;
67
import ca.uhn.fhir.test.BaseFhirVersionParameterizedTest;
78
import org.apache.http.HttpResponse;
89
import org.apache.http.client.HttpClient;
@@ -159,4 +160,15 @@ public void testSetProxy(FhirVersionEnum theFhirVersion){
159160
}
160161
}
161162

163+
@ParameterizedTest
164+
@MethodSource("baseParamsProvider")
165+
public void testConnectionTimeToLive(FhirVersionEnum theFhirVersion) {
166+
FhirVersionParams fhirVersionParams = getFhirVersionParams(theFhirVersion);
167+
HapiFhirCliRestfulClientFactory clientFactory = new HapiFhirCliRestfulClientFactory(fhirVersionParams.getFhirContext());
168+
169+
assertEquals(IRestfulClientFactory.DEFAULT_CONNECTION_TTL, clientFactory.getConnectionTimeToLive());
170+
clientFactory.setConnectionTimeToLive(25000);
171+
assertEquals(25000, clientFactory.getConnectionTimeToLive());
172+
}
173+
162174
}

Diff for: hapi-fhir-client-okhttp/src/main/java/ca/uhn/fhir/okhttp/client/OkHttpRestfulClientFactory.java

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import ca.uhn.fhir.rest.client.api.IHttpClient;
2626
import ca.uhn.fhir.rest.client.impl.RestfulClientFactory;
2727
import okhttp3.Call;
28+
import okhttp3.ConnectionPool;
2829
import okhttp3.OkHttpClient;
2930

3031
import java.net.InetSocketAddress;
@@ -65,6 +66,7 @@ public synchronized Call.Factory getNativeClient() {
6566
myNativeClient = new OkHttpClient()
6667
.newBuilder()
6768
.connectTimeout(getConnectTimeout(), TimeUnit.MILLISECONDS)
69+
.connectionPool(new ConnectionPool(5, getConnectionTimeToLive(), TimeUnit.MILLISECONDS))
6870
.readTimeout(getSocketTimeout(), TimeUnit.MILLISECONDS)
6971
.writeTimeout(getSocketTimeout(), TimeUnit.MILLISECONDS)
7072
.build();

Diff for: hapi-fhir-client-okhttp/src/test/java/ca/uhn/fhir/okhttp/OkHttpRestfulClientFactoryTest.java

+8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import ca.uhn.fhir.context.FhirContext;
44
import ca.uhn.fhir.context.FhirVersionEnum;
55
import ca.uhn.fhir.okhttp.client.OkHttpRestfulClientFactory;
6+
import ca.uhn.fhir.rest.client.api.IRestfulClientFactory;
67
import ca.uhn.fhir.test.BaseFhirVersionParameterizedTest;
78
import okhttp3.Call;
89
import okhttp3.OkHttpClient;
@@ -71,6 +72,13 @@ public void testConnectTimeout() {
7172
assertEquals(1516, ((OkHttpClient) clientFactory.getNativeClient()).connectTimeoutMillis());
7273
}
7374

75+
@Test
76+
public void testConnectionTimeToLive() {
77+
assertEquals(IRestfulClientFactory.DEFAULT_CONNECTION_TTL, clientFactory.getConnectionTimeToLive());
78+
clientFactory.setConnectionTimeToLive(25000);
79+
assertEquals(25000, clientFactory.getConnectionTimeToLive());
80+
}
81+
7482
@ParameterizedTest
7583
@MethodSource("baseParamsProvider")
7684
public void testNativeClientHttp(FhirVersionEnum theFhirVersion) throws Exception {

Diff for: hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheRestfulClientFactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public HttpClient getNativeHttpClient() {
103103
.disableCookieManagement();
104104

105105
PoolingHttpClientConnectionManager connectionManager =
106-
new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
106+
new PoolingHttpClientConnectionManager(getConnectionTimeToLive(), TimeUnit.MILLISECONDS);
107107
connectionManager.setMaxTotal(getPoolMaxTotal());
108108
connectionManager.setDefaultMaxPerRoute(getPoolMaxPerRoute());
109109
builder.setConnectionManager(connectionManager);

Diff for: hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/RestfulClientFactory.java

+12
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
5757
private final Set<String> myValidatedServerBaseUrls = Collections.synchronizedSet(new HashSet<>());
5858
private int myConnectionRequestTimeout = DEFAULT_CONNECTION_REQUEST_TIMEOUT;
5959
private int myConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
60+
private int myConnectionTimeToLive = DEFAULT_CONNECTION_TTL;
6061
private FhirContext myContext;
6162
private final Map<Class<? extends IRestfulClient>, ClientInvocationHandlerFactory> myInvocationHandlers =
6263
new HashMap<>();
@@ -91,6 +92,11 @@ public synchronized int getConnectTimeout() {
9192
return myConnectTimeout;
9293
}
9394

95+
@Override
96+
public synchronized int getConnectionTimeToLive() {
97+
return myConnectionTimeToLive;
98+
}
99+
94100
/**
95101
* Return the proxy username to authenticate with the HTTP proxy
96102
*/
@@ -210,6 +216,12 @@ public synchronized void setConnectTimeout(int theConnectTimeout) {
210216
resetHttpClient();
211217
}
212218

219+
@Override
220+
public synchronized void setConnectionTimeToLive(int theConnectionTimeToLive) {
221+
myConnectionTimeToLive = theConnectionTimeToLive;
222+
resetHttpClient();
223+
}
224+
213225
/**
214226
* Sets the context associated with this client factory. Must not be called more than once.
215227
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
type: add
3+
issue: 6184
4+
title: "Added a configuration setting for the TTL of HTTP connections to IRestfulClientFactory.
5+
The following implementations have been updated to respect this new setting:
6+
1. ApacheRestfulClientFactory
7+
2. OkHttpRestfulClientFactory
8+
3. HapiFhirCliRestfulClientFactory
9+
Thanks to Alex Kopp and Alex Cote for the contribution!
10+
"

Diff for: pom.xml

+15-9
Original file line numberDiff line numberDiff line change
@@ -919,15 +919,21 @@
919919
<id>adriennesox</id>
920920
<name>Adrienne Sox</name>
921921
<organization>Galileo, Inc.</organization>
922-
</developer>
923-
<developer>
924-
<id>melihaydogd</id>
925-
<name>Ahmet Melih Aydoğdu</name>
926-
</developer>
927-
<developer>
928-
<id>alexrkopp</id>
929-
<name>Alex Kopp</name>
930-
</developer>
922+
</developer>
923+
<developer>
924+
<id>melihaydogd</id>
925+
<name>Ahmet Melih Aydoğdu</name>
926+
</developer>
927+
<developer>
928+
<id>alexrkopp</id>
929+
<name>Alex Kopp</name>
930+
<organization>athenahealth</organization>
931+
</developer>
932+
<developer>
933+
<id>acoteathn</id>
934+
<name>Alex Cote</name>
935+
<organization>athenahealth</organization>
936+
</developer>
931937
</developers>
932938

933939
<licenses>

0 commit comments

Comments
 (0)