You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2019/06/18 14:50:08 UTC

[sling-whiteboard] 02/06: Add support for setting timeouts using the client API in HttpClientLauncher

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch feature/test-improvements
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git

commit 50cf6f2399d3eddb981763c9626b13e30c51de19
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Jun 18 14:45:43 2019 +0200

    Add support for setting timeouts using the client API in HttpClientLauncher
---
 url-connection-agent/README.md                     | 12 ++++--
 .../apache/sling/uca/impl/HttpClientLauncher.java  | 50 ++++++++++++++++++----
 2 files changed, 49 insertions(+), 13 deletions(-)

diff --git a/url-connection-agent/README.md b/url-connection-agent/README.md
index 96995aa..d743d88 100644
--- a/url-connection-agent/README.md
+++ b/url-connection-agent/README.md
@@ -15,16 +15,20 @@ It currently supports setting timeouts for HTTP connections done using:
 
 ## Validation
 
-Build the project with `mvn clean package` and then run a simple connection test with 
+In addition to running the integration tests, you can also build the project with `mvn clean package` and then run a simple connection test with 
 
-    java -javaagent:target/org.apache.sling.connection-timeout-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar=<connect-timeout>,<read-timeout> -cp target/test-classes:target/it-dependencies/* org.apache.sling.uca.impl.HttpClientLauncher <url> <client-type>
+    java -javaagent:target/org.apache.sling.connection-timeout-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar=<agent-connect-timeout>,<agent-read-timeout> -cp target/test-classes:target/it-dependencies/* org.apache.sling.uca.impl.HttpClientLauncher <url> <client-type> [<client-connect-timeout> <client-read-timeout>]
     
  The parameters are as follows:
  
- - `<connect-timeout>` - connection timeout in milliseconds
- - `<read-timeout>`- read timeout in milliseconds
+ - `<agent-connect-timeout>` - connection timeout in milliseconds to apply via the agent
+ - `<agent-read-timeout>`- read timeout in milliseconds to apply via the agent
  - `<url>` - the URL to access
  - `<client-type>` - the client type, either `JavaNet` for java.net.URL-based connections ,`HC3` for Apache Commons HttpClient 3.x, `HC4` for Apache Commons HttpClient 4.x or `OkHttp` for OK HTTP.
+ - `<client-connect-timeout>` (optional) - the connection timeout in milliseconds to apply via client APIs
+ - `<client-read-timeout>` (optional) - the read timeout in milliseconds to apply via client APIs
+ 
+The read and connect timeouts may be specified for both the agent and client APIs. The reason is that the agent should not change the timeout defaults if they are already set. Therefore, setting the agent timeouts to a very high value and the client API timeouts to a very low value ( e.g. 1 millisecond ) should still result in a timeout. 
  
  
  For a test that always fails, set one of the timeouts to 1. Both executions listed below will typically fail:
diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/HttpClientLauncher.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/HttpClientLauncher.java
index df1de9e..06953e3 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/HttpClientLauncher.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/HttpClientLauncher.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.time.Duration;
 import java.util.Date;
 import java.util.EnumSet;
 import java.util.stream.Collectors;
@@ -32,7 +33,10 @@ import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.HttpMethod;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.params.HttpClientParams;
+import org.apache.commons.httpclient.params.HttpConnectionParams;
 import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.config.RequestConfig.Builder;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -84,12 +88,12 @@ public class HttpClientLauncher {
      */
     @FunctionalInterface
     interface HttpConsumer {
-        void accept(String http) throws Exception;
+        void accept(String http, int connectTimeoutSeconds, int readTimeoutSeconds) throws Exception;
     }
 
     public static void main(String[] args) throws Exception {
         
-        if ( args.length != 2 )
+        if ( args.length < 2 )
             throw new IllegalArgumentException(usage());
         
         ClientType type = ClientType.fromString(args[1]);
@@ -98,17 +102,23 @@ public class HttpClientLauncher {
         
         System.out.println("[WEB] Executing request via " + type);
         
-        type.consumer.accept(args[0]);
+        int connectTimeout = args.length > 2 ? Integer.parseInt(args[2]) : 0;
+        int readTimeout = args.length > 3 ? Integer.parseInt(args[3]) : 0;
+        
+        type.consumer.accept(args[0], connectTimeout, readTimeout);
     }
 
     private static String usage() {
         return "Usage: java -cp ... " + HttpClientLauncher.class.getName() + " <URL> " + ClientType.pipeSeparatedString();
     }
 
-    private static void runUsingJavaNet(String targetUrl) throws IOException  {
+    private static void runUsingJavaNet(String targetUrl, int connectTimeoutMillis, int readTimeoutMillis) throws IOException  {
         HttpURLConnection con = (HttpURLConnection) new URL(targetUrl).openConnection();
         System.out.println("Connection type is " + con);
         
+        con.setConnectTimeout(connectTimeoutMillis);
+        con.setReadTimeout(readTimeoutMillis);
+        
         try (InputStream in = con.getInputStream();
                 InputStreamReader isr = new InputStreamReader(in);
                 BufferedReader br = new BufferedReader(isr)) {
@@ -122,10 +132,16 @@ public class HttpClientLauncher {
     }
 
 
-    private static void runUsingHttpClient3(String targetUrl) throws IOException {
+    private static void runUsingHttpClient3(String targetUrl, int connectTimeoutMillis, int readTimeoutMillis) throws IOException {
         HttpClient client = new HttpClient();
         // disable retries, to make sure that we get equivalent behaviour with other implementations
         client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0, false));
+        
+        if ( connectTimeoutMillis != 0 )
+            client.getParams().setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, Integer.valueOf(connectTimeoutMillis));
+        if ( readTimeoutMillis != 0 )
+            client.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, Integer.valueOf(readTimeoutMillis));
+        
         HttpMethod get = new GetMethod(targetUrl);
         System.out.format("Connection timeouts: connect: %d, so: %s%n", 
                 client.getHttpConnectionManager().getParams().getConnectionTimeout(),
@@ -140,9 +156,19 @@ public class HttpClientLauncher {
             System.out.print(new Date() + " [WEB] " + header.toExternalForm());
     }
     
-    private static void runUsingHttpClient4(String targetUrl) throws IOException {
+    private static void runUsingHttpClient4(String targetUrl, int connectTimeoutMillis, int readTimeoutMillis) throws IOException {
         // disable retries, to make sure that we get equivalent behaviour with other implementations
-        try ( CloseableHttpClient client = HttpClients.custom().disableAutomaticRetries().build() ) {
+        
+        Builder config = RequestConfig.custom();
+        if ( connectTimeoutMillis != 0 )
+            config.setConnectTimeout(connectTimeoutMillis);
+        if ( readTimeoutMillis != 0 )
+            config.setSocketTimeout(readTimeoutMillis);
+        
+        try ( CloseableHttpClient client = HttpClients.custom()
+                .setDefaultRequestConfig(config.build())
+                .disableAutomaticRetries().build() ) {
+            
             HttpGet get = new HttpGet(targetUrl);
             try ( CloseableHttpResponse response = client.execute(get)) {
                 System.out.println("[WEB] " + response.getStatusLine());
@@ -154,8 +180,14 @@ public class HttpClientLauncher {
         }
     }
 
-    private static void runUsingOkHttp(String targetUrl) throws IOException {
-        OkHttpClient client = new OkHttpClient();
+    private static void runUsingOkHttp(String targetUrl, int connectTimeoutSeconds, int readTimeoutSeconds) throws IOException {
+        OkHttpClient.Builder clientBuilder = new OkHttpClient().newBuilder();
+        if ( connectTimeoutSeconds != 0 )
+            clientBuilder.connectTimeout(Duration.ofMillis(connectTimeoutSeconds));
+        if ( readTimeoutSeconds != 0 )
+            clientBuilder.readTimeout(Duration.ofMillis(readTimeoutSeconds));
+        
+        OkHttpClient client = clientBuilder.build();
         
         Request request = new Request.Builder()
             .url(targetUrl)