Skip to content

Commit c7d04ab

Browse files
namedgraphclaude
andcommitted
Make HTTP client connectionRequestTimeout configurable
Defaults to 30000 ms (via Dockerfile ENV). Passed through the CATALINA_OPTS path (same as allowInternalUrls) to avoid exceeding the ~30-param libxslt limit already reached by context.xsl. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 845ce0d commit c7d04ab

File tree

5 files changed

+27
-13
lines changed

5 files changed

+27
-13
lines changed

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ ENV MAX_TOTAL_CONN=40
109109

110110
ENV MAX_REQUEST_RETRIES=3
111111

112+
ENV CONNECTION_REQUEST_TIMEOUT=30000
113+
112114
ENV IMPORT_KEEPALIVE=
113115

114116
ENV MAX_IMPORT_THREADS=10

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ services:
6565
- SIGN_UP_CERT_VALIDITY=180
6666
- MAX_CONTENT_LENGTH=${MAX_CONTENT_LENGTH:-2097152}
6767
- ALLOW_INTERNAL_URLS=${ALLOW_INTERNAL_URLS:-}
68+
- CONNECTION_REQUEST_TIMEOUT=${CONNECTION_REQUEST_TIMEOUT:-}
6869
- NOTIFICATION_ADDRESS=LinkedDataHub <notifications@localhost>
6970
- MAIL_SMTP_HOST=email-server
7071
- MAIL_SMTP_PORT=25

platform/entrypoint.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,10 @@ if [ -n "$ALLOW_INTERNAL_URLS" ]; then
10371037
export CATALINA_OPTS="$CATALINA_OPTS -Dcom.atomgraph.linkeddatahub.allowInternalUrls=$ALLOW_INTERNAL_URLS"
10381038
fi
10391039

1040+
if [ -n "$CONNECTION_REQUEST_TIMEOUT" ]; then
1041+
export CATALINA_OPTS="$CATALINA_OPTS -Dcom.atomgraph.linkeddatahub.connectionRequestTimeout=$CONNECTION_REQUEST_TIMEOUT"
1042+
fi
1043+
10401044
if [ -n "$MAX_CONTENT_LENGTH" ]; then
10411045
MAX_CONTENT_LENGTH_PARAM="--stringparam ldhc:maxContentLength '$MAX_CONTENT_LENGTH' "
10421046
fi

src/main/java/com/atomgraph/linkeddatahub/Application.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,8 @@ public Application(@Context ServletConfig servletConfig) throws URISyntaxExcepti
359359
servletConfig.getServletContext().getInitParameter(LDHC.maxConnPerRoute.getURI()) != null ? Integer.valueOf(servletConfig.getServletContext().getInitParameter(LDHC.maxConnPerRoute.getURI())) : null,
360360
servletConfig.getServletContext().getInitParameter(LDHC.maxTotalConn.getURI()) != null ? Integer.valueOf(servletConfig.getServletContext().getInitParameter(LDHC.maxTotalConn.getURI())) : null,
361361
servletConfig.getServletContext().getInitParameter(LDHC.maxRequestRetries.getURI()) != null ? Integer.valueOf(servletConfig.getServletContext().getInitParameter(LDHC.maxRequestRetries.getURI())) : null,
362+
System.getProperty("com.atomgraph.linkeddatahub.connectionRequestTimeout") != null ? Integer.valueOf(System.getProperty("com.atomgraph.linkeddatahub.connectionRequestTimeout")) :
363+
servletConfig.getServletContext().getInitParameter(LDHC.connectionRequestTimeout.getURI()) != null ? Integer.valueOf(servletConfig.getServletContext().getInitParameter(LDHC.connectionRequestTimeout.getURI())) : null,
362364
servletConfig.getServletContext().getInitParameter(LDHC.maxImportThreads.getURI()) != null ? Integer.valueOf(servletConfig.getServletContext().getInitParameter(LDHC.maxImportThreads.getURI())) : null,
363365
servletConfig.getServletContext().getInitParameter(LDHC.notificationAddress.getURI()) != null ? servletConfig.getServletContext().getInitParameter(LDHC.notificationAddress.getURI()) : null,
364366
servletConfig.getServletContext().getInitParameter(LDHC.supportedLanguages.getURI()) != null ? servletConfig.getServletContext().getInitParameter(LDHC.supportedLanguages.getURI()) : null,
@@ -446,7 +448,7 @@ public Application(final ServletConfig servletConfig, final MediaTypes mediaType
446448
final String baseURIString, final String proxyScheme, final String proxyHostname, final Integer proxyPort,
447449
final String uploadRootString, final boolean invalidateCache,
448450
final Integer cookieMaxAge, final boolean enableLinkedDataProxy, final boolean allowInternalUrls, final Integer maxContentLength,
449-
final Integer maxConnPerRoute, final Integer maxTotalConn, final Integer maxRequestRetries, final Integer maxImportThreads,
451+
final Integer maxConnPerRoute, final Integer maxTotalConn, final Integer maxRequestRetries, final Integer connectionRequestTimeout, final Integer maxImportThreads,
450452
final String notificationAddressString, final String supportedLanguageCodes, final boolean enableWebIDSignUp, final String oidcRefreshTokensPropertiesPath,
451453
final String frontendProxyString, final String backendProxyAdminString, final String backendProxyEndUserString,
452454
final String mailUser, final String mailPassword, final String smtpHost, final String smtpPort,
@@ -710,10 +712,10 @@ public Application(final ServletConfig servletConfig, final MediaTypes mediaType
710712
trustStore.load(trustStoreInputStream, clientTrustStorePassword.toCharArray());
711713
}
712714

713-
client = getClient(keyStore, clientKeyStorePassword, trustStore, maxConnPerRoute, maxTotalConn, null, false);
714-
externalClient = getClient(keyStore, clientKeyStorePassword, trustStore, maxConnPerRoute, maxTotalConn, null, false);
715-
importClient = getClient(keyStore, clientKeyStorePassword, trustStore, maxConnPerRoute, maxTotalConn, maxRequestRetries, true);
716-
noCertClient = getNoCertClient(trustStore, maxConnPerRoute, maxTotalConn, maxRequestRetries);
715+
client = getClient(keyStore, clientKeyStorePassword, trustStore, maxConnPerRoute, maxTotalConn, null, false, connectionRequestTimeout);
716+
externalClient = getClient(keyStore, clientKeyStorePassword, trustStore, maxConnPerRoute, maxTotalConn, null, false, connectionRequestTimeout);
717+
importClient = getClient(keyStore, clientKeyStorePassword, trustStore, maxConnPerRoute, maxTotalConn, maxRequestRetries, true, connectionRequestTimeout);
718+
noCertClient = getNoCertClient(trustStore, maxConnPerRoute, maxTotalConn, maxRequestRetries, connectionRequestTimeout);
717719

718720
if (maxContentLength != null)
719721
{
@@ -1528,7 +1530,7 @@ public void submitImport(RDFImport rdfImport, com.atomgraph.linkeddatahub.apps.m
15281530
* @throws UnrecoverableKeyException key loading error
15291531
* @throws KeyManagementException key loading error
15301532
*/
1531-
public static Client getClient(KeyStore keyStore, String keyStorePassword, KeyStore trustStore, Integer maxConnPerRoute, Integer maxTotalConn, Integer maxRequestRetries, boolean buffered) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException
1533+
public static Client getClient(KeyStore keyStore, String keyStorePassword, KeyStore trustStore, Integer maxConnPerRoute, Integer maxTotalConn, Integer maxRequestRetries, boolean buffered, Integer connectionRequestTimeout) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException
15321534
{
15331535
if (keyStore == null) throw new IllegalArgumentException("KeyStore cannot be null");
15341536
if (keyStorePassword == null) throw new IllegalArgumentException("KeyStore password string cannot be null");
@@ -1593,9 +1595,10 @@ public void releaseConnection(final HttpClientConnection managedConn, final Obje
15931595
config.property(ClientProperties.FOLLOW_REDIRECTS, true);
15941596
config.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.BUFFERED); // https://stackoverflow.com/questions/42139436/jersey-client-throws-cannot-retry-request-with-a-non-repeatable-request-entity
15951597
config.property(ApacheClientProperties.CONNECTION_MANAGER, conman);
1596-
config.property(ApacheClientProperties.REQUEST_CONFIG, RequestConfig.custom().
1597-
setConnectionRequestTimeout(30000).
1598-
build());
1598+
if (connectionRequestTimeout != null)
1599+
config.property(ApacheClientProperties.REQUEST_CONFIG, RequestConfig.custom().
1600+
setConnectionRequestTimeout(connectionRequestTimeout).
1601+
build());
15991602

16001603
if (maxRequestRetries != null)
16011604
config.property(ApacheClientProperties.RETRY_HANDLER, (HttpRequestRetryHandler) (IOException ex, int executionCount, HttpContext context) ->
@@ -1633,7 +1636,7 @@ public void releaseConnection(final HttpClientConnection managedConn, final Obje
16331636
* @param maxRequestRetries maximum number of times that the HTTP client will retry a request
16341637
* @return client instance
16351638
*/
1636-
public static Client getNoCertClient(KeyStore trustStore, Integer maxConnPerRoute, Integer maxTotalConn, Integer maxRequestRetries)
1639+
public static Client getNoCertClient(KeyStore trustStore, Integer maxConnPerRoute, Integer maxTotalConn, Integer maxRequestRetries, Integer connectionRequestTimeout)
16371640
{
16381641
try
16391642
{
@@ -1692,9 +1695,10 @@ public void releaseConnection(final HttpClientConnection managedConn, final Obje
16921695
config.property(ClientProperties.FOLLOW_REDIRECTS, true);
16931696
config.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.BUFFERED); // https://stackoverflow.com/questions/42139436/jersey-client-throws-cannot-retry-request-with-a-non-repeatable-request-entity
16941697
config.property(ApacheClientProperties.CONNECTION_MANAGER, conman);
1695-
config.property(ApacheClientProperties.REQUEST_CONFIG, RequestConfig.custom().
1696-
setConnectionRequestTimeout(30000).
1697-
build());
1698+
if (connectionRequestTimeout != null)
1699+
config.property(ApacheClientProperties.REQUEST_CONFIG, RequestConfig.custom().
1700+
setConnectionRequestTimeout(connectionRequestTimeout).
1701+
build());
16981702

16991703
if (maxRequestRetries != null)
17001704
config.property(ApacheClientProperties.RETRY_HANDLER, (HttpRequestRetryHandler) (IOException ex, int executionCount, HttpContext context) ->

src/main/java/com/atomgraph/linkeddatahub/vocabulary/LDHC.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ public static String getURI()
152152
/** HTTP client request retry count */
153153
public static final DatatypeProperty maxRequestRetries = m_model.createDatatypeProperty( NS + "maxRequestRetries" );
154154

155+
/** Timeout in milliseconds waiting for a connection from the HTTP client pool */
156+
public static final DatatypeProperty connectionRequestTimeout = m_model.createDatatypeProperty( NS + "connectionRequestTimeout" );
157+
155158
/** Max content length property */
156159
public static final DatatypeProperty maxContentLength = m_model.createDatatypeProperty( NS + "maxContentLength" );
157160

0 commit comments

Comments
 (0)