Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: set socket config with blocking operation timeout #670

Merged
merged 1 commit into from
Feb 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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