171171import com .atomgraph .spinrdf .vocabulary .SP ;
172172import com .github .jsonldjava .core .DocumentLoader ;
173173import com .github .jsonldjava .core .JsonLdOptions ;
174+ import jakarta .inject .Inject ;
174175import java .io .FileOutputStream ;
175176import java .io .UnsupportedEncodingException ;
176177import java .nio .charset .StandardCharsets ;
192193import jakarta .ws .rs .client .Client ;
193194import jakarta .ws .rs .client .ClientBuilder ;
194195import jakarta .ws .rs .client .ClientRequestFilter ;
196+ import java .util .concurrent .ScheduledExecutorService ;
195197import javax .xml .transform .TransformerException ;
196198import javax .xml .transform .stream .StreamSource ;
197199import net .jodah .expiringmap .ExpiringMap ;
230232import org .glassfish .hk2 .utilities .binding .AbstractBinder ;
231233import org .glassfish .jersey .client .ClientConfig ;
232234import org .glassfish .jersey .apache .connector .ApacheClientProperties ;
233- import org .glassfish .jersey .apache .connector .ApacheConnectionClosingStrategy ;
234235import org .glassfish .jersey .apache .connector .ApacheConnectorProvider ;
235236import org .glassfish .jersey .client .ClientProperties ;
236237import org .glassfish .jersey .client .RequestEntityProcessing ;
@@ -251,6 +252,7 @@ public class Application extends ResourceConfig
251252
252253 private static final Logger log = LoggerFactory .getLogger (Application .class );
253254
255+ private @ Inject ScheduledExecutorService idleConnectionMonitor ;
254256 private final ExecutorService importThreadPool ;
255257 private final ServletConfig servletConfig ;
256258 private final EventBus eventBus = new EventBus ();
@@ -623,10 +625,10 @@ public Application(final ServletConfig servletConfig, final MediaTypes mediaType
623625 trustStore = KeyStore .getInstance ("JKS" );
624626 trustStore .load (new FileInputStream (new java .io .File (new URI (clientTrustStoreURIString ))), clientTrustStorePassword .toCharArray ());
625627
626- client = getClient (keyStore , clientKeyStorePassword , trustStore , maxConnPerRoute , maxTotalConn , null , false );
627- externalClient = getClient (keyStore , clientKeyStorePassword , trustStore , maxConnPerRoute , maxTotalConn , null , false );
628- importClient = getClient (keyStore , clientKeyStorePassword , trustStore , maxConnPerRoute , maxTotalConn , importKeepAliveStrategy , true );
629- noCertClient = getNoCertClient (trustStore , maxConnPerRoute , maxTotalConn );
628+ client = createClient (keyStore , clientKeyStorePassword , trustStore , maxConnPerRoute , maxTotalConn , null , false );
629+ externalClient = createClient (keyStore , clientKeyStorePassword , trustStore , maxConnPerRoute , maxTotalConn , null , false );
630+ importClient = createClient (keyStore , clientKeyStorePassword , trustStore , maxConnPerRoute , maxTotalConn , importKeepAliveStrategy , true );
631+ noCertClient = createNoCertClient (trustStore , maxConnPerRoute , maxTotalConn );
630632
631633 if (maxContentLength != null )
632634 {
@@ -1331,7 +1333,7 @@ public void submitImport(RDFImport rdfImport, com.atomgraph.linkeddatahub.apps.m
13311333 * @throws UnrecoverableKeyException key loading error
13321334 * @throws KeyManagementException key loading error
13331335 */
1334- public static Client getClient (KeyStore keyStore , String keyStorePassword , KeyStore trustStore , Integer maxConnPerRoute , Integer maxTotalConn , ConnectionKeepAliveStrategy keepAliveStrategy , boolean buffered ) throws NoSuchAlgorithmException , KeyStoreException , UnrecoverableKeyException , KeyManagementException
1336+ public Client createClient (KeyStore keyStore , String keyStorePassword , KeyStore trustStore , Integer maxConnPerRoute , Integer maxTotalConn , ConnectionKeepAliveStrategy keepAliveStrategy , boolean buffered ) throws NoSuchAlgorithmException , KeyStoreException , UnrecoverableKeyException , KeyManagementException
13351337 {
13361338 if (keyStore == null ) throw new IllegalArgumentException ("KeyStore cannot be null" );
13371339 if (keyStorePassword == null ) throw new IllegalArgumentException ("KeyStore password string cannot be null" );
@@ -1417,7 +1419,7 @@ public void releaseConnection(final HttpClientConnection managedConn, final Obje
14171419 * @param maxTotalConn max total connections
14181420 * @return client instance
14191421 */
1420- public static Client getNoCertClient (KeyStore trustStore , Integer maxConnPerRoute , Integer maxTotalConn )
1422+ public Client createNoCertClient (KeyStore trustStore , Integer maxConnPerRoute , Integer maxTotalConn )
14211423 {
14221424 try
14231425 {
@@ -1465,7 +1467,22 @@ public void releaseConnection(final HttpClientConnection managedConn, final Obje
14651467 if (maxConnPerRoute != null ) conman .setDefaultMaxPerRoute (maxConnPerRoute );
14661468 if (maxTotalConn != null ) conman .setMaxTotal (maxTotalConn );
14671469 conman .setValidateAfterInactivity (5000 ); // check connections idle for more than Varnish's idle_timeout which is 5s
1468-
1470+
1471+ Integer idleConnTimeout = 5000 ;
1472+ // create monitor thread that evicts idle connections: https://hc.apache.org/httpcomponents-client-4.5.x/current/tutorial/html/connmgmt.html#d5e418
1473+ idleConnectionMonitor .scheduleAtFixedRate (() ->
1474+ {
1475+ try
1476+ {
1477+ if (log .isDebugEnabled ()) log .debug ("Evicting idle HTTP connections (every {} ms)" , idleConnTimeout );
1478+ conman .closeIdleConnections (idleConnTimeout , TimeUnit .MILLISECONDS );
1479+ }
1480+ catch (Exception ex )
1481+ {
1482+ if (log .isErrorEnabled ()) log .error ("Error closing idle connections: {}" , ex );
1483+ }
1484+ }, 0 , idleConnTimeout , java .util .concurrent .TimeUnit .MILLISECONDS );
1485+
14691486 ClientConfig config = new ClientConfig ();
14701487 config .connectorProvider (new ApacheConnectorProvider ());
14711488 config .register (MultiPartFeature .class );
@@ -1486,17 +1503,17 @@ public void releaseConnection(final HttpClientConnection managedConn, final Obje
14861503 }
14871504 catch (NoSuchAlgorithmException ex )
14881505 {
1489- if ( log .isErrorEnabled ()) log .error ("No such algorithm: {}" , ex );
1506+ if (log .isErrorEnabled ()) log .error ("No such algorithm: {}" , ex );
14901507 throw new IllegalStateException (ex );
14911508 }
14921509 catch (KeyStoreException ex )
14931510 {
1494- if ( log .isErrorEnabled ()) log .error ("Key store error: {}" , ex );
1511+ if (log .isErrorEnabled ()) log .error ("Key store error: {}" , ex );
14951512 throw new IllegalStateException (ex );
14961513 }
14971514 catch (KeyManagementException ex )
14981515 {
1499- if ( log .isErrorEnabled ()) log .error ("Key management error: {}" , ex );
1516+ if (log .isErrorEnabled ()) log .error ("Key management error: {}" , ex );
15001517 throw new IllegalStateException (ex );
15011518 }
15021519 }
0 commit comments