Skip to content
This repository was archived by the owner on May 14, 2020. It is now read-only.

Commit e5d7c55

Browse files
author
Ruslan Malona
authored
Merge pull request #52 from Smartling/REPO-202_configure_timeouts
REPO-202 Add an option to configure HTTP settings in Files SDK
2 parents c0d6b14 + fb2fe29 commit e5d7c55

11 files changed

Lines changed: 217 additions & 148 deletions

File tree

api-sdk/src/main/java/com/smartling/api/sdk/BaseApiClient.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,25 @@ public abstract class BaseApiClient
2626

2727
private final HttpUtils httpUtils = new HttpUtils();
2828
private final ProxyConfiguration proxyConfiguration;
29+
private final HttpClientConfiguration httpClientConfiguration;
2930

3031
protected final String baseUrl;
3132

3233
protected BaseApiClient()
3334
{
34-
this(DEFAULT_BASE_URL, null);
35+
this(DEFAULT_BASE_URL, null, null);
3536
}
3637

37-
protected BaseApiClient(final String baseUrl, final ProxyConfiguration proxyConfiguration)
38+
protected BaseApiClient(final String baseUrl, final ProxyConfiguration proxyConfiguration, final HttpClientConfiguration httpClientConfiguration)
3839
{
3940
this.baseUrl = Objects.requireNonNull(baseUrl, "Base URL can not be null");
4041
this.proxyConfiguration = proxyConfiguration;
42+
this.httpClientConfiguration = httpClientConfiguration;
4143
}
4244

4345
protected StringResponse executeRequest(final HttpRequestBase request) throws SmartlingApiException
4446
{
45-
return httpUtils.executeHttpCall(request, proxyConfiguration);
47+
return httpUtils.executeHttpCall(request, proxyConfiguration, httpClientConfiguration);
4648
}
4749

4850
protected static <T extends ResponseData> Response<T> getApiV2Response(final String response, final TypeToken<ApiV2ResponseWrapper<T>> responseType) throws SmartlingApiException
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.smartling.api.sdk;
2+
3+
/**
4+
* All timeouts are in milliseconds. The defaults here are designed
5+
* for a service with a relatively low number of long running requests.
6+
*/
7+
public class HttpClientConfiguration
8+
{
9+
private int connectionRequestTimeout = 60000;
10+
private int connectionTimeout = 10000;
11+
private int socketTimeout = 10000;
12+
13+
public int getConnectionRequestTimeout()
14+
{
15+
return connectionRequestTimeout;
16+
}
17+
18+
public HttpClientConfiguration setConnectionRequestTimeout(final int connectionRequestTimeout)
19+
{
20+
this.connectionRequestTimeout = connectionRequestTimeout;
21+
return this;
22+
}
23+
24+
public int getConnectionTimeout()
25+
{
26+
return connectionTimeout;
27+
}
28+
29+
public HttpClientConfiguration setConnectionTimeout(final int connectionTimeout)
30+
{
31+
this.connectionTimeout = connectionTimeout;
32+
return this;
33+
}
34+
35+
public int getSocketTimeout()
36+
{
37+
return socketTimeout;
38+
}
39+
40+
public HttpClientConfiguration setSocketTimeout(final int socketTimeout)
41+
{
42+
this.socketTimeout = socketTimeout;
43+
return this;
44+
}
45+
46+
}

api-sdk/src/main/java/com/smartling/api/sdk/TokenProviderAwareClient.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ public abstract class TokenProviderAwareClient extends BaseApiClient
1313
{
1414
private final TokenProvider tokenProvider;
1515

16-
protected TokenProviderAwareClient(final String baseUrl, final ProxyConfiguration proxyConfiguration, TokenProvider tokenProvider)
16+
protected TokenProviderAwareClient(final String baseUrl, final ProxyConfiguration proxyConfiguration, TokenProvider tokenProvider,
17+
final HttpClientConfiguration httpClientConfiguration)
1718
{
18-
super(baseUrl, proxyConfiguration);
19+
super(baseUrl, proxyConfiguration, httpClientConfiguration);
1920
this.tokenProvider = Objects.requireNonNull(tokenProvider, "Token Provider can not be null");
2021
}
2122

api-sdk/src/main/java/com/smartling/api/sdk/auth/AuthApiClient.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.google.gson.reflect.TypeToken;
44
import com.smartling.api.sdk.BaseApiClient;
5+
import com.smartling.api.sdk.HttpClientConfiguration;
56
import com.smartling.api.sdk.ProxyConfiguration;
67
import com.smartling.api.sdk.dto.file.StringResponse;
78
import com.smartling.api.sdk.exceptions.SmartlingApiException;
@@ -30,7 +31,12 @@ public AuthApiClient(final String baseUrl)
3031

3132
public AuthApiClient(final ProxyConfiguration proxyConfiguration, final String baseUrl)
3233
{
33-
super(baseUrl, proxyConfiguration);
34+
super(baseUrl, proxyConfiguration, null);
35+
}
36+
37+
public AuthApiClient(final ProxyConfiguration proxyConfiguration, final HttpClientConfiguration httpClientConfiguration, final String baseUrl)
38+
{
39+
super(baseUrl, proxyConfiguration, httpClientConfiguration);
3440
}
3541

3642
public Response<AuthenticationContext> authenticate(String userIdentifier, String userSecret)

api-sdk/src/main/java/com/smartling/api/sdk/file/FileApiClientImpl.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.smartling.api.sdk.file;
22

33
import com.google.gson.reflect.TypeToken;
4+
import com.smartling.api.sdk.HttpClientConfiguration;
45
import com.smartling.api.sdk.ProxyConfiguration;
56
import com.smartling.api.sdk.TokenProviderAwareClient;
67
import com.smartling.api.sdk.auth.AuthApiClient;
@@ -79,9 +80,10 @@ public final class FileApiClientImpl extends TokenProviderAwareClient implements
7980

8081
private final String projectId;
8182

82-
private FileApiClientImpl(final TokenProvider tokenProvider, final String projectId, final ProxyConfiguration proxyConfiguration, final String baseUrl)
83+
private FileApiClientImpl(final TokenProvider tokenProvider, final String projectId, final ProxyConfiguration proxyConfiguration,
84+
final String baseUrl, final HttpClientConfiguration httpClientConfiguration)
8385
{
84-
super(baseUrl, proxyConfiguration, tokenProvider);
86+
super(baseUrl, proxyConfiguration, tokenProvider, httpClientConfiguration);
8587
this.projectId = Objects.requireNonNull(projectId, "Project ID can not be null");
8688
}
8789

@@ -419,6 +421,7 @@ public static class Builder
419421
private String userId;
420422
private String userSecret;
421423
private ProxyConfiguration proxyConfiguration;
424+
private HttpClientConfiguration httpClientConfiguration;
422425

423426
public Builder(String projectId)
424427
{
@@ -437,6 +440,12 @@ public Builder proxyConfiguration(ProxyConfiguration proxyConfiguration)
437440
return this;
438441
}
439442

443+
public Builder httpClientConfiguration(HttpClientConfiguration httpClientConfiguration)
444+
{
445+
this.httpClientConfiguration = httpClientConfiguration;
446+
return this;
447+
}
448+
440449
public Builder authWithUserIdAndSecret(String userId, String userSecret)
441450
{
442451
this.userId = userId;
@@ -461,10 +470,10 @@ public FileApiClient build()
461470
{
462471
TokenProvider tokenProvider = this.tokenProvider;
463472
if (tokenProvider == null && userId != null && userSecret != null) {
464-
tokenProvider = new OAuthTokenProvider(userId, userSecret, new AuthApiClient(proxyConfiguration, baseSmartlingApiUrl));
473+
tokenProvider = new OAuthTokenProvider(userId, userSecret, new AuthApiClient(proxyConfiguration, httpClientConfiguration, baseSmartlingApiUrl));
465474
}
466475

467-
return new FileApiClientImpl(tokenProvider, projectId, proxyConfiguration, baseSmartlingApiUrl);
476+
return new FileApiClientImpl(tokenProvider, projectId, proxyConfiguration, baseSmartlingApiUrl, httpClientConfiguration);
468477
}
469478
}
470479
}

api-sdk/src/main/java/com/smartling/api/sdk/util/HttpProxyUtils.java renamed to api-sdk/src/main/java/com/smartling/api/sdk/util/HttpClientFactory.java

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package com.smartling.api.sdk.util;
1717

18+
import com.smartling.api.sdk.HttpClientConfiguration;
1819
import com.smartling.api.sdk.ProxyConfiguration;
1920
import com.smartling.api.sdk.exceptions.SmartlingApiException;
2021
import org.apache.commons.lang3.StringUtils;
@@ -32,27 +33,51 @@
3233
import java.security.KeyManagementException;
3334
import java.security.NoSuchAlgorithmException;
3435

35-
class HttpProxyUtils
36+
class HttpClientFactory
3637
{
37-
HttpProxyUtils()
38+
HttpClientFactory()
3839
{
3940

4041
}
4142

4243
/**
43-
* Get a request config given the applicable request and proxy config if any
44-
* @param httpRequest request
44+
* Get an HttpClient given a proxy config if any
4545
* @param proxyConfiguration configuration of proxy to use
46-
* @return org.apache.http.client.config.RequestConfig
46+
* @param httpClientConfiguration configuration of http transport
47+
* @return org.apache.http.impl.client.CloseableHttpClient
4748
*/
48-
RequestConfig getProxyRequestConfig(HttpRequestBase httpRequest, final ProxyConfiguration proxyConfiguration)
49-
{
49+
CloseableHttpClient getHttpClient(final ProxyConfiguration proxyConfiguration, final HttpClientConfiguration httpClientConfiguration) throws SmartlingApiException {
50+
HttpClientBuilder httpClientBuilder = getHttpClientBuilder();
51+
5052
if (hasActiveProxyConfiguration(proxyConfiguration))
5153
{
52-
HttpHost proxyHttpHost = new HttpHost(proxyConfiguration.getHost(), proxyConfiguration.getPort());
53-
return RequestConfig.custom().setProxy(proxyHttpHost).build();
54+
HttpHost proxyHost = new HttpHost(proxyConfiguration.getHost(), proxyConfiguration.getPort());
55+
httpClientBuilder.setProxy(proxyHost);
56+
57+
if (proxyAuthenticationRequired(proxyConfiguration))
58+
{
59+
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
60+
credentialsProvider.setCredentials(
61+
new AuthScope(proxyConfiguration.getHost(), proxyConfiguration.getPort()),
62+
new UsernamePasswordCredentials(proxyConfiguration.getUsername(), proxyConfiguration.getPassword()));
63+
64+
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
65+
}
66+
}
67+
68+
httpClientBuilder.setSSLContext(getSSLConfig());
69+
70+
if (httpConfigurationRequired(httpClientConfiguration))
71+
{
72+
final RequestConfig defaultRequestConfig = RequestConfig.custom()
73+
.setSocketTimeout(httpClientConfiguration.getSocketTimeout())
74+
.setConnectTimeout(httpClientConfiguration.getConnectionTimeout())
75+
.setConnectionRequestTimeout(httpClientConfiguration.getConnectionRequestTimeout())
76+
.build();
77+
httpClientBuilder.setDefaultRequestConfig(defaultRequestConfig);
5478
}
55-
return null;
79+
80+
return httpClientBuilder.build();
5681
}
5782

5883
private SSLContext getSSLConfig() throws SmartlingApiException {
@@ -76,27 +101,9 @@ private void initSSLContext(SSLContext sslContext) throws SmartlingApiException
76101
}
77102
}
78103

79-
/**
80-
* Get an HttpClient given a proxy config if any
81-
* @param proxyConfiguration configuration of proxy to use
82-
* @return org.apache.http.impl.client.CloseableHttpClient
83-
*/
84-
CloseableHttpClient getHttpClient(final ProxyConfiguration proxyConfiguration) throws SmartlingApiException {
85-
HttpClientBuilder httpClientBuilder = getHttpClientBuilder();
86-
87-
if (proxyAuthenticationRequired(proxyConfiguration))
88-
{
89-
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
90-
credentialsProvider.setCredentials(
91-
new AuthScope(proxyConfiguration.getHost(), proxyConfiguration.getPort()),
92-
new UsernamePasswordCredentials(proxyConfiguration.getUsername(), proxyConfiguration.getPassword()));
93-
94-
httpClientBuilder = httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
95-
}
96-
97-
httpClientBuilder.setSSLContext(getSSLConfig());
98-
99-
return httpClientBuilder.build();
104+
private boolean httpConfigurationRequired(HttpClientConfiguration httpClientConfiguration)
105+
{
106+
return httpClientConfiguration != null;
100107
}
101108

102109
HttpClientBuilder getHttpClientBuilder()

api-sdk/src/main/java/com/smartling/api/sdk/util/HttpUtils.java

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package com.smartling.api.sdk.util;
1717

18+
import com.smartling.api.sdk.HttpClientConfiguration;
1819
import com.smartling.api.sdk.LibNameVersionHolder;
1920
import com.smartling.api.sdk.ProxyConfiguration;
2021
import com.smartling.api.sdk.dto.file.StringResponse;
@@ -29,7 +30,6 @@
2930
import org.apache.http.HttpMessage;
3031
import org.apache.http.HttpResponse;
3132
import org.apache.http.HttpStatus;
32-
import org.apache.http.client.config.RequestConfig;
3333
import org.apache.http.client.methods.HttpRequestBase;
3434
import org.apache.http.impl.client.CloseableHttpClient;
3535
import org.apache.http.util.EntityUtils;
@@ -57,16 +57,16 @@ public class HttpUtils
5757
private static final ThreadLocal<String> requestId = new ThreadLocal<>();
5858
private static final ThreadLocal<ResponseDetails> responseDetails = new ThreadLocal<>();
5959

60-
private HttpProxyUtils httpProxyUtils;
60+
private HttpClientFactory httpClientFactory;
6161

62-
void setHttpProxyUtils(HttpProxyUtils httpProxyUtils)
62+
void setHttpClientFactory(HttpClientFactory httpClientFactory)
6363
{
64-
this.httpProxyUtils = httpProxyUtils;
64+
this.httpClientFactory = httpClientFactory;
6565
}
6666

6767
public HttpUtils()
6868
{
69-
this.httpProxyUtils = new HttpProxyUtils();
69+
this.httpClientFactory = new HttpClientFactory();
7070
}
7171

7272
public static ThreadLocal<String> getRequestId()
@@ -83,10 +83,12 @@ public static ThreadLocal<ResponseDetails> getResponseDetails()
8383
* Method for executing http calls and retrieving string response.
8484
* @param httpRequest request for execute
8585
* @param proxyConfiguration proxy configuration, if it is set to {@code NULL} proxy settings will be setup from system properties. Otherwise switched off.
86+
* @param httpClientConfiguration http transport configuration, if it is set to {@code NULL} defaults will be used
8687
* @return {@link StringResponse} the contents of the requested file along with the encoding of the file.
8788
* @throws com.smartling.api.sdk.exceptions.SmartlingApiException if an exception has occurred or non success is returned from the Smartling Translation API.
8889
*/
89-
public StringResponse executeHttpCall(final HttpRequestBase httpRequest, final ProxyConfiguration proxyConfiguration) throws SmartlingApiException
90+
public StringResponse executeHttpCall(final HttpRequestBase httpRequest, final ProxyConfiguration proxyConfiguration,
91+
final HttpClientConfiguration httpClientConfiguration) throws SmartlingApiException
9092
{
9193
CloseableHttpClient httpClient = null;
9294
try
@@ -98,14 +100,8 @@ public StringResponse executeHttpCall(final HttpRequestBase httpRequest, final P
98100

99101
logProxyConfiguration(newProxyConfiguration);
100102

101-
httpClient = httpProxyUtils.getHttpClient(newProxyConfiguration);
103+
httpClient = httpClientFactory.getHttpClient(newProxyConfiguration, httpClientConfiguration);
102104

103-
RequestConfig proxyRequestConfig = httpProxyUtils.getProxyRequestConfig(httpRequest, newProxyConfiguration);
104-
105-
if (proxyRequestConfig != null)
106-
{
107-
httpRequest.setConfig(proxyRequestConfig);
108-
}
109105
addUserAgentHeader(httpRequest);
110106
final HttpResponse response = httpClient.execute(httpRequest);
111107

api-sdk/src/test/java/com/smartling/api/sdk/auth/AuthApiClientTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.smartling.api.sdk.auth;
22

3+
import com.smartling.api.sdk.HttpClientConfiguration;
34
import com.smartling.api.sdk.ProxyConfiguration;
45
import com.smartling.api.sdk.dto.file.StringResponse;
56
import com.smartling.api.sdk.exceptions.SmartlingApiException;
@@ -15,6 +16,7 @@
1516
import static mockit.Deencapsulation.setField;
1617
import static org.junit.Assert.assertEquals;
1718
import static org.mockito.Matchers.eq;
19+
import static org.mockito.Matchers.isNull;
1820
import static org.mockito.Mockito.mock;
1921
import static org.mockito.Mockito.when;
2022

@@ -53,7 +55,7 @@ public void setup() throws SmartlingApiException
5355
proxyConfiguration = mock(ProxyConfiguration.class);
5456
authApiClient = new AuthApiClient(proxyConfiguration, "https://api.smartling.com");
5557
setField(authApiClient, "httpUtils", httpUtils);
56-
when(httpUtils.executeHttpCall(requestCaptor.capture(), eq(proxyConfiguration))).thenReturn(response);
58+
when(httpUtils.executeHttpCall(requestCaptor.capture(), eq(proxyConfiguration), isNull(HttpClientConfiguration.class))).thenReturn(response);
5759
}
5860

5961
@Test

0 commit comments

Comments
 (0)