Skip to content

Commit

Permalink
[DI-1920] fix: set socket config with blocking operation timeout (#670)
Browse files Browse the repository at this point in the history
  • Loading branch information
childish-sambino committed Feb 4, 2022
1 parent 6de0d4f commit 6ba652f
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 60 deletions.
38 changes: 21 additions & 17 deletions src/main/java/com/twilio/http/HttpClient.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,44 @@
package com.twilio.http;

import lombok.Getter;
import lombok.Setter;
import org.apache.http.client.RedirectStrategy;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.client.DefaultRedirectStrategy;

public abstract class HttpClient {

public static final int CONNECTION_TIMEOUT = 10000;
public static final int SOCKET_TIMEOUT = 30500;
public static final RequestConfig DEFAULT_REQUEST_CONFIG = RequestConfig
.custom()
.setConnectTimeout(CONNECTION_TIMEOUT)
.setSocketTimeout(SOCKET_TIMEOUT)
.build();
public static final SocketConfig DEFAULT_SOCKET_CONFIG = SocketConfig
.custom()
.setSoTimeout(SOCKET_TIMEOUT)
.build();

public static final int ANY_500 = -500;
public static final int ANY_400 = -400;
public static final int ANY_300 = -300;
public static final int ANY_200 = -200;
public static final int ANY_100 = -100;

public static final int[] RETRY_CODES = new int[]{ANY_500};
public static final int[] RETRY_CODES = new int[] {ANY_500};
public static final int RETRIES = 3;
public static final long DELAY_MILLIS = 100L;

// Default redirect strategy to not auto-redirect for any methods (empty string array).
@Getter
@Setter
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(new String[0]);

@Getter
private Response lastResponse;
@Getter
private Request lastRequest;

/**
Expand Down Expand Up @@ -66,14 +86,6 @@ public Response reliableRequest(final Request request, final int[] retryCodes, i
return response;
}

public Response getLastResponse() {
return lastResponse;
}

public Request getLastRequest() {
return lastRequest;
}

protected boolean shouldRetry(final Response response, final int[] retryCodes) {
if (response == null) {
return true;
Expand Down Expand Up @@ -119,13 +131,5 @@ protected boolean shouldRetry(final Response response, final int[] retryCodes) {
return false;
}

public RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}

public void setRedirectStrategy(final RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}

public abstract Response makeRequest(final Request request);
}
52 changes: 29 additions & 23 deletions src/main/java/com/twilio/http/NetworkHttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,54 @@

import com.twilio.Twilio;
import com.twilio.exception.ApiException;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.config.SocketConfig;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class NetworkHttpClient extends HttpClient {

private static final int CONNECTION_TIMEOUT = 10000;
private static final int SOCKET_TIMEOUT = 30500;

private final org.apache.http.client.HttpClient client;

/**
* Create a new HTTP Client.
*/
public NetworkHttpClient() {
this(RequestConfig.custom()
.setConnectTimeout(CONNECTION_TIMEOUT)
.setSocketTimeout(SOCKET_TIMEOUT)
.build()
);
this(DEFAULT_REQUEST_CONFIG);
}

/**
* Create a new HTTP Client with a custom request config.
* @param config a RequestConfig.
*
* @param requestConfig a RequestConfig.
*/
public NetworkHttpClient(RequestConfig config) {
public NetworkHttpClient(final RequestConfig requestConfig) {
this(requestConfig, DEFAULT_SOCKET_CONFIG);
}

/**
* Create a new HTTP Client with a custom request and socket config.
*
* @param requestConfig a RequestConfig.
* @param socketConfig a SocketConfig.
*/
public NetworkHttpClient(final RequestConfig requestConfig, final SocketConfig socketConfig) {
Collection<BasicHeader> headers = Arrays.asList(
new BasicHeader("X-Twilio-Client", "java-" + Twilio.VERSION),
new BasicHeader(HttpHeaders.USER_AGENT, "twilio-java/" + Twilio.VERSION + " (" + Twilio.JAVA_VERSION + ")"),
Expand All @@ -61,12 +67,13 @@ public NetworkHttpClient(RequestConfig config) {
}

PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setDefaultMaxPerRoute(10);
connectionManager.setMaxTotal(10*2);
connectionManager.setDefaultSocketConfig(socketConfig);
connectionManager.setDefaultMaxPerRoute(10);
connectionManager.setMaxTotal(10 * 2);

client = clientBuilder
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(config)
.setDefaultRequestConfig(requestConfig)
.setDefaultHeaders(headers)
.setRedirectStrategy(this.getRedirectStrategy())
.build();
Expand Down Expand Up @@ -145,6 +152,5 @@ public Response makeRequest(final Request request) {
HttpClientUtils.closeQuietly(response);

}

}
}
63 changes: 43 additions & 20 deletions src/main/java/com/twilio/http/ValidationClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.apache.http.HttpVersion;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
Expand All @@ -21,47 +22,69 @@

public class ValidationClient extends HttpClient {

private static final int CONNECTION_TIMEOUT = 10000;
private static final int SOCKET_TIMEOUT = 30500;
private static final RequestConfig DEFAULT_REQUEST_CONFIG = RequestConfig.custom()
.setConnectTimeout(CONNECTION_TIMEOUT)
.setSocketTimeout(SOCKET_TIMEOUT)
.build();;

private final org.apache.http.client.HttpClient client;

/**
* Create a new ValidationClient.
*
* @param accountSid Twilio Account SID
* @param credentialSid Twilio Credential SID
* @param signingKey Twilio Signing key
* @param privateKey Private Key
* @param accountSid Twilio Account SID
* @param credentialSid Twilio Credential SID
* @param signingKey Twilio Signing key
* @param privateKey Private Key
*/
public ValidationClient(String accountSid, String credentialSid, String signingKey, PrivateKey privateKey) {
public ValidationClient(final String accountSid,
final String credentialSid,
final String signingKey,
final PrivateKey privateKey) {
this(accountSid, credentialSid, signingKey, privateKey, DEFAULT_REQUEST_CONFIG);
}

/**
* Create a new ValidationClient.
*
* @param accountSid Twilio Account SID
* @param credentialSid Twilio Credential SID
* @param signingKey Twilio Signing key
* @param privateKey Private Key
* @param config HTTP Request Config
* @param accountSid Twilio Account SID
* @param credentialSid Twilio Credential SID
* @param signingKey Twilio Signing key
* @param privateKey Private Key
* @param requestConfig HTTP Request Config
*/
public ValidationClient(final String accountSid,
final String credentialSid,
final String signingKey,
final PrivateKey privateKey,
final RequestConfig requestConfig) {
this(accountSid, credentialSid, signingKey, privateKey, requestConfig, DEFAULT_SOCKET_CONFIG);
}

/**
* Create a new ValidationClient.
*
* @param accountSid Twilio Account SID
* @param credentialSid Twilio Credential SID
* @param signingKey Twilio Signing key
* @param privateKey Private Key
* @param requestConfig HTTP Request Config
* @param socketConfig HTTP Socket Config
*/
public ValidationClient(String accountSid, String credentialSid, String signingKey, PrivateKey privateKey, RequestConfig config) {
public ValidationClient(final String accountSid,
final String credentialSid,
final String signingKey,
final PrivateKey privateKey,
final RequestConfig requestConfig,
final SocketConfig socketConfig) {
Collection<BasicHeader> headers = Arrays.asList(
new BasicHeader("X-Twilio-Client", "java-" + Twilio.VERSION),
new BasicHeader(HttpHeaders.USER_AGENT, "twilio-java/" + Twilio.VERSION + " (" + Twilio.JAVA_VERSION + ")"),
new BasicHeader(HttpHeaders.ACCEPT, "application/json"),
new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "utf-8")
);

final PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setDefaultSocketConfig(socketConfig);

client = HttpClientBuilder.create()
.setConnectionManager(new PoolingHttpClientConnectionManager())
.setDefaultRequestConfig(config)
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig)
.setDefaultHeaders(headers)
.setMaxConnPerRoute(10)
.addInterceptorLast(new ValidationInterceptor(accountSid, credentialSid, signingKey, privateKey))
Expand Down

0 comments on commit 6ba652f

Please sign in to comment.