You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by as...@apache.org on 2015/02/02 10:54:54 UTC

[3/4] cxf git commit: [CXF-6227] Adding a convenient Address abstraction to the http transports to avoid useless (and costly) URI->URL->URI conversions

[CXF-6227] Adding a convenient Address abstraction to the http transports to avoid useless (and costly) URI->URL->URI conversions


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/c2d62df7
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/c2d62df7
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/c2d62df7

Branch: refs/heads/3.0.x-fixes
Commit: c2d62df737b73098ba55059fa872eb9b717b525c
Parents: 34f0aa6
Author: Alessio Soldano <as...@redhat.com>
Authored: Fri Jan 30 14:41:42 2015 +0100
Committer: Alessio Soldano <as...@redhat.com>
Committed: Mon Feb 2 10:33:11 2015 +0100

----------------------------------------------------------------------
 .../http/asyncclient/AsyncHTTPConduit.java      | 14 +++--
 .../http/netty/client/NettyHttpConduit.java     | 12 +++--
 .../org/apache/cxf/transport/http/Address.java  | 55 ++++++++++++++++++++
 .../apache/cxf/transport/http/HTTPConduit.java  | 20 +++----
 .../http/URLConnectionHTTPConduit.java          | 32 +++++++-----
 .../websocket/ahc/AhcWebSocketConduit.java      |  4 +-
 6 files changed, 105 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/c2d62df7/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java
----------------------------------------------------------------------
diff --git a/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java b/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java
index 77815fa..47bf717 100644
--- a/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java
+++ b/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java
@@ -61,6 +61,7 @@ import org.apache.cxf.io.CopyingOutputStream;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.http.Address;
 import org.apache.cxf.transport.http.Headers;
 import org.apache.cxf.transport.http.URLConnectionHTTPConduit;
 import org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduitFactory.UseAsyncPolicy;
@@ -127,17 +128,21 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit {
         return factory;
     }
     
-    protected void setupConnection(Message message, URI uri, HTTPClientPolicy csPolicy) throws IOException {
+    @Override
+    protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException {
         if (factory.isShutdown()) {
             message.put(USE_ASYNC, Boolean.FALSE);
-            super.setupConnection(message, uri, csPolicy);
+            super.setupConnection(message, address, csPolicy);
             return;
         }
+        boolean addressChanged = false;
         // need to do some clean up work on the URI address
+        URI uri = address.getURI();
         String uriString = uri.toString();
         if (uriString.startsWith("hc://")) {
             try {
                 uri = new URI(uriString.substring(5));
+                addressChanged = true;
             } catch (URISyntaxException ex) {
                 throw new MalformedURLException("unsupport uri: "  + uriString);
             }
@@ -179,12 +184,13 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit {
         }
         if (!MessageUtils.isTrue(o)) {
             message.put(USE_ASYNC, Boolean.FALSE);
-            super.setupConnection(message, uri, csPolicy);
+            super.setupConnection(message, addressChanged ? new Address(uri) : address, csPolicy);
             return;
         }
         if (StringUtils.isEmpty(uri.getPath())) {
             //hc needs to have the path be "/" 
             uri = uri.resolve("/");
+            addressChanged = true;
         }
 
         message.put(USE_ASYNC, Boolean.TRUE);
@@ -823,7 +829,7 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit {
             outbuf = new SharedOutputBuffer(bufSize, allocator);
             try {
                 this.url = new URI(newURL);
-                setupConnection(outMessage, this.url, csPolicy);
+                setupConnection(outMessage, new Address(this.url), csPolicy);
                 entity = outMessage.get(CXFHttpRequest.class);
                 basicEntity = (BasicHttpEntity)entity.getEntity();
                 entity.setOutputStream(this);

http://git-wip-us.apache.org/repos/asf/cxf/blob/c2d62df7/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java
----------------------------------------------------------------------
diff --git a/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java b/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java
index c5006a3..c81b4d2 100644
--- a/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java
+++ b/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java
@@ -48,6 +48,7 @@ import org.apache.cxf.io.CacheAndWriteOutputStream;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.http.Address;
 import org.apache.cxf.transport.http.Headers;
 import org.apache.cxf.transport.http.URLConnectionHTTPConduit;
 import org.apache.cxf.transport.https.HttpsURLConnectionInfo;
@@ -91,15 +92,17 @@ public class NettyHttpConduit extends URLConnectionHTTPConduit implements BusLif
     }
     
     // Using Netty API directly
-    protected void setupConnection(Message message, URI uri, HTTPClientPolicy csPolicy) throws IOException {
-        
+    protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException {
         
+        URI uri = address.getURI();
+        boolean addressChanged = false;
         
         // need to do some clean up work on the URI address
         String uriString = uri.toString();
         if (uriString.startsWith("netty://")) {
             try {
                 uri = new URI(uriString.substring(8));
+                addressChanged = true;
             } catch (URISyntaxException ex) {
                 throw new MalformedURLException("unsupport uri: "  + uriString);
             }
@@ -141,7 +144,7 @@ public class NettyHttpConduit extends URLConnectionHTTPConduit implements BusLif
         }
         if (!MessageUtils.isTrue(o)) {
             message.put(USE_ASYNC, Boolean.FALSE);
-            super.setupConnection(message, uri, csPolicy);
+            super.setupConnection(message, addressChanged ? new Address(uri) : address, csPolicy);
             return;
         }
         message.put(USE_ASYNC, Boolean.TRUE);
@@ -542,7 +545,8 @@ public class NettyHttpConduit extends URLConnectionHTTPConduit implements BusLif
 
             try {
                 this.url = new URI(newURL);
-                setupConnection(outMessage, this.url, csPolicy);
+                Address address = new Address(this.url);
+                setupConnection(outMessage, address, csPolicy);
                 entity = outMessage.get(NettyHttpClientRequest.class);
                 //reset the buffers
                 outBuffer.clear();

http://git-wip-us.apache.org/repos/asf/cxf/blob/c2d62df7/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Address.java
----------------------------------------------------------------------
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Address.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Address.java
new file mode 100644
index 0000000..745b45f
--- /dev/null
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Address.java
@@ -0,0 +1,55 @@
+/**
+ * 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.cxf.transport.http;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+
+/**
+ * A convenient class for storing URI and URL representation of an address and avoid useless conversions.
+ * The class is thread-safe.
+ */
+@NoJSR250Annotations
+public final class Address {  
+
+    private final URI uri;
+    private volatile URL url;
+    
+    public Address(URI uri) {
+        this.uri = uri;
+    }
+    
+    public URL getURL() throws MalformedURLException {
+        if (url == null) {
+            synchronized (this) {
+                if (url == null) {
+                    url = uri.toURL();
+                }
+            }
+        }
+        return url;
+    }
+    
+    public URI getURI() {
+        return uri;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c2d62df7/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
----------------------------------------------------------------------
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
index 836b530..4c81fb8 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
@@ -153,6 +153,7 @@ public abstract class HTTPConduit
      *  is used to get the response.
      */
     public static final String KEY_HTTP_CONNECTION = "http.connection";
+    public static final String KEY_HTTP_CONNECTION_ADDRESS = "http.connection.address";
 
     /**
      * The Logger for this class.
@@ -442,7 +443,8 @@ public abstract class HTTPConduit
     }
     
 
-    protected abstract void setupConnection(Message message, URI url, HTTPClientPolicy csPolicy) throws IOException;
+    protected abstract void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy)
+        throws IOException;
 
     /**
      * Prepare to send an outbound HTTP message over this http conduit to a 
@@ -469,9 +471,9 @@ public abstract class HTTPConduit
         // This call can possibly change the conduit endpoint address and 
         // protocol from the default set in EndpointInfo that is associated
         // with the Conduit.
-        URI currentURI;
+        Address currentAddress;
         try {
-            currentURI = setupURI(message);
+            currentAddress = setupAddress(message);
         } catch (URISyntaxException e) {
             throw new IOException(e);
         }       
@@ -480,7 +482,7 @@ public abstract class HTTPConduit
         boolean needToCacheRequest = false;
         
         HTTPClientPolicy csPolicy = getClient(message);
-        setupConnection(message, currentURI, csPolicy);
+        setupConnection(message, currentAddress, csPolicy);
         
         // If the HTTP_REQUEST_METHOD is not set, the default is "POST".
         String httpRequestMethod = 
@@ -539,7 +541,7 @@ public abstract class HTTPConduit
             message.getInterceptorChain().add(CertConstraintsInterceptor.INSTANCE);
         }
 
-        setHeadersByAuthorizationPolicy(message, currentURI);
+        setHeadersByAuthorizationPolicy(message, currentAddress.getURI());
         new Headers(message).setFromClientPolicy(getClient(message));
         message.setContent(OutputStream.class, 
                            createOutputStream(message,
@@ -656,7 +658,7 @@ public abstract class HTTPConduit
      * @throws MalformedURLException
      * @throws URISyntaxException 
      */
-    private URI setupURI(Message message) throws URISyntaxException {
+    private Address setupAddress(Message message) throws URISyntaxException {
         String result = (String)message.get(Message.ENDPOINT_ADDRESS);
         String pathInfo = (String)message.get(Message.PATH_INFO);
         String queryString = (String)message.get(Message.QUERY_STRING);
@@ -664,7 +666,7 @@ public abstract class HTTPConduit
             if (pathInfo == null && queryString == null) {
                 URI uri = getURI();
                 message.put(Message.ENDPOINT_ADDRESS, defaultEndpointURIString);
-                return uri;
+                return new Address(uri);
             }
             result = getURI().toString();
             message.put(Message.ENDPOINT_ADDRESS, result);
@@ -677,7 +679,7 @@ public abstract class HTTPConduit
         if (queryString != null) {
             result = result + "?" + queryString;
         }        
-        return new URI(result);    
+        return new Address(new URI(result));
     }
 
 
@@ -1876,6 +1878,4 @@ public abstract class HTTPConduit
         // Register that we have been here before we go.
         authURLs.add(currentURL.toString() + realm);
     }
-
-    
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/c2d62df7/rt/transports/http/src/main/java/org/apache/cxf/transport/http/URLConnectionHTTPConduit.java
----------------------------------------------------------------------
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/URLConnectionHTTPConduit.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/URLConnectionHTTPConduit.java
index 9f44f35..6fdfe79 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/URLConnectionHTTPConduit.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/URLConnectionHTTPConduit.java
@@ -88,8 +88,10 @@ public class URLConnectionHTTPConduit extends HTTPConduit {
         }
     }    
     
-    private HttpURLConnection createConnection(Message message, URI uri, HTTPClientPolicy csPolicy) throws IOException {
-        URL url = uri.toURL();
+    private HttpURLConnection createConnection(Message message, Address address, HTTPClientPolicy csPolicy)
+        throws IOException {
+        URL url = address.getURL();
+        URI uri = address.getURI();
         Proxy proxy = proxyFactory.createProxy(csPolicy , uri);
         message.put("http.scheme", uri.getScheme());
         // check tlsClientParameters from message header
@@ -99,8 +101,8 @@ public class URLConnectionHTTPConduit extends HTTPConduit {
         }
         return connectionFactory.createConnection(clientParameters, proxy, url);
     }
-    protected void setupConnection(Message message, URI currentURL, HTTPClientPolicy csPolicy) throws IOException {
-        HttpURLConnection connection = createConnection(message, currentURL, csPolicy);
+    protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException {
+        HttpURLConnection connection = createConnection(message, address, csPolicy);
         connection.setDoOutput(true);       
         
         int ctimeout = determineConnectionTimeout(message, csPolicy);
@@ -127,6 +129,7 @@ public class URLConnectionHTTPConduit extends HTTPConduit {
         // We place the connection on the message to pick it up
         // in the WrappedOutputStream.
         message.put(KEY_HTTP_CONNECTION, connection);
+        message.put(KEY_HTTP_CONNECTION_ADDRESS, address);
     }
 
     
@@ -151,6 +154,11 @@ public class URLConnectionHTTPConduit extends HTTPConduit {
         }
     }
     
+    private static URI computeURI(Message message, HttpURLConnection connection) throws URISyntaxException {
+        Address address = (Address)message.get(KEY_HTTP_CONNECTION_ADDRESS);
+        return address != null ? address.getURI() : connection.getURL().toURI();
+    }
+    
     class URLConnectionWrappedOutputStream extends WrappedOutputStream {
         HttpURLConnection connection;
         public URLConnectionWrappedOutputStream(Message message, HttpURLConnection connection,
@@ -158,9 +166,10 @@ public class URLConnectionHTTPConduit extends HTTPConduit {
                                                 int chunkThreshold, String conduitName) throws URISyntaxException {
             super(message, needToCacheRequest, isChunking,
                   chunkThreshold, conduitName,
-                  connection.getURL().toURI());
+                  computeURI(message, connection));
             this.connection = connection;
         }
+        
         // This construction makes extending the HTTPConduit more easier 
         protected URLConnectionWrappedOutputStream(URLConnectionWrappedOutputStream wos) {
             super(wos);
@@ -285,18 +294,15 @@ public class URLConnectionHTTPConduit extends HTTPConduit {
         }
         protected void setupNewConnection(String newURL) throws IOException {
             HTTPClientPolicy cp = getClient(outMessage);
-            URI nurl;
+            Address address;
             try {
-                nurl = new URI(newURL);
+                URI nurl = new URI(newURL);
+                address = new Address(nurl);
             } catch (URISyntaxException e) {
                 throw new IOException(e);
             }
-            setupConnection(outMessage, nurl, cp);
-            try {
-                url = new URI(newURL);
-            } catch (URISyntaxException e) {
-                throw new IOException(e); 
-            }
+            setupConnection(outMessage, address, cp);
+            this.url = address.getURI();
             connection = (HttpURLConnection)outMessage.get(KEY_HTTP_CONNECTION);
         }
 

http://git-wip-us.apache.org/repos/asf/cxf/blob/c2d62df7/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/ahc/AhcWebSocketConduit.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/ahc/AhcWebSocketConduit.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/ahc/AhcWebSocketConduit.java
index 68d6407..d6ef890 100644
--- a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/ahc/AhcWebSocketConduit.java
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/ahc/AhcWebSocketConduit.java
@@ -43,6 +43,7 @@ import org.apache.cxf.Bus;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.http.Address;
 import org.apache.cxf.transport.http.Headers;
 import org.apache.cxf.transport.http.URLConnectionHTTPConduit;
 import org.apache.cxf.transport.https.HttpsURLConnectionInfo;
@@ -72,9 +73,10 @@ public class AhcWebSocketConduit extends URLConnectionHTTPConduit {
     }
 
     @Override
-    protected void setupConnection(Message message, URI currentURL, HTTPClientPolicy csPolicy)
+    protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy)
         throws IOException {
 
+        URI currentURL = address.getURI();
         String s = currentURL.getScheme();
         if (!"ws".equals(s) && !"wss".equals(s)) {
             throw new MalformedURLException("unknown protocol: " + s);