diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/configdto/HttpClientConfigurationDTO.java b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/configdto/HttpClientConfigurationDTO.java index 1c1509848dac..c21ab71c4571 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/configdto/HttpClientConfigurationDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/configdto/HttpClientConfigurationDTO.java @@ -30,6 +30,7 @@ public class HttpClientConfigurationDTO { private int connectionLimit; private int maximumConnectionsPerRoute; + private int connectionTimeout; private boolean proxyEnabled; private String proxyHost; private int proxyPort; @@ -87,6 +88,10 @@ public SSLContext getSslContext() { return sslContext; } + public int getConnectionTimeout() { + return connectionTimeout; + } + /** * Builder class for @code{HTTPClientConfigurationDTO} */ @@ -94,6 +99,7 @@ public static class Builder { private int connectionLimit; private int maximumConnectionsPerRoute; + private int connectionTimeout; private boolean proxyEnabled; private String proxyHost; private int proxyPort; @@ -104,9 +110,11 @@ public static class Builder { private SSLContext sslContext; private HostnameVerifier hostnameVerifier; - public Builder withConnectionParams(int connectionLimit, int maximumConnectionsPerRoute) { + public Builder withConnectionParams(int connectionLimit, int maximumConnectionsPerRoute, + int connectionTimeout) { this.connectionLimit = connectionLimit; this.maximumConnectionsPerRoute = maximumConnectionsPerRoute; + this.connectionTimeout = connectionTimeout; return this; } @@ -138,6 +146,7 @@ public HttpClientConfigurationDTO build() { HttpClientConfigurationDTO configuration = new HttpClientConfigurationDTO(); configuration.connectionLimit = this.connectionLimit; configuration.maximumConnectionsPerRoute = this.maximumConnectionsPerRoute; + configuration.connectionTimeout = this.connectionTimeout; configuration.proxyEnabled = this.proxyEnabled; configuration.proxyHost = this.proxyHost; configuration.proxyPort = this.proxyPort; diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/util/CommonAPIUtil.java b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/util/CommonAPIUtil.java index 1e81d9a67cce..fecb7f3f1945 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/util/CommonAPIUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/util/CommonAPIUtil.java @@ -84,6 +84,7 @@ public static HttpClient getHttpClient(String protocol, HttpClientConfigurationD int maxTotal = clientConfiguration.getConnectionLimit(); int defaultMaxPerRoute = clientConfiguration.getMaximumConnectionsPerRoute(); + int connectionTimeout = clientConfiguration.getConnectionTimeout(); boolean proxyEnabled = clientConfiguration.isProxyEnabled(); String proxyHost = clientConfiguration.getProxyHost(); @@ -102,7 +103,10 @@ public static HttpClient getHttpClient(String protocol, HttpClientConfigurationD pool.setMaxTotal(maxTotal); pool.setDefaultMaxPerRoute(defaultMaxPerRoute); - RequestConfig params = RequestConfig.custom().build(); + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + requestConfigBuilder.setConnectTimeout(connectionTimeout); + RequestConfig params = requestConfigBuilder.build(); + HttpClientBuilder clientBuilder = HttpClients.custom().setConnectionManager(pool) .setDefaultRequestConfig(params); diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/CommonAPIUtilTestCase.java b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/CommonAPIUtilTestCase.java index cdadcaab1256..7ad16899b411 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/CommonAPIUtilTestCase.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/CommonAPIUtilTestCase.java @@ -38,6 +38,7 @@ public class CommonAPIUtilTestCase { private static ClientAndServer proxyServer; int connectionLimit = 100; int maximumConnectionsPerRoute = 10; + int connectionTimeout = -1; static String trustStorePath = Objects.requireNonNull(CommonAPIUtilTestCase.class.getClassLoader() .getResource("client-truststore.jks")).getPath(); static String trustStorePassword = "wso2carbon"; @@ -91,7 +92,7 @@ public void testGetHttpClientWithProxy() { // directly to the backend. HttpGet httpGetWithTLS = new HttpGet("http://localhost:" + mockServer.getPort() + "/hello"); HttpClientConfigurationDTO nonProxyHostBasedProxyConfig = builder - .withConnectionParams(connectionLimit, maximumConnectionsPerRoute) + .withConnectionParams(connectionLimit, maximumConnectionsPerRoute, connectionTimeout) .withSSLContext(sslContext) // proxyProtocol here is https (due to existing limitation) .withProxy(proxyHost, proxyServer.getPort(), proxyUsername, "random", proxyProtocol, @@ -109,7 +110,7 @@ public void testGetHttpClientWithProxy() { // Given the proxy configuration, checks if the call is successfully routed via the proxy server. HttpClientConfigurationDTO configuration = builder - .withConnectionParams(connectionLimit, maximumConnectionsPerRoute) + .withConnectionParams(connectionLimit, maximumConnectionsPerRoute, connectionTimeout) .withSSLContext(sslContext) .withProxy(proxyHost, proxyServer.getPort(), proxyUsername, proxyPassword, proxyProtocol, nonProxyHosts) .build(); @@ -129,7 +130,7 @@ public void testGetHttpClientWithProxy() { // Given the proxy configuration with wrong credentials, checks if the call fails at the proxy server. HttpClientConfigurationDTO configWithWrongProxyCredentials = builder - .withConnectionParams(connectionLimit, maximumConnectionsPerRoute) + .withConnectionParams(connectionLimit, maximumConnectionsPerRoute, connectionTimeout) .withSSLContext(sslContext) .withProxy(proxyHost, proxyServer.getPort(), proxyUsername, "random", proxyProtocol, nonProxyHosts) .build(); @@ -148,7 +149,7 @@ public void testGetHttpClientWithoutProxy() { HttpGet httpsGet = new HttpGet("https://localhost:" + mockServer.getPort() + "/hello"); HttpClientConfigurationDTO.Builder builder = new HttpClientConfigurationDTO.Builder(); HttpClientConfigurationDTO configuration = builder - .withConnectionParams(connectionLimit, maximumConnectionsPerRoute) + .withConnectionParams(connectionLimit, maximumConnectionsPerRoute, connectionTimeout) .withSSLContext(sslContext) .build(); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java index ce60e1a1db09..85c06021182c 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java @@ -1512,6 +1512,7 @@ private OAuthConstants() { public static final String HTTP_CLIENT_MAX_TOTAL = "HttpClient.MaxTotal"; public static final String HTTP_CLIENT_DEFAULT_MAX_PER_ROUTE = "HttpClient.DefaultMaxPerRoute"; + public static final String HTTP_CLIENT_CONNECTION_TIMEOUT = "HttpClient.ConnectionTimeout"; public static final String PROXY_ENABLE = "ProxyConfig.Enable"; public static final String PROXY_HOST = "ProxyConfig.Host"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java index c2094d7d88af..e51d713d8505 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java @@ -1022,6 +1022,7 @@ void populateHttpClientConfiguration() { int maxTotal = Integer.parseInt(configuration.getFirstProperty(APIConstants.HTTP_CLIENT_MAX_TOTAL)); int defaultMaxPerRoute = Integer.parseInt(configuration.getFirstProperty(APIConstants.HTTP_CLIENT_DEFAULT_MAX_PER_ROUTE)); + int connectionTimeout = Integer.parseInt(configuration.getFirstProperty(APIConstants.HTTP_CLIENT_CONNECTION_TIMEOUT)); boolean proxyEnabled = Boolean.parseBoolean(configuration.getFirstProperty(APIConstants.PROXY_ENABLE)); @@ -1071,7 +1072,8 @@ public boolean verify(String urlHostName, SSLSession session) { default: hostnameVerifier = new BrowserHostnameVerifier(); } - configuration.setHttpClientConfiguration(builder.withConnectionParams(maxTotal, defaultMaxPerRoute) + configuration.setHttpClientConfiguration(builder + .withConnectionParams(maxTotal, defaultMaxPerRoute, connectionTimeout) .withSSLContext(sslContext, hostnameVerifier).build()); } diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json index ffb63ced22be..ad67edf92bc7 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json @@ -55,6 +55,7 @@ "apim.api_quota_limit.enable": false, "apim.http_client.max_total": "100", "apim.http_client.default_max_per_route": "50", + "apim.http_client.connection_timeout": "-1", "apim.key_manager.service_url": "https://localhost:${mgt.transport.https.port}${carbon.context}services/", "apim.key_manager.username": "${admin.username}", "apim.key_manager.password": "${admin.password}", diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 index b19e9bd78070..1607b483efbc 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 @@ -19,6 +19,7 @@ {{apim.http_client.max_total}} {{apim.http_client.default_max_per_route}} + {{apim.http_client.connection_timeout}}