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/12 14:27:23 UTC

[sling-whiteboard] branch master updated (2dbd960 -> 1b101fd)

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

rombert pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git.


    from 2dbd960  Updated README to reflect latest state.
     new 69e0fe7  Implement default timeouts for httpclient 4.x
     new 4fcc38d  Prevent NPE if agent is launched with no arguments
     new a45edb6  Send back user-agent to help identify which requests come through
     new 7d419a5  Whitespace fix
     new 6c64985  Documentation updates
     new 6668540  Create a simple log abstraction
     new 7e7dfe3  Rename 'Main' to 'HttpClientLauncher'
     new 312771a  Launcher cleanup
     new 6523166  AgentIT: better handling of missing exception lines
     new b9fcb9a  Use a per-test-method instance of the mock server.
     new 1b101fd  Prevent NPE in test

The 11 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 url-connection-agent/README.md                     |  21 +++-
 url-connection-agent/pom.xml                       |   6 ++
 .../main/java/org/apache/sling/uca/impl/Agent.java |  22 ++--
 .../uca/impl/HttpClient3TimeoutTransformer.java    |  13 ++-
 ...mer.java => HttpClient4TimeoutTransformer.java} |  40 +++++---
 .../sling/uca/impl/JavaNetTimeoutTransformer.java  |  16 +--
 .../main/java/org/apache/sling/uca/impl/Log.java   | 113 +++++++++++++++++++++
 .../java/org/apache/sling/uca/impl/AgentIT.java    |  60 +++++++----
 .../impl/{Main.java => HttpClientLauncher.java}    |  99 ++++++++++++++----
 .../sling/uca/impl/MisbehavingServerExtension.java |  12 ++-
 10 files changed, 318 insertions(+), 84 deletions(-)
 copy url-connection-agent/src/main/java/org/apache/sling/uca/impl/{HttpClient3TimeoutTransformer.java => HttpClient4TimeoutTransformer.java} (56%)
 create mode 100644 url-connection-agent/src/main/java/org/apache/sling/uca/impl/Log.java
 rename url-connection-agent/src/test/java/org/apache/sling/uca/impl/{Main.java => HttpClientLauncher.java} (55%)


[sling-whiteboard] 07/11: Rename 'Main' to 'HttpClientLauncher'

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7e7dfe335c04af717fc28e702348f96143c34742
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Jun 7 16:47:31 2019 +0200

    Rename 'Main' to 'HttpClientLauncher'
---
 .../src/test/java/org/apache/sling/uca/impl/AgentIT.java         | 8 ++++----
 .../apache/sling/uca/impl/{Main.java => HttpClientLauncher.java} | 9 ++++++---
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
index 3a343ba..59240cd 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
@@ -34,7 +34,7 @@ import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.commons.httpclient.ConnectTimeoutException;
-import org.apache.sling.uca.impl.Main.ClientType;
+import org.apache.sling.uca.impl.HttpClientLauncher.ClientType;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.EnumSource;
@@ -71,7 +71,7 @@ public class AgentIT {
      * @throws IOException various I/O problems 
      */
     @ParameterizedTest
-    @EnumSource(Main.ClientType.class)
+    @EnumSource(HttpClientLauncher.ClientType.class)
     public void connectTimeout(ClientType clientType) throws IOException {
 
         RecordedThrowable error = assertTimeout(ofSeconds(5),  () -> runTest("http://repo1.maven.org:81", clientType));
@@ -107,7 +107,7 @@ public class AgentIT {
      * @throws IOException various I/O problems
      */
     @ParameterizedTest
-    @EnumSource(Main.ClientType.class)
+    @EnumSource(HttpClientLauncher.ClientType.class)
     public void readTimeout(ClientType clientType, MisbehavingServerControl server) throws IOException {
         
         RecordedThrowable error = assertTimeout(ofSeconds(5),  () -> runTest("http://localhost:" + server.getLocalPort(), clientType));
@@ -165,7 +165,7 @@ public class AgentIT {
             "-javaagent:" + jar +"=" + TimeUnit.SECONDS.toMillis(connectTimeoutSeconds) +"," + TimeUnit.SECONDS.toMillis(readTimeoutSeconds)+",v",
             "-cp",
             classPath,
-            "org.apache.sling.uca.impl.Main",
+            HttpClientLauncher.class.getName(),
             url.toString(),
             clientType.toString()
         );
diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/Main.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/HttpClientLauncher.java
similarity index 96%
rename from url-connection-agent/src/test/java/org/apache/sling/uca/impl/Main.java
rename to url-connection-agent/src/test/java/org/apache/sling/uca/impl/HttpClientLauncher.java
index aee0725..9d8ca73 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/Main.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/HttpClientLauncher.java
@@ -40,7 +40,10 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
 
-public class Main {
+/**
+ * CLI interface to run HTTP clients
+ */
+public class HttpClientLauncher {
     
     // TODO - write help messages with the values from this enum
     public enum ClientType {
@@ -50,7 +53,7 @@ public class Main {
     public static void main(String[] args) throws MalformedURLException, IOException {
         
         if ( args.length != 2 )
-            throw new IllegalArgumentException("Usage: java -cp ... " + Main.class.getName() + " <URL> JavaNet|HC3|HC4");
+            throw new IllegalArgumentException("Usage: java -cp ... " + HttpClientLauncher.class.getName() + " <URL> JavaNet|HC3|HC4");
         
         System.out.println(new Date() + " [WEB] Executing request via " + args[1]);
 
@@ -65,7 +68,7 @@ public class Main {
                 runUsingHttpClient4(args[0]);
                 break;
             default:
-                throw new IllegalArgumentException("Usage: java -cp ... " + Main.class.getName() + " <URL> JavaNet|HC3|HC4");
+                throw new IllegalArgumentException("Usage: java -cp ... " + HttpClientLauncher.class.getName() + " <URL> JavaNet|HC3|HC4");
         }
     }
 


[sling-whiteboard] 03/11: Send back user-agent to help identify which requests come through

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit a45edb6d0e8bba7535c34c7266562c82175e178c
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Jun 7 11:47:48 2019 +0200

    Send back user-agent to help identify which requests come through
---
 .../test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java
index 702b82f..601adfd 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java
@@ -94,6 +94,8 @@ class MisbehavingServerExtension implements BeforeAllCallback, AfterAllCallback,
             public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
                     throws IOException, ServletException {
                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+                if ( baseRequest.getHeader("User-Agent") != null )
+                    response.addHeader("Original-User-Agent", baseRequest.getHeader("User-Agent"));
                 baseRequest.setHandled(true);
             }
         });


[sling-whiteboard] 02/11: Prevent NPE if agent is launched with no arguments

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4fcc38d79c081bcbb42a2b3df4d04caf26e4acee
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Jun 7 11:47:33 2019 +0200

    Prevent NPE if agent is launched with no arguments
---
 url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
index c35565f..a9320d6 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
@@ -25,7 +25,7 @@ public class Agent {
     public static void premain(String args, Instrumentation inst) {
         
         System.out.println("[AGENT] Loading agent...");
-        String[] parsedArgs = args.split(",");
+        String[] parsedArgs = args != null ? args.split(",") : new String[0];
         long connectTimeout =  TimeUnit.MINUTES.toMillis(1);
         long readTimeout = TimeUnit.MINUTES.toMillis(1);
         if ( parsedArgs.length > 0 )


[sling-whiteboard] 08/11: Launcher cleanup

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 312771a9e76fbd2fe9faa9547da0c4927c0178c0
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Jun 7 17:18:55 2019 +0200

    Launcher cleanup
---
 .../apache/sling/uca/impl/HttpClientLauncher.java  | 73 +++++++++++++++-------
 1 file changed, 51 insertions(+), 22 deletions(-)

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 9d8ca73..09ef81f 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
@@ -20,15 +20,15 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.Date;
+import java.util.EnumSet;
+import java.util.stream.Collectors;
 
 import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
 import org.apache.commons.httpclient.Header;
 import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpException;
 import org.apache.commons.httpclient.HttpMethod;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.params.HttpClientParams;
@@ -45,34 +45,63 @@ import org.apache.http.util.EntityUtils;
  */
 public class HttpClientLauncher {
     
-    // TODO - write help messages with the values from this enum
     public enum ClientType {
-        JavaNet, HC3, HC4
+        JavaNet(HttpClientLauncher::runUsingJavaNet), 
+        HC3(HttpClientLauncher::runUsingHttpClient3),
+        HC4(HttpClientLauncher::runUsingHttpClient4);
+        
+        private final HttpConsumer consumer;
+
+        ClientType(HttpConsumer consumer) {
+            this.consumer = consumer;
+        }
+        
+        public HttpConsumer getConsumer() {
+            return consumer;
+        }
+        
+        static String pipeSeparatedString() {
+            return EnumSet.allOf(ClientType.class).stream()
+                .map(ClientType::toString)
+                .collect(Collectors.joining("|"));
+        }
+        
+        static ClientType fromString(String value) {
+            return EnumSet.allOf(ClientType.class).stream()
+                .filter( e -> e.toString().equals(value) )
+                .findFirst()
+                .orElse(null);
+        }
+    }
+    
+    /**
+     * A <tt>Consumer</tt> that allows throwing checked exceptions.</p>
+     *
+     */
+    @FunctionalInterface
+    interface HttpConsumer {
+        void accept(String http) throws Exception;
     }
 
-    public static void main(String[] args) throws MalformedURLException, IOException {
+    public static void main(String[] args) throws Exception {
         
         if ( args.length != 2 )
-            throw new IllegalArgumentException("Usage: java -cp ... " + HttpClientLauncher.class.getName() + " <URL> JavaNet|HC3|HC4");
+            throw new IllegalArgumentException(usage());
+        
+        ClientType type = ClientType.fromString(args[1]);
+        if ( type == null )
+            throw new IllegalArgumentException(usage());
         
-        System.out.println(new Date() + " [WEB] Executing request via " + args[1]);
+        System.out.println("[WEB] Executing request via " + type);
+        
+        type.consumer.accept(args[0]);
+    }
 
-        switch ( args[1] ) {
-            case "JavaNet":
-                runUsingJavaNet(args[0]);
-                break;
-            case "HC3":
-                runUsingHttpClient3(args[0]);
-                break;
-            case "HC4":
-                runUsingHttpClient4(args[0]);
-                break;
-            default:
-                throw new IllegalArgumentException("Usage: java -cp ... " + HttpClientLauncher.class.getName() + " <URL> JavaNet|HC3|HC4");
-        }
+    private static String usage() {
+        return "Usage: java -cp ... " + HttpClientLauncher.class.getName() + " <URL> " + ClientType.pipeSeparatedString();
     }
 
-    private static void runUsingJavaNet(String targetUrl) throws MalformedURLException, IOException {
+    private static void runUsingJavaNet(String targetUrl) throws IOException  {
         URLConnection con = new URL(targetUrl).openConnection();
         System.out.println("Connection type is " + con);
         
@@ -86,7 +115,7 @@ public class HttpClientLauncher {
     }
 
 
-    private static void runUsingHttpClient3(String targetUrl) throws HttpException, IOException {
+    private static void runUsingHttpClient3(String targetUrl) 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));


[sling-whiteboard] 05/11: Documentation updates

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 6c64985973d93eb7dc1c40977d506b65b4ed999e
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Jun 7 16:07:44 2019 +0200

    Documentation updates
---
 url-connection-agent/README.md                           | 16 +++++++++++++---
 .../sling/uca/impl/HttpClient3TimeoutTransformer.java    |  6 ++++++
 .../sling/uca/impl/HttpClient4TimeoutTransformer.java    |  6 ++++++
 .../apache/sling/uca/impl/JavaNetTimeoutTransformer.java |  6 +++---
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/url-connection-agent/README.md b/url-connection-agent/README.md
index fcc5d06..916c0ca 100644
--- a/url-connection-agent/README.md
+++ b/url-connection-agent/README.md
@@ -1,10 +1,18 @@
-# Apache Sling URL connection agent
+# Apache Sling HTTP timeout enforcer
 
 This module is part of the [Apache Sling](https://sling.apache.org) project.
 
-This module provides a java agent that uses the instrumentation API to add timeouts to `connect` calls made via HTTP or HTTPs without setting read and connect timeouts. It is intended as an additional layer of control to use when running unstrusted client code that may make calls without explicitly setting timeouts.
+This module provides a java agent that uses the [instrumentation API](https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html) to add connect and read timeouts to `connect` made via HTTP or HTTPs. It only applies these timeouts if none were set explicitly.
 
-## Launching
+The agent is intended as an additional layer of control to use when running untrusted client code that may make calls without explicitly setting timeouts. It is always recommended to set timeouts in client code, rather than relying on this agent.
+
+It currently supports setting timeouts for HTTP connections done using:
+
+* [java.net.URL](https://docs.oracle.com/javase/7/docs/api/java/net/URL.html) and/or [java.net.URLConnection](https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html)
+* [Apache Commons HttpClient 3.x](https://hc.apache.org/httpclient-3.x/)
+* [Apache HttpComponents Client 4.x](https://hc.apache.org/httpcomponents-client-ga/)
+
+## Validation
 
 Build the project with `mvn clean package` and then run a simple connection test with 
 
@@ -31,6 +39,8 @@ In contrast, the execution below should succeed:
 java -javaagent:target/url-connection-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar=1000,1000 -cp target/test-classes:target/it-dependencies/* org.apache.sling.uca.impl.Main https://sling.apache.org JavaNet
 ```
 
+To use this in your own project you should 
+
 ## Tested platforms
 
 * openjdk version "1.8.0_212"
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
index b287447..6e57245 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
@@ -25,6 +25,12 @@ import javassist.CtClass;
 import javassist.CtMethod;
 import javassist.bytecode.Descriptor;
 
+/**
+ * Sets timeouts for HTTP calls done using <em>Apache Commons HttpClient 3.x</em>
+ * 
+ * <p>It inserts two calls in <tt>org.apache.commons.httpclient.params.DefaultHttpParamsFactory.createParams</tt> that set
+ * default values for <tt>http.connection.timeout</tt> and <tt>http.socket.timeout</tt>.</p>
+ */
 public class HttpClient3TimeoutTransformer implements ClassFileTransformer {
     
     private static final String DEFAULT_HTTP_PARAMS_FACTORY_CLASS_NAME = Descriptor.toJvmName("org.apache.commons.httpclient.params.DefaultHttpParamsFactory");
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
index ee62458..e74dabf 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
@@ -26,6 +26,12 @@ import javassist.CtConstructor;
 import javassist.CtField;
 import javassist.bytecode.Descriptor;
 
+/**
+ * Sets timeouts for HTTP calls done using <em>Apache HttpComponents Client 4.x</em>
+ * 
+ * <p>It inserts two calls to <tt>org.apache.http.client.config.RequestConfig$Builder</tt> that set default
+ * values for <tt>connectTimeout</tt> and <tt>socketTimeout</tt>.</p>
+ */
 public class HttpClient4TimeoutTransformer implements ClassFileTransformer {
 
     // org.apache.http.client.config.RequestConfig.Builder
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
index d320875..9978c33 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
@@ -29,10 +29,10 @@ import javassist.NotFoundException;
 import javassist.bytecode.Descriptor;
 
 /**
- * Transforms well-known HTTP URL connection classes
+ * Sets timeouts for HTTP calls done using <tt>java.net.URL</tt>/<tt>java.net.URLConnection</tt>.
  * 
- * <p>This implementation adds connect and read timeouts to those connections
- * if none are defined.</p>
+ * <p>It transforms calls to <tt>connect</tt> methods of internal URL connection classes to set the
+ * connect and read timeout in case they have the default value of <tt>0</tt>.</p>
  * 
  * @see URLConnection#getConnectTimeout()
  * @see URLConnection#getReadTimeout()


[sling-whiteboard] 06/11: Create a simple log abstraction

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 6668540c7f61672287d060b436f691ce2eb62b2e
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Jun 7 16:39:13 2019 +0200

    Create a simple log abstraction
---
 .../main/java/org/apache/sling/uca/impl/Agent.java |  17 ++--
 .../uca/impl/HttpClient3TimeoutTransformer.java    |   7 +-
 .../uca/impl/HttpClient4TimeoutTransformer.java    |   7 +-
 .../sling/uca/impl/JavaNetTimeoutTransformer.java  |  10 +-
 .../main/java/org/apache/sling/uca/impl/Log.java   | 113 +++++++++++++++++++++
 .../java/org/apache/sling/uca/impl/AgentIT.java    |   2 +-
 6 files changed, 135 insertions(+), 21 deletions(-)

diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
index a9320d6..e523155 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
@@ -24,16 +24,20 @@ public class Agent {
 
     public static void premain(String args, Instrumentation inst) {
         
-        System.out.println("[AGENT] Loading agent...");
         String[] parsedArgs = args != null ? args.split(",") : new String[0];
         long connectTimeout =  TimeUnit.MINUTES.toMillis(1);
         long readTimeout = TimeUnit.MINUTES.toMillis(1);
+        String logSpec = "";
         if ( parsedArgs.length > 0 )
             connectTimeout = Long.parseLong(parsedArgs[0]);
         if ( parsedArgs.length > 1 )
             readTimeout = Long.parseLong(parsedArgs[1]);
+        if ( parsedArgs.length > 2)
+            logSpec = parsedArgs[2];
         
-        System.out.format("[AGENT] Set connectTimeout : %d, readTimeout: %d%n", connectTimeout, readTimeout);
+        Log.configure(logSpec);
+        
+        Log.get().log("Preparing to install URL transformers. Configured timeouts - connectTimeout : %d, readTimeout: %d", connectTimeout, readTimeout);
 
         ClassFileTransformer[] transformers = new ClassFileTransformer[] {
             new JavaNetTimeoutTransformer(connectTimeout, readTimeout),
@@ -44,11 +48,6 @@ public class Agent {
         for ( ClassFileTransformer transformer : transformers )
             inst.addTransformer(transformer, true);
 
-        System.out.println("[AGENT] Loaded agent!");
-    }
-
-    public static void agentmain(String args, Instrumentation inst) {
-        premain(args, inst);
-    }
-    
+        Log.get().log("All transformers installed");
+    }    
 }
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
index 6e57245..9bf5d92 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
@@ -48,7 +48,7 @@ public class HttpClient3TimeoutTransformer implements ClassFileTransformer {
             ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
         try {
             if ( DEFAULT_HTTP_PARAMS_FACTORY_CLASS_NAME.equals(className) ) {
-                System.out.println("[AGENT] Asked to transform " + className);
+                Log.get().log("%s asked to transform %s", getClass().getSimpleName(), className);
                 
                 ClassPool defaultPool = ClassPool.getDefault();
                 CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
@@ -63,11 +63,12 @@ public class HttpClient3TimeoutTransformer implements ClassFileTransformer {
                 
                 classfileBuffer = cc.toBytecode();
                 cc.detach();
+                Log.get().log("Transformation complete.");
             }
             return classfileBuffer;
         } catch (Exception e) {
-            e.printStackTrace(); // ensure _something_ is printed
-            throw new RuntimeException("[AGENT] Transformation failed", e);
+            Log.get().fatal("Transformation failed", e);
+            return null;
         }
     }
 }
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
index e74dabf..230c1db 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
@@ -51,7 +51,7 @@ public class HttpClient4TimeoutTransformer implements ClassFileTransformer {
             ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
         try {
             if ( REQUEST_CONFIG_BUILDER_CLASS_NAME.equals(className) ) {
-                System.out.println("[AGENT] Asked to transform " + className);
+                Log.get().log("%s asked to transform %s", getClass().getSimpleName(), className);
                 
                 ClassPool defaultPool = ClassPool.getDefault();
                 CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
@@ -65,11 +65,12 @@ public class HttpClient4TimeoutTransformer implements ClassFileTransformer {
                 
                 classfileBuffer = cc.toBytecode();
                 cc.detach();
+                Log.get().log("Transformation complete.");
             }
             return classfileBuffer;
         } catch (Exception e) {
-            e.printStackTrace(); // ensure _something_ is printed
-            throw new RuntimeException("[AGENT] Transformation failed", e);
+            Log.get().fatal("Transformation failed", e);
+            return null;
         }
     }
 
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
index 9978c33..121417c 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
@@ -60,18 +60,18 @@ class JavaNetTimeoutTransformer implements ClassFileTransformer {
             ProtectionDomain protectionDomain, byte[] classfileBuffer) {
         try {
             if (CLASSES_TO_TRANSFORM.contains(className)) {
-                System.out.println("[AGENT] Asked to transform " + className);
+                Log.get().log("%s asked to transform %s", getClass().getSimpleName(), className);
                 CtMethod connectMethod = findConnectMethod(className);
                 connectMethod.insertBefore("if ( getConnectTimeout() == 0 ) { setConnectTimeout(" + connectTimeoutMillis + "); }");
                 connectMethod.insertBefore("if ( getReadTimeout() == 0 ) { setReadTimeout(" + readTimeoutMillis + "); }");
                 classfileBuffer = connectMethod.getDeclaringClass().toBytecode();
                 connectMethod.getDeclaringClass().detach();
-                System.out.println("[AGENT] Transformation complete!");
+                Log.get().log("Transformation complete.");
             }
             return classfileBuffer;
         } catch (Exception e) {
-            e.printStackTrace(); // ensure _something_ is printed
-            throw new RuntimeException("[AGENT] Transformation failed", e);
+            Log.get().fatal("Transformation failed", e);
+            return null;
         }
     }
     
@@ -80,7 +80,7 @@ class JavaNetTimeoutTransformer implements ClassFileTransformer {
         ClassPool defaultPool = ClassPool.getDefault();
         CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
         if (cc == null) {
-            System.out.println("[AGENT] no class found with name " + className);
+            Log.get().log("No class found with name %s", className);
             return null;
         }
         return cc.getDeclaredMethod("connect");
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Log.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Log.java
new file mode 100644
index 0000000..900f426
--- /dev/null
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Log.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.uca.impl;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Formatter;
+
+/**
+ * Simple logger abstraction
+ * 
+ * <p>This is an intentionally simple and simplistic logger for agent-internal usage. Since the agent environment
+ * is limited and can make no assumption about how it will be used, it only uses the console and no
+ * external libraries.</p>
+ * 
+ * <p>It is required to call {@link #configure(String)} before accessing the log instance using {@link #get()}.</p>
+ *
+ */
+abstract class Log {
+    
+    private static Log INSTANCE;
+
+    /**
+     * Configures the global logger instance
+     * 
+     * @param spec the logger spec, <tt>v</tt> for a console log, anything else for a no-op log
+     */
+    public static void configure(String spec) {
+        INSTANCE = "v".equals(spec) ? new ConsoleLog() : new NoopLog();
+    }
+    
+    /**
+     * Gets the global logger instance, configured with {@link #configure(String)}
+     * 
+     * @return the global logger instance
+     * @throws NullPointerException in case the logger is not configured
+     */
+    public static Log get() {
+        return requireNonNull(INSTANCE, "Log is null, did you foget to call Log.configure() ?");
+    }
+
+    private Log() {
+
+    }
+
+    /**
+     * Logs a message
+     * 
+     * <p>The message and the arguments are interpolated using a {@link Formatter}, e.g.
+     * 
+     * <pre>Logger.get().log("Transforming %s", klazz.getName());</pre>
+     * 
+     *  </p>
+     *  
+     *  <p>The line separator <tt>%n</tt> is automatically appended to the message.</p>
+     * 
+     * @param msg the message
+     * @param args the arguments
+     */
+    public abstract void log(String msg, Object... args);
+    
+    /**
+     * Prints the throwable stack trace and throws a <tt>RuntimeException</tt>
+     * 
+     * @param message the message to include in the <tt>RuntimeException</tt>
+     * @param t the throwable to print the stack trace for 
+     */
+    public abstract void fatal(String message, Throwable t);
+
+    static class ConsoleLog extends Log {
+
+        private static final String LOG_ENTRY_PREFIX = "[AGENT] ";
+
+        @Override
+        public void log(String msg, Object... args) {
+            System.out.format(LOG_ENTRY_PREFIX + msg + " %n", args);
+        }
+        
+        @Override
+        public void fatal(String msg, Throwable t) {
+            t.printStackTrace(); // ensure _something_ is printed
+            throw new RuntimeException(LOG_ENTRY_PREFIX + msg, t);
+            
+        }
+    }
+    
+    static class NoopLog extends Log {
+
+        @Override
+        public void log(String msg, Object... args) {
+            // empty by design
+        }
+        
+        @Override
+        public void fatal(String message, Throwable t) {
+            // empty by design
+        }
+    }
+}
diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
index a14c700..3a343ba 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
@@ -162,7 +162,7 @@ public class AgentIT {
         ProcessBuilder pb = new ProcessBuilder(
             javaExe.toString(),
             "-showversion",
-            "-javaagent:" + jar +"=" + TimeUnit.SECONDS.toMillis(connectTimeoutSeconds) +"," + TimeUnit.SECONDS.toMillis(readTimeoutSeconds),
+            "-javaagent:" + jar +"=" + TimeUnit.SECONDS.toMillis(connectTimeoutSeconds) +"," + TimeUnit.SECONDS.toMillis(readTimeoutSeconds)+",v",
             "-cp",
             classPath,
             "org.apache.sling.uca.impl.Main",


[sling-whiteboard] 09/11: AgentIT: better handling of missing exception lines

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 65231667f5ed57c428385a34f20dda982f9e1e38
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Wed Jun 12 16:14:16 2019 +0200

    AgentIT: better handling of missing exception lines
---
 .../src/test/java/org/apache/sling/uca/impl/AgentIT.java     | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
index 59240cd..dd2bbfe 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
@@ -55,6 +55,7 @@ import org.slf4j.LoggerFactory;
 @ExtendWith(MisbehavingServerExtension.class)
 public class AgentIT {
     
+    private static final String EXCEPTION_MARKER = "Exception in thread \"main\" ";
     private static final Path STDERR = Paths.get("target", "stderr.txt");
     private static final Path STDOUT = Paths.get("target", "stdout.txt");
     private static final Logger LOG = LoggerFactory.getLogger(AgentIT.class);
@@ -195,12 +196,15 @@ public class AgentIT {
         return String.join(File.pathSeparator, elements);
     }
 
-    private RecordedThrowable newRecordedThrowable(String string) {
+    private RecordedThrowable newRecordedThrowable(String line) {
+        
+        if ( !line.startsWith(EXCEPTION_MARKER) )
+            return null;
      
-        string = string.replace("Exception in thread \"main\" ", "");
+        line = line.replace(EXCEPTION_MARKER, "");
 
-        String className = string.substring(0, string.indexOf(':'));
-        String message = string.substring(string.indexOf(':') + 2); // ignore ':' and leading ' '
+        String className = line.substring(0, line.indexOf(':'));
+        String message = line.substring(line.indexOf(':') + 2); // ignore ':' and leading ' '
 
         return new RecordedThrowable(className, message);
     }


[sling-whiteboard] 11/11: Prevent NPE in test

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1b101fd4e697edd809a74b6c3e9286b528b28a8d
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Wed Jun 12 16:23:16 2019 +0200

    Prevent NPE in test
---
 .../src/test/java/org/apache/sling/uca/impl/AgentIT.java            | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
index dd2bbfe..e8b6ac8 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
@@ -138,15 +138,15 @@ public class AgentIT {
         int exitCode = process.exitValue();
         LOG.info("Exited with code {}", exitCode);
         
-        if ( exitCode != 0 ) {
+        if ( exitCode == 0 ) {
+            throw new RuntimeException("Command terminated successfully. That is unexpected.");
+        } else {
             return Files.lines(STDERR)
                 .filter( l -> l.startsWith("Exception in thread \"main\""))
                 .map( l -> newRecordedThrowable(l) )
                 .findFirst()
                 .orElseThrow(() -> new RuntimeException("Exit code was zero but did not find any exception information in stderr.txt"));
         }
-        
-        return null;
     }
     
     private Process runForkedCommandWithAgent(URL url, int connectTimeoutSeconds, int readTimeoutSeconds, ClientType clientType) throws IOException {


[sling-whiteboard] 04/11: Whitespace fix

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7d419a5017db70046f3c3f5fd27679b2df3d4bf8
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Jun 7 11:47:57 2019 +0200

    Whitespace fix
---
 .../src/test/java/org/apache/sling/uca/impl/AgentIT.java                 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
index 97f0c4c..a14c700 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
@@ -114,7 +114,6 @@ public class AgentIT {
         assertEquals(SocketTimeoutException.class.getName(), error.className);
         assertEquals("Read timed out", error.message);
     }
-    
 
     private RecordedThrowable runTest(String urlSpec, ClientType clientType) throws IOException, InterruptedException {
 


[sling-whiteboard] 01/11: Implement default timeouts for httpclient 4.x

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 69e0fe76b73e5b1be772221fb1ff530bc326351d
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Jun 7 11:33:04 2019 +0200

    Implement default timeouts for httpclient 4.x
---
 url-connection-agent/README.md                     |  5 +-
 url-connection-agent/pom.xml                       |  6 ++
 .../main/java/org/apache/sling/uca/impl/Agent.java |  3 +-
 .../uca/impl/HttpClient4TimeoutTransformer.java    | 70 ++++++++++++++++++++++
 .../java/org/apache/sling/uca/impl/AgentIT.java    | 37 +++++++++---
 .../test/java/org/apache/sling/uca/impl/Main.java  | 29 ++++++++-
 6 files changed, 139 insertions(+), 11 deletions(-)

diff --git a/url-connection-agent/README.md b/url-connection-agent/README.md
index d39b235..fcc5d06 100644
--- a/url-connection-agent/README.md
+++ b/url-connection-agent/README.md
@@ -15,7 +15,7 @@ Build the project with `mvn clean package` and then run a simple connection test
  - `<connect-timeout>` - connection timeout in milliseconds
  - `<read-timeout>`- read timeout in milliseconds
  - `<url>` - the URL to access
- - `<client-type>` - the client type, either `JavaNet` for java.net.URL-based connections or `HC3` for commons-httpclient 3.x
+ - `<client-type>` - the client type, either `JavaNet` for java.net.URL-based connections ,`HC3` for Apache Commons HttpClient 3.x or `HC4` for Apache Commons HttpClient 4.x
  
  
  For a test that always fails, set one of the timeouts to 1. Both executions listed below will typically fail:
@@ -35,4 +35,5 @@ java -javaagent:target/url-connection-agent-0.0.1-SNAPSHOT-jar-with-dependencies
 
 * openjdk version "1.8.0_212"
 * openjdk version "11.0.2" 2019-01-15
-* commons-httpclient 3.1
\ No newline at end of file
+* commons-httpclient 3.1
+* httpclient 4.5.4
\ No newline at end of file
diff --git a/url-connection-agent/pom.xml b/url-connection-agent/pom.xml
index b020df3..c148a64 100644
--- a/url-connection-agent/pom.xml
+++ b/url-connection-agent/pom.xml
@@ -127,5 +127,11 @@
             <version>1.7.25</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.4</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
index 4ed0067..c35565f 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
@@ -37,7 +37,8 @@ public class Agent {
 
         ClassFileTransformer[] transformers = new ClassFileTransformer[] {
             new JavaNetTimeoutTransformer(connectTimeout, readTimeout),
-            new HttpClient3TimeoutTransformer(connectTimeout, readTimeout)
+            new HttpClient3TimeoutTransformer(connectTimeout, readTimeout),
+            new HttpClient4TimeoutTransformer(connectTimeout, readTimeout)
         };
         
         for ( ClassFileTransformer transformer : transformers )
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
new file mode 100644
index 0000000..ee62458
--- /dev/null
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.uca.impl;
+
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtField;
+import javassist.bytecode.Descriptor;
+
+public class HttpClient4TimeoutTransformer implements ClassFileTransformer {
+
+    // org.apache.http.client.config.RequestConfig.Builder
+    
+    private static final String REQUEST_CONFIG_BUILDER_CLASS_NAME = Descriptor.toJvmName("org.apache.http.client.config.RequestConfig$Builder");
+    
+    private final long connectTimeoutMillis;
+    private final long readTimeoutMillis;
+    
+    public HttpClient4TimeoutTransformer(long connectTimeoutMillis, long readTimeoutMillis) {
+        this.connectTimeoutMillis = connectTimeoutMillis;
+        this.readTimeoutMillis = readTimeoutMillis;
+    }
+
+    @Override
+    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
+            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
+        try {
+            if ( REQUEST_CONFIG_BUILDER_CLASS_NAME.equals(className) ) {
+                System.out.println("[AGENT] Asked to transform " + className);
+                
+                ClassPool defaultPool = ClassPool.getDefault();
+                CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
+                
+                // TODO - access the default constructor explicitly in case it changes
+                CtConstructor noArgCtor =  cc.getConstructors()[0];
+                CtField connectTimeout = cc.getDeclaredField("connectTimeout");
+                CtField socketTimeout = cc.getDeclaredField("socketTimeout");
+                noArgCtor.insertAfter("this." + connectTimeout.getName() + " = " + connectTimeoutMillis + ";");
+                noArgCtor.insertAfter("this." + socketTimeout.getName() + " = " + readTimeoutMillis + ";");
+                
+                classfileBuffer = cc.toBytecode();
+                cc.detach();
+            }
+            return classfileBuffer;
+        } catch (Exception e) {
+            e.printStackTrace(); // ensure _something_ is printed
+            throw new RuntimeException("[AGENT] Transformation failed", e);
+        }
+    }
+
+}
diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
index 65bd7af..97f0c4c 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/AgentIT.java
@@ -19,6 +19,7 @@ package org.apache.sling.uca.impl;
 import static java.time.Duration.ofSeconds;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTimeout;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
 import java.io.IOException;
@@ -75,11 +76,29 @@ public class AgentIT {
 
         RecordedThrowable error = assertTimeout(ofSeconds(5),  () -> runTest("http://repo1.maven.org:81", clientType));
         
-        Class<?> expectedClass = clientType == ClientType.HC3 ? ConnectTimeoutException.class : SocketTimeoutException.class;
-        String expectedMessage = clientType == ClientType.HC3 ? "The host did not accept the connection within timeout of 3000 ms" : "connect timed out";
+        Class<?> expectedClass;
+        String expectedMessageRegex;
+        
+        switch ( clientType ) {
+            case JavaNet:
+                expectedClass= SocketTimeoutException.class;
+                expectedMessageRegex = "connect timed out";
+                break;
+            case HC3:
+                expectedClass = ConnectTimeoutException.class;
+                expectedMessageRegex = "The host did not accept the connection within timeout of 3000 ms";
+                break;
+            case HC4:
+                expectedClass = org.apache.http.conn.ConnectTimeoutException.class;
+                expectedMessageRegex = "Connect to repo1.maven.org:81 \\[.*\\] failed: connect timed out";
+                break;
+            default:
+                throw new AssertionError("Unhandled clientType " + clientType);
+        }
         
         assertEquals(expectedClass.getName(), error.className);
-        assertEquals(expectedMessage, error.message);
+        assertTrue(error.message.matches(expectedMessageRegex), 
+            "Actual message " + error.message + " did not match regex " + expectedMessageRegex);
     }
 
     /**
@@ -169,7 +188,9 @@ public class AgentIT {
                     || p.getFileName().toString().equals("commons-codec.jar")
                     || p.getFileName().toString().equals("slf4j-simple.jar")
                     || p.getFileName().toString().equals("slf4j-api.jar")
-                    || p.getFileName().toString().equals("jcl-over-slf4j.jar"))
+                    || p.getFileName().toString().equals("jcl-over-slf4j.jar")
+                    || p.getFileName().toString().contentEquals("httpclient.jar")
+                    || p.getFileName().toString().contentEquals("httpcore.jar") )
             .forEach( p -> elements.add(p.toString()));
         
         return String.join(File.pathSeparator, elements);
@@ -177,10 +198,12 @@ public class AgentIT {
 
     private RecordedThrowable newRecordedThrowable(String string) {
      
-        string = string.replace("Exception in thread \"main\"", "");
-        String[] parts = string.split(":");
+        string = string.replace("Exception in thread \"main\" ", "");
+
+        String className = string.substring(0, string.indexOf(':'));
+        String message = string.substring(string.indexOf(':') + 2); // ignore ':' and leading ' '
 
-        return new RecordedThrowable(parts[0].trim(), parts[1].trim());
+        return new RecordedThrowable(className, message);
     }
     
     /**
diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/Main.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/Main.java
index de07a23..aee0725 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/Main.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/Main.java
@@ -33,12 +33,18 @@ 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.HttpMethodParams;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
 
 public class Main {
     
     // TODO - write help messages with the values from this enum
     public enum ClientType {
-        JavaNet, HC3
+        JavaNet, HC3, HC4
     }
 
     public static void main(String[] args) throws MalformedURLException, IOException {
@@ -55,6 +61,9 @@ public class Main {
             case "HC3":
                 runUsingHttpClient3(args[0]);
                 break;
+            case "HC4":
+                runUsingHttpClient4(args[0]);
+                break;
             default:
                 throw new IllegalArgumentException("Usage: java -cp ... " + Main.class.getName() + " <URL> JavaNet|HC3|HC4");
         }
@@ -104,4 +113,22 @@ public class Main {
             }
         }
     }
+    
+    private static void runUsingHttpClient4(String targetUrl) throws IOException {
+        // disable retries, to make sure that we get equivalent behaviour with other implementations
+        try ( CloseableHttpClient client = HttpClients.custom().disableAutomaticRetries().build() ) {
+            HttpGet get = new HttpGet(targetUrl);
+            try ( CloseableHttpResponse response = client.execute(get)) {
+                System.out.println("[WEB] " + response.getStatusLine());
+                for ( org.apache.http.Header header : response.getAllHeaders() )
+                    System.out.println("[WEB] " + header);
+                
+                HttpEntity entity = response.getEntity();
+                // TODO - print response body
+                EntityUtils.consume(entity);
+            }
+            
+        }
+    }
+
 }


[sling-whiteboard] 10/11: Use a per-test-method instance of the mock server.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b9fcb9a461e9144743ac1cd39a83ab6da34c7a81
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Wed Jun 12 16:21:57 2019 +0200

    Use a per-test-method instance of the mock server.
---
 .../org/apache/sling/uca/impl/MisbehavingServerExtension.java  | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java
index 601adfd..b659451 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java
@@ -28,8 +28,8 @@ import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.ServerConnector;
 import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.junit.jupiter.api.extension.AfterAllCallback;
-import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.api.extension.ParameterContext;
 import org.junit.jupiter.api.extension.ParameterResolutionException;
@@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory;
  * will be resolved.</p>
  *
  */
-class MisbehavingServerExtension implements BeforeAllCallback, AfterAllCallback, ParameterResolver, MisbehavingServerControl {
+class MisbehavingServerExtension implements BeforeEachCallback, AfterEachCallback, ParameterResolver, MisbehavingServerControl {
     
     private final Logger logger = LoggerFactory.getLogger(getClass());
     
@@ -70,7 +70,7 @@ class MisbehavingServerExtension implements BeforeAllCallback, AfterAllCallback,
     }
     
     @Override
-    public void beforeAll(ExtensionContext context) throws Exception {
+    public void beforeEach(ExtensionContext context) throws Exception {
         
         server = new Server();
         ServerConnector connector = new ServerConnector(server) {
@@ -104,7 +104,7 @@ class MisbehavingServerExtension implements BeforeAllCallback, AfterAllCallback,
     }
 
     @Override
-    public void afterAll(ExtensionContext context) throws Exception {
+    public void afterEach(ExtensionContext context) throws Exception {
         if ( server == null )
             return;
         try {