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/05/23 15:54:21 UTC

[sling-whiteboard] branch feature/url-connection-agent created (now 79372f4)

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

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


      at 79372f4  POC for a Java Agent to set URL connection timeout defaults

This branch includes the following new commits:

     new e0698ee  POC for a Java Agent to set URL connection timeout defaults
     new 964966d  POC for a Java Agent to set URL connection timeout defaults
     new 7da88ff  POC for a Java Agent to set URL connection timeout defaults
     new 517438d  POC for a Java Agent to set URL connection timeout defaults
     new a571d16  Added README
     new eeae0f4  POC for a Java Agent to set URL connection timeout defaults
     new e6f3f4b  POC for a Java Agent to set URL connection timeout defaults
     new 79372f4  POC for a Java Agent to set URL connection timeout defaults

The 8 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.



[sling-whiteboard] 05/08: Added README

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

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

commit a571d16b67389f2b23f4833d5e5cc70000adfc80
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 23 17:49:54 2019 +0200

    Added README
---
 url-connection-agent/README.md | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/url-connection-agent/README.md b/url-connection-agent/README.md
new file mode 100644
index 0000000..108d9db
--- /dev/null
+++ b/url-connection-agent/README.md
@@ -0,0 +1,35 @@
+# Apache Sling URL connection agent
+
+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.
+
+## Launching
+
+Build the project with `mvn clean package` and then run a simple connection test with 
+
+    java -javaagent:target/url-connection-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar -cp target/url-connection-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar=<connect-timeout>,<read-timeout> org.apache.sling.uca.impl.Main <url>
+    
+ The parameters are as follows:
+ 
+ - `<connect-timeout>` - connection timeout in milliseconds
+ - `<read-timeout>`- read timeout in milliseconds
+ - `<url>` - the URL to access
+ 
+ For a test that always fails, set one of the timeouts to 1. Both executions listed below will typically fail:
+ 
+ ```
+java -javaagent:target/url-connection-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar=1,1000 -cp target/url-connection-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar org.apache.sling.uca.impl.Main https://sling.apache.org
+java -javaagent:target/url-connection-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar=1000,1 -cp target/url-connection-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar org.apache.sling.uca.impl.Main https://sling.apache.org
+ ```
+ 
+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/url-connection-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar org.apache.sling.uca.impl.Main https://sling.apache.org
+```
+
+## Tested platforms
+
+* openjdk version "1.8.0_212"
+* openjdk version "11.0.2" 2019-01-15
\ No newline at end of file


[sling-whiteboard] 04/08: POC for a Java Agent to set URL connection timeout defaults

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

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

commit 517438dc419eca4f642e903d4fe18a75fb61f13e
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 23 17:48:55 2019 +0200

    POC for a Java Agent to set URL connection timeout defaults
    
    Correct parameter assignment
---
 .../main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java
index a5b720d..ea8f8ae 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java
@@ -35,8 +35,8 @@ class URLTimeoutTransformer implements ClassFileTransformer {
     private final long connectTimeoutMillis;
 
     public URLTimeoutTransformer(long connectTimeout, long readTimeout) {
-        this.readTimeoutMillis = connectTimeout;
-        this.connectTimeoutMillis = readTimeout;
+        this.connectTimeoutMillis = connectTimeout;
+        this.readTimeoutMillis = readTimeout;
     }
 
     @Override


[sling-whiteboard] 02/08: POC for a Java Agent to set URL connection timeout defaults

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

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

commit 964966de9ddb1bcf755d37e185cf75952728ae56
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 23 16:32:19 2019 +0200

    POC for a Java Agent to set URL connection timeout defaults
    
    Start intercepting URL calls
---
 .../main/java/org/apache/sling/uca/impl/Agent.java | 28 ++++++++++++----------
 .../main/java/org/apache/sling/uca/impl/Main.java  | 13 ++++------
 2 files changed, 21 insertions(+), 20 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 909bb9e..1391182 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
@@ -4,9 +4,10 @@ import java.io.IOException;
 import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.IllegalClassFormatException;
 import java.lang.instrument.Instrumentation;
-import java.lang.instrument.UnmodifiableClassException;
 import java.security.ProtectionDomain;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
 
 import javassist.CannotCompileException;
 import javassist.ClassPool;
@@ -19,12 +20,7 @@ public class Agent {
     public static void premain(String args, Instrumentation inst) {
 
         System.out.println("Loading agent...");
-        inst.addTransformer(new HashMapTransformer(), true);
-        try {
-            inst.retransformClasses(HashMap.class);
-        } catch (UnmodifiableClassException e) {
-            throw new RuntimeException(e);
-        }
+        inst.addTransformer(new URLTimeoutTransformer(), true);
         System.out.println("Loaded agent!");
     }
     
@@ -32,19 +28,27 @@ public class Agent {
         premain(args, inst);
     }
 
-    static class HashMapTransformer implements ClassFileTransformer {
-
+    static class URLTimeoutTransformer implements ClassFileTransformer {
+        
+        private static final Set<String> CLASSES_TO_TRANSFORM = new HashSet<>();
+        
+        static {
+            CLASSES_TO_TRANSFORM.add("sun.net.www.protocol.http.HttpURLConnection".replace('.', '/'));
+            CLASSES_TO_TRANSFORM.add("sun.net.www.protocol.https.HttpsURLConnectionImpl".replace('.', '/'));
+        }
+        
         private final Class<?> klazz = HashMap.class;
         
         @Override
         public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                 ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
             try {
-                if ( classBeingRedefined == klazz) {
+                if ( CLASSES_TO_TRANSFORM.contains(className)) {
                     System.out.println("Asked to transform " + className);
                     CtClass cc = ClassPool.getDefault().get(klazz.getName());
-                    CtMethod putMethod = cc.getDeclaredMethod("put");
-                    putMethod.insertAfter("System.out.println(\"[AGENT] Adding key \" + key );");
+                    CtMethod connectMethod = cc.getDeclaredMethod("connect");
+                    connectMethod.insertBefore("if ( getConnectTimeout() == 0 ) { setConnectTimeout(60); }");
+                    connectMethod.insertBefore("if ( getReadTimeout() == 0 ) { setReadTimeout(60); }");
                     classfileBuffer = cc.toBytecode();
                     cc.detach();
                     System.err.println("Transformation complete!");
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
index 9cf5802..21bcbb7 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
@@ -1,17 +1,14 @@
 package org.apache.sling.uca.impl;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
 
 public class Main {
     
-    public static void main(String[] args) {
+    public static void main(String[] args) throws MalformedURLException, IOException {
         
-        Map<String, String> map = new HashMap<>();
-        map.put("foo", "bar");
-        map.put("foo", "baz");
-        
-        System.out.println(map.get("foo"));
+        new URL("http://sling.apache.org").openConnection();
     }
 
 }


[sling-whiteboard] 01/08: POC for a Java Agent to set URL connection timeout defaults

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

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

commit e0698ee153f560de36ebba1a47f50e8ca6ef8b5f
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue May 21 17:57:28 2019 +0200

    POC for a Java Agent to set URL connection timeout defaults
    
    Initial work towards intercepting HashMap calls, to prove that it can work for core JVM classes.
---
 url-connection-agent/pom.xml                       | 51 +++++++++++++++++++
 .../main/java/org/apache/sling/uca/impl/Agent.java | 59 ++++++++++++++++++++++
 .../main/java/org/apache/sling/uca/impl/Main.java  | 17 +++++++
 3 files changed, 127 insertions(+)

diff --git a/url-connection-agent/pom.xml b/url-connection-agent/pom.xml
new file mode 100644
index 0000000..cdaf3e1
--- /dev/null
+++ b/url-connection-agent/pom.xml
@@ -0,0 +1,51 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>35</version>
+    </parent>
+    <artifactId>url-connection-agent</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <archiveBaseDirectory>${project.basedir}</archiveBaseDirectory>
+                            <archive>
+                                <manifestEntries>
+                                    <Agent-Class>org.apache.sling.uca.impl.Agent</Agent-Class>
+                                    <Premain-Class>org.apache.sling.uca.impl.Agent</Premain-Class>
+                                    <Can-Redefine-Classes>true</Can-Redefine-Classes>
+                                    <Can-Retransform-Classes>true</Can-Retransform-Classes>
+                                </manifestEntries>
+                            </archive>
+                            <descriptorRefs>
+                                <descriptorRef>jar-with-dependencies</descriptorRef>
+                            </descriptorRefs>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>3.24.0-GA</version>
+        </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
new file mode 100644
index 0000000..909bb9e
--- /dev/null
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
@@ -0,0 +1,59 @@
+package org.apache.sling.uca.impl;
+
+import java.io.IOException;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.lang.instrument.Instrumentation;
+import java.lang.instrument.UnmodifiableClassException;
+import java.security.ProtectionDomain;
+import java.util.HashMap;
+
+import javassist.CannotCompileException;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+
+public class Agent {
+
+    public static void premain(String args, Instrumentation inst) {
+
+        System.out.println("Loading agent...");
+        inst.addTransformer(new HashMapTransformer(), true);
+        try {
+            inst.retransformClasses(HashMap.class);
+        } catch (UnmodifiableClassException e) {
+            throw new RuntimeException(e);
+        }
+        System.out.println("Loaded agent!");
+    }
+    
+    public static void agentmain(String args, Instrumentation inst) {
+        premain(args, inst);
+    }
+
+    static class HashMapTransformer implements ClassFileTransformer {
+
+        private final Class<?> klazz = HashMap.class;
+        
+        @Override
+        public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
+                ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
+            try {
+                if ( classBeingRedefined == klazz) {
+                    System.out.println("Asked to transform " + className);
+                    CtClass cc = ClassPool.getDefault().get(klazz.getName());
+                    CtMethod putMethod = cc.getDeclaredMethod("put");
+                    putMethod.insertAfter("System.out.println(\"[AGENT] Adding key \" + key );");
+                    classfileBuffer = cc.toBytecode();
+                    cc.detach();
+                    System.err.println("Transformation complete!");
+                }
+                return classfileBuffer;
+            } catch (NotFoundException | CannotCompileException | IOException e) {
+                throw new RuntimeException("Transformation failed", e);
+            }
+        }
+    }
+}
+    
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
new file mode 100644
index 0000000..9cf5802
--- /dev/null
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
@@ -0,0 +1,17 @@
+package org.apache.sling.uca.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Main {
+    
+    public static void main(String[] args) {
+        
+        Map<String, String> map = new HashMap<>();
+        map.put("foo", "bar");
+        map.put("foo", "baz");
+        
+        System.out.println(map.get("foo"));
+    }
+
+}


[sling-whiteboard] 08/08: POC for a Java Agent to set URL connection timeout defaults

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

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

commit 79372f4c9a44f496f83e3bcbca01622f88f76fae
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 23 17:53:56 2019 +0200

    POC for a Java Agent to set URL connection timeout defaults
    
    Add to reactor pom
---
 pom.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/pom.xml b/pom.xml
index 406d475..db99403 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,6 +41,7 @@
     <modules>
           <module>mdresourceprovider</module>
           <module>maven-central-source-reporter</module>
+          <module>url-connection-agent</module>
     </modules>
 </project>
 


[sling-whiteboard] 06/08: POC for a Java Agent to set URL connection timeout defaults

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

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

commit eeae0f47d509322264b54ab3774f72ab89eefcb8
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 23 17:52:09 2019 +0200

    POC for a Java Agent to set URL connection timeout defaults
    
    Add license headers
---
 url-connection-agent/pom.xml                           | 18 ++++++++++++++++++
 .../src/main/java/org/apache/sling/uca/impl/Agent.java | 16 ++++++++++++++++
 .../src/main/java/org/apache/sling/uca/impl/Main.java  | 16 ++++++++++++++++
 .../apache/sling/uca/impl/URLTimeoutTransformer.java   | 16 ++++++++++++++++
 .../sling/uca/impl/UrlTimeoutTransformerTest.java      | 16 ++++++++++++++++
 5 files changed, 82 insertions(+)

diff --git a/url-connection-agent/pom.xml b/url-connection-agent/pom.xml
index 6945823..9a4c75a 100644
--- a/url-connection-agent/pom.xml
+++ b/url-connection-agent/pom.xml
@@ -1,3 +1,21 @@
+<!--
+    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.
+-->
 <project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
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 36f7c65..2b27373 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
@@ -1,3 +1,19 @@
+/*
+ * 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.Instrumentation;
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
index 883aa01..e6bc48d 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
@@ -1,3 +1,19 @@
+/*
+ * 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.io.BufferedReader;
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java
index ea8f8ae..1143004 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java
@@ -1,3 +1,19 @@
+/*
+ * 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;
diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/UrlTimeoutTransformerTest.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/UrlTimeoutTransformerTest.java
index 84da14c..774b420 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/UrlTimeoutTransformerTest.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/UrlTimeoutTransformerTest.java
@@ -1,3 +1,19 @@
+/*
+ * 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 org.junit.Assert.assertNotNull;


[sling-whiteboard] 07/08: POC for a Java Agent to set URL connection timeout defaults

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

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

commit e6f3f4bdfa947277f952861fc29f39a3eba80372
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 23 17:52:31 2019 +0200

    POC for a Java Agent to set URL connection timeout defaults
    
    Fixed Maven warnings
---
 url-connection-agent/pom.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/url-connection-agent/pom.xml b/url-connection-agent/pom.xml
index 9a4c75a..01af5b3 100644
--- a/url-connection-agent/pom.xml
+++ b/url-connection-agent/pom.xml
@@ -24,6 +24,7 @@
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
         <version>35</version>
+        <relativePath/>
     </parent>
     <artifactId>url-connection-agent</artifactId>
     <version>0.0.1-SNAPSHOT</version>


[sling-whiteboard] 03/08: POC for a Java Agent to set URL connection timeout defaults

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

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

commit 7da88ff098521199065c765236e4442b60b84798
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 23 17:42:48 2019 +0200

    POC for a Java Agent to set URL connection timeout defaults
    
    Completed initial implementation
---
 url-connection-agent/pom.xml                       |  4 ++
 .../main/java/org/apache/sling/uca/impl/Agent.java | 68 ++++++--------------
 .../main/java/org/apache/sling/uca/impl/Main.java  | 21 +++++-
 .../sling/uca/impl/URLTimeoutTransformer.java      | 74 ++++++++++++++++++++++
 .../sling/uca/impl/UrlTimeoutTransformerTest.java  | 31 +++++++++
 5 files changed, 146 insertions(+), 52 deletions(-)

diff --git a/url-connection-agent/pom.xml b/url-connection-agent/pom.xml
index cdaf3e1..6945823 100644
--- a/url-connection-agent/pom.xml
+++ b/url-connection-agent/pom.xml
@@ -47,5 +47,9 @@
             <artifactId>javassist</artifactId>
             <version>3.24.0-GA</version>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </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 1391182..36f7c65 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
@@ -1,63 +1,31 @@
 package org.apache.sling.uca.impl;
 
-import java.io.IOException;
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
 import java.lang.instrument.Instrumentation;
-import java.security.ProtectionDomain;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-import javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtMethod;
-import javassist.NotFoundException;
+import java.util.concurrent.TimeUnit;
 
 public class Agent {
 
     public static void premain(String args, Instrumentation inst) {
 
-        System.out.println("Loading agent...");
-        inst.addTransformer(new URLTimeoutTransformer(), true);
-        System.out.println("Loaded agent!");
+        System.out.println("[AGENT] Loading agent...");
+        String[] parsedArgs = args.split(",");
+        long connectTimeout =  TimeUnit.MINUTES.toMillis(1);
+        long readTimeout = TimeUnit.MINUTES.toMillis(1);
+        if ( parsedArgs.length > 0 )
+            connectTimeout = Long.parseLong(parsedArgs[0]);
+        if ( parsedArgs.length > 1 )
+            readTimeout = Long.parseLong(parsedArgs[1]);
+        
+        System.out.format("[AGENT] Set connectTimeout : %d, readTimeout: %d%n", connectTimeout, readTimeout);
+
+        URLTimeoutTransformer transformer = new URLTimeoutTransformer(connectTimeout, readTimeout);
+        
+        inst.addTransformer(transformer, true);
+        System.out.println("[AGENT] Loaded agent!");
     }
-    
+
     public static void agentmain(String args, Instrumentation inst) {
         premain(args, inst);
     }
-
-    static class URLTimeoutTransformer implements ClassFileTransformer {
-        
-        private static final Set<String> CLASSES_TO_TRANSFORM = new HashSet<>();
-        
-        static {
-            CLASSES_TO_TRANSFORM.add("sun.net.www.protocol.http.HttpURLConnection".replace('.', '/'));
-            CLASSES_TO_TRANSFORM.add("sun.net.www.protocol.https.HttpsURLConnectionImpl".replace('.', '/'));
-        }
-        
-        private final Class<?> klazz = HashMap.class;
-        
-        @Override
-        public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
-                ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
-            try {
-                if ( CLASSES_TO_TRANSFORM.contains(className)) {
-                    System.out.println("Asked to transform " + className);
-                    CtClass cc = ClassPool.getDefault().get(klazz.getName());
-                    CtMethod connectMethod = cc.getDeclaredMethod("connect");
-                    connectMethod.insertBefore("if ( getConnectTimeout() == 0 ) { setConnectTimeout(60); }");
-                    connectMethod.insertBefore("if ( getReadTimeout() == 0 ) { setReadTimeout(60); }");
-                    classfileBuffer = cc.toBytecode();
-                    cc.detach();
-                    System.err.println("Transformation complete!");
-                }
-                return classfileBuffer;
-            } catch (NotFoundException | CannotCompileException | IOException e) {
-                throw new RuntimeException("Transformation failed", e);
-            }
-        }
-    }
-}
     
+}
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
index 21bcbb7..883aa01 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Main.java
@@ -1,14 +1,31 @@
 package org.apache.sling.uca.impl;
 
+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;
 
 public class Main {
-    
+
     public static void main(String[] args) throws MalformedURLException, IOException {
         
-        new URL("http://sling.apache.org").openConnection();
+        if ( args.length != 1 )
+            throw new IllegalArgumentException("Usage: java -jar ... <URL>");
+
+        URLConnection con = new URL(args[0]).openConnection();
+        System.out.println("Connection type is " + con);
+        
+        try (InputStream in = con.getInputStream();
+                InputStreamReader isr = new InputStreamReader(in);
+                BufferedReader br = new BufferedReader(isr)) {
+            String line;
+            while ( (line = br.readLine()) != null )
+                System.out.println("[WEB] " + line);
+        }
+
     }
 
 }
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java
new file mode 100644
index 0000000..a5b720d
--- /dev/null
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/URLTimeoutTransformer.java
@@ -0,0 +1,74 @@
+package org.apache.sling.uca.impl;
+
+import java.lang.instrument.ClassFileTransformer;
+import java.net.URLConnection;
+import java.security.ProtectionDomain;
+import java.util.HashSet;
+import java.util.Set;
+
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+import javassist.bytecode.Descriptor;
+
+/**
+ * Transforms well-known HTTP URL connection classes
+ * 
+ * <p>This implementation adds connect and read timeouts to those connections
+ * if none are defined.</p>
+ * 
+ * @see URLConnection#getConnectTimeout()
+ * @see URLConnection#getReadTimeout()
+ *
+ */
+class URLTimeoutTransformer implements ClassFileTransformer {
+
+    private static final Set<String> CLASSES_TO_TRANSFORM = new HashSet<>();
+
+    static {
+        CLASSES_TO_TRANSFORM.add(Descriptor.toJvmName("sun.net.www.protocol.http.HttpURLConnection"));
+        CLASSES_TO_TRANSFORM.add(Descriptor.toJvmName("sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection"));
+    }
+
+    private final long readTimeoutMillis;
+    private final long connectTimeoutMillis;
+
+    public URLTimeoutTransformer(long connectTimeout, long readTimeout) {
+        this.readTimeoutMillis = connectTimeout;
+        this.connectTimeoutMillis = readTimeout;
+    }
+
+    @Override
+    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
+            ProtectionDomain protectionDomain, byte[] classfileBuffer) {
+        try {
+            if (CLASSES_TO_TRANSFORM.contains(className)) {
+                System.out.println("[AGENT] Asked to transform " + 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!");
+            }
+            return classfileBuffer;
+        } catch (Exception e) {
+            e.printStackTrace(); // ensure _something_ is printed
+            throw new RuntimeException("[AGENT] Transformation failed", e);
+        }
+    }
+    
+    CtMethod findConnectMethod(String className) throws NotFoundException {
+        
+        ClassPool defaultPool = ClassPool.getDefault();
+        CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
+        if (cc == null) {
+            System.out.println("[AGENT] no class found with name " + className);
+            return null;
+        }
+        return cc.getDeclaredMethod("connect");
+
+    }
+
+}
\ No newline at end of file
diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/UrlTimeoutTransformerTest.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/UrlTimeoutTransformerTest.java
new file mode 100644
index 0000000..84da14c
--- /dev/null
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/UrlTimeoutTransformerTest.java
@@ -0,0 +1,31 @@
+package org.apache.sling.uca.impl;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import javassist.NotFoundException;
+
+public class UrlTimeoutTransformerTest {
+    
+    private URLTimeoutTransformer transformer;
+
+    @Before
+    public void initFields() {
+        transformer = new URLTimeoutTransformer(1, 1);
+    }
+
+    @Test
+    public void findDeclaredConnectMethod() throws NotFoundException {
+        assertNotNull(transformer.findConnectMethod("sun/net/www/protocol/http/HttpURLConnection"));
+    }
+
+    @Test(expected = NotFoundException.class)
+    public void findInheritedConnectMethod() throws NotFoundException {
+        // do NOT look for inherited methods, as we can only rewrite the precise classes the
+        // retransform was triggered for
+        transformer.findConnectMethod("sun/net/www/protocol/https/DelegateHttpsURLConnection");
+    }
+    
+}