aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/juick/config/HttpClientConfig.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/juick/config/HttpClientConfig.java')
-rw-r--r--src/main/java/com/juick/config/HttpClientConfig.java111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/main/java/com/juick/config/HttpClientConfig.java b/src/main/java/com/juick/config/HttpClientConfig.java
new file mode 100644
index 00000000..0b23ca15
--- /dev/null
+++ b/src/main/java/com/juick/config/HttpClientConfig.java
@@ -0,0 +1,111 @@
+package com.juick.config;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.http.HeaderElement;
+import org.apache.http.HeaderElementIterator;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.config.CookieSpecs;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
+
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.message.BasicHeaderElementIterator;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.protocol.HttpContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+/**
+ * - Uses a connection pool to re-use connections and save overhead of creating connections.
+ * - Has a custom connection keep-alive strategy (to apply a default keep-alive if one isn't specified)
+ * - Starts an idle connection monitor to continuously clean up stale connections.
+ */
+@Configuration
+public class HttpClientConfig {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientConfig.class);
+
+ // Determines the timeout in milliseconds until a connection is established.
+ private static final int CONNECT_TIMEOUT = 30000;
+
+ // The timeout when requesting a connection from the connection manager.
+ private static final int REQUEST_TIMEOUT = 30000;
+
+ // The timeout for waiting for data
+ private static final int SOCKET_TIMEOUT = 60000;
+
+ private static final int MAX_TOTAL_CONNECTIONS = 50;
+ private static final int DEFAULT_KEEP_ALIVE_TIME_MILLIS = 20 * 1000;
+ private static final int CLOSE_IDLE_CONNECTION_WAIT_TIME_SECS = 30;
+
+ @Bean
+ public PoolingHttpClientConnectionManager poolingConnectionManager() {
+ PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager();
+ poolingConnectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
+ return poolingConnectionManager;
+ }
+
+ @Bean
+ public ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
+ return new ConnectionKeepAliveStrategy() {
+ @Override
+ public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
+ HeaderElementIterator it = new BasicHeaderElementIterator
+ (response.headerIterator(HTTP.CONN_KEEP_ALIVE));
+ while (it.hasNext()) {
+ HeaderElement he = it.nextElement();
+ String param = he.getName();
+ String value = he.getValue();
+
+ if (value != null && param.equalsIgnoreCase("timeout")) {
+ return Long.parseLong(value) * 1000;
+ }
+ }
+ return DEFAULT_KEEP_ALIVE_TIME_MILLIS;
+ }
+ };
+ }
+
+ @Bean
+ public CloseableHttpClient httpClient() {
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setCookieSpec(CookieSpecs.IGNORE_COOKIES)
+ .setConnectionRequestTimeout(REQUEST_TIMEOUT)
+ .setConnectTimeout(CONNECT_TIMEOUT)
+ .setSocketTimeout(SOCKET_TIMEOUT).build();
+
+ return HttpClients.custom()
+ .setDefaultRequestConfig(requestConfig)
+ .setConnectionManager(poolingConnectionManager())
+ .setKeepAliveStrategy(connectionKeepAliveStrategy())
+ .build();
+ }
+
+ @Bean
+ public Runnable idleConnectionMonitor(final PoolingHttpClientConnectionManager connectionManager) {
+ return new Runnable() {
+ @Override
+ @Scheduled(fixedDelay = 10000)
+ public void run() {
+ try {
+ if (connectionManager != null) {
+ LOGGER.trace("run IdleConnectionMonitor - Closing expired and idle connections...");
+ connectionManager.closeExpiredConnections();
+ connectionManager.closeIdleConnections(CLOSE_IDLE_CONNECTION_WAIT_TIME_SECS, TimeUnit.SECONDS);
+ } else {
+ LOGGER.trace("run IdleConnectionMonitor - Http Client Connection manager is not initialised");
+ }
+ } catch (Exception e) {
+ LOGGER.error("run IdleConnectionMonitor - Exception occurred. msg={}, e={}", e.getMessage(), e);
+ }
+ }
+ };
+ }
+} \ No newline at end of file