Repository: cxf Updated Branches: refs/heads/3.0.x-fixes f7d259db9 -> 1b7e0dfc9
[CXF-6404] HTTPConduit performance improvements Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/1b7e0dfc Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/1b7e0dfc Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/1b7e0dfc Branch: refs/heads/3.0.x-fixes Commit: 1b7e0dfc9c2eb3249ec12624ef3aff473424265c Parents: f7d259d Author: Alessio Soldano <[email protected]> Authored: Fri May 15 10:29:24 2015 +0200 Committer: Alessio Soldano <[email protected]> Committed: Fri May 15 10:32:04 2015 +0200 ---------------------------------------------------------------------- .../http/asyncclient/AsyncHTTPConduit.java | 14 +++-- .../http/netty/client/NettyHttpConduit.java | 15 ++++-- .../org/apache/cxf/transport/http/Address.java | 54 ++++++++++++++++++- .../apache/cxf/transport/http/HTTPConduit.java | 56 ++++++++------------ .../http/URLConnectionHTTPConduit.java | 14 +++-- .../cxf/transport/http/HTTPConduitTest.java | 2 - .../http/HTTPConduitURLEasyMockTest.java | 2 +- 7 files changed, 107 insertions(+), 50 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/1b7e0dfc/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 6d9ff3d..f70dbb8 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 @@ -141,7 +141,8 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit { String uriString = uri.toString(); if (uriString.startsWith("hc://")) { try { - uri = new URI(uriString.substring(5)); + uriString = uriString.substring(5); + uri = new URI(uriString); addressChanged = true; } catch (URISyntaxException ex) { throw new MalformedURLException("unsupport uri: " + uriString); @@ -184,7 +185,7 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit { } if (!MessageUtils.isTrue(o)) { message.put(USE_ASYNC, Boolean.FALSE); - super.setupConnection(message, addressChanged ? new Address(uri) : address, csPolicy); + super.setupConnection(message, addressChanged ? new Address(uriString, uri) : address, csPolicy); return; } if (StringUtils.isEmpty(uri.getPath())) { @@ -834,8 +835,13 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit { inbuf = new SharedInputBuffer(bufSize, allocator); outbuf = new SharedOutputBuffer(bufSize, allocator); try { - this.url = new URI(newURL); - setupConnection(outMessage, new Address(this.url), csPolicy); + if (defaultAddress.getString().equals(newURL)) { + setupConnection(outMessage, defaultAddress, csPolicy); + } else { + Address address = new Address(newURL); + this.url = address.getURI(); + setupConnection(outMessage, address, csPolicy); + } entity = outMessage.get(CXFHttpRequest.class); basicEntity = (BasicHttpEntity)entity.getEntity(); entity.setOutputStream(this); http://git-wip-us.apache.org/repos/asf/cxf/blob/1b7e0dfc/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 c81b4d2..029d0d8 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 @@ -101,7 +101,8 @@ public class NettyHttpConduit extends URLConnectionHTTPConduit implements BusLif String uriString = uri.toString(); if (uriString.startsWith("netty://")) { try { - uri = new URI(uriString.substring(8)); + uriString = uriString.substring(8); + uri = new URI(uriString); addressChanged = true; } catch (URISyntaxException ex) { throw new MalformedURLException("unsupport uri: " + uriString); @@ -144,7 +145,7 @@ public class NettyHttpConduit extends URLConnectionHTTPConduit implements BusLif } if (!MessageUtils.isTrue(o)) { message.put(USE_ASYNC, Boolean.FALSE); - super.setupConnection(message, addressChanged ? new Address(uri) : address, csPolicy); + super.setupConnection(message, addressChanged ? new Address(uriString, uri) : address, csPolicy); return; } message.put(USE_ASYNC, Boolean.TRUE); @@ -544,8 +545,14 @@ public class NettyHttpConduit extends URLConnectionHTTPConduit implements BusLif } try { - this.url = new URI(newURL); - Address address = new Address(this.url); + Address address; + if (defaultAddress.getString().equals(newURL)) { + address = defaultAddress; + this.url = defaultAddress.getURI(); + } else { + this.url = new URI(newURL); + address = new Address(newURL, this.url); + } setupConnection(outMessage, address, csPolicy); entity = outMessage.get(NettyHttpClientRequest.class); //reset the buffers http://git-wip-us.apache.org/repos/asf/cxf/blob/1b7e0dfc/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 index 745b45f..b753251 100644 --- 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 @@ -19,22 +19,37 @@ package org.apache.cxf.transport.http; import java.net.MalformedURLException; +import java.net.Proxy; +import java.net.ProxySelector; import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; +import java.util.Iterator; import org.apache.cxf.common.injection.NoJSR250Annotations; /** * A convenient class for storing URI and URL representation of an address and avoid useless conversions. + * A proxy for the current address is also lazily resolved and stored; most of the times, that proxy can + * be used to prevent the HttpURLConnection from computing the proxy when the connection is opened. + * * The class is thread-safe. */ @NoJSR250Annotations public final class Address { + private final String str; private final URI uri; private volatile URL url; + private volatile Proxy defaultProxy; - public Address(URI uri) { + public Address(String str) throws URISyntaxException { + this.str = str; + this.uri = new URI(str); + } + + public Address(String str, URI uri) { + this.str = str; this.uri = uri; } @@ -52,4 +67,41 @@ public final class Address { public URI getURI() { return uri; } + + public String getString() { + return str; + } + + public Proxy getDefaultProxy() { + if (defaultProxy == null) { + synchronized (this) { + if (defaultProxy == null) { + defaultProxy = chooseProxy(uri); + } + } + } + return defaultProxy; + } + + private static Proxy chooseProxy(URI uri) { + ProxySelector sel = java.security.AccessController + .doPrivileged(new java.security.PrivilegedAction<ProxySelector>() { + @Override + public ProxySelector run() { + return ProxySelector.getDefault(); + } + }); + if (sel == null) { + return Proxy.NO_PROXY; + } + //detect usage of user-defined proxy and avoid optimizations in that case + if (!sel.getClass().getName().equals("sun.net.spi.DefaultProxySelector")) { + return null; + } + Iterator<Proxy> it = sel.select(uri).iterator(); + if (it.hasNext()) { + return it.next(); + } + return Proxy.NO_PROXY; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/1b7e0dfc/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 789b3e3..734e89c 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 @@ -208,8 +208,8 @@ public abstract class HTTPConduit * This field holds the "default" URI for this particular conduit, which * is created on demand. */ - protected URI defaultEndpointURI; - protected String defaultEndpointURIString; + protected Address defaultAddress; + protected boolean fromEndpointReferenceType; protected ProxyFactory proxyFactory; @@ -299,6 +299,11 @@ public abstract class HTTPConduit if (t != null) { fromEndpointReferenceType = true; } + try { + defaultAddress = createAddress(); + } catch (URISyntaxException use) { + throw new IOException(use); + } proxyFactory = new ProxyFactory(); cookies = new Cookies(); } @@ -676,12 +681,10 @@ public abstract class HTTPConduit String queryString = (String)message.get(Message.QUERY_STRING); if (result == null) { if (pathInfo == null && queryString == null) { - URI uri = getURI(); - message.put(Message.ENDPOINT_ADDRESS, defaultEndpointURIString); - return new Address(uri); + message.put(Message.ENDPOINT_ADDRESS, defaultAddress.getString()); + return defaultAddress; } - result = getURI().toString(); - message.put(Message.ENDPOINT_ADDRESS, result); + message.put(Message.ENDPOINT_ADDRESS, defaultAddress.getString()); } // REVISIT: is this really correct? @@ -691,10 +694,9 @@ public abstract class HTTPConduit if (queryString != null) { result = result + "?" + queryString; } - return new Address(new URI(result)); + return result.equals(defaultAddress.getString()) ? defaultAddress : new Address(result); } - /** * Close the conduit */ @@ -708,8 +710,8 @@ public abstract class HTTPConduit * @return the default target address */ public String getAddress() { - if (defaultEndpointURI != null) { - return defaultEndpointURIString; + if (defaultAddress != null) { + return defaultAddress.getString(); } else if (fromEndpointReferenceType) { return getTarget().getAddress().getValue(); } @@ -720,31 +722,19 @@ public abstract class HTTPConduit * @return the default target URL */ protected URI getURI() throws URISyntaxException { - return getURI(true); + return defaultAddress.getURI(); } - /** - * @param createOnDemand create URL on-demand if null - * @return the default target URL - * @throws URISyntaxException - */ - protected synchronized URI getURI(boolean createOnDemand) - throws URISyntaxException { - if (defaultEndpointURI == null && createOnDemand) { - if (fromEndpointReferenceType && getTarget().getAddress().getValue() != null) { - defaultEndpointURI = new URI(this.getTarget().getAddress().getValue()); - defaultEndpointURIString = defaultEndpointURI.toString(); - return defaultEndpointURI; - } - if (endpointInfo.getAddress() == null) { - throw new URISyntaxException("<null>", - "Invalid address. Endpoint address cannot be null.", - 0); - } - defaultEndpointURI = new URI(endpointInfo.getAddress()); - defaultEndpointURIString = defaultEndpointURI.toString(); + private Address createAddress() throws URISyntaxException { + if (fromEndpointReferenceType && getTarget().getAddress().getValue() != null) { + return new Address(this.getTarget().getAddress().getValue()); + } + if (endpointInfo.getAddress() == null) { + throw new URISyntaxException("<null>", + "Invalid address. Endpoint address cannot be null.", + 0); } - return defaultEndpointURI; + return new Address(endpointInfo.getAddress()); } /** http://git-wip-us.apache.org/repos/asf/cxf/blob/1b7e0dfc/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 6fdfe79..22fdcd3 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 @@ -75,9 +75,9 @@ public class URLConnectionHTTPConduit extends HTTPConduit { */ public void close() { super.close(); - if (defaultEndpointURI != null) { + if (defaultAddress != null) { try { - URLConnection connect = defaultEndpointURI.toURL().openConnection(); + URLConnection connect = defaultAddress.getURL().openConnection(); if (connect instanceof HttpURLConnection) { ((HttpURLConnection)connect).disconnect(); } @@ -99,7 +99,8 @@ public class URLConnectionHTTPConduit extends HTTPConduit { if (clientParameters == null) { clientParameters = tlsClientParameters; } - return connectionFactory.createConnection(clientParameters, proxy, url); + return connectionFactory.createConnection(clientParameters, + proxy != null ? proxy : address.getDefaultProxy(), url); } protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException { HttpURLConnection connection = createConnection(message, address, csPolicy); @@ -296,8 +297,11 @@ public class URLConnectionHTTPConduit extends HTTPConduit { HTTPClientPolicy cp = getClient(outMessage); Address address; try { - URI nurl = new URI(newURL); - address = new Address(nurl); + if (defaultAddress.getString().equals(newURL)) { + address = defaultAddress; + } else { + address = new Address(newURL); + } } catch (URISyntaxException e) { throw new IOException(e); } http://git-wip-us.apache.org/repos/asf/cxf/blob/1b7e0dfc/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java ---------------------------------------------------------------------- diff --git a/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java b/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java index acd9910..ee6f890 100644 --- a/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java +++ b/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java @@ -108,8 +108,6 @@ public class HTTPConduitTest extends Assert { assertEquals("unexpected address", conduit.getAddress(), "http://nowhere.com/bar/foo"); - assertNull("unexpected upfront URL", - conduit.getURI(false)); assertEquals("unexpected on-demand URL", conduit.getURI().getPath(), "/bar/foo"); http://git-wip-us.apache.org/repos/asf/cxf/blob/1b7e0dfc/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitURLEasyMockTest.java ---------------------------------------------------------------------- diff --git a/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitURLEasyMockTest.java b/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitURLEasyMockTest.java index aaac07e..c307159 100644 --- a/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitURLEasyMockTest.java +++ b/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitURLEasyMockTest.java @@ -313,7 +313,7 @@ public class HTTPConduitURLEasyMockTest extends Assert { if (send) { //proxy = control.createMock(Proxy.class); - proxy = null; + proxy = Proxy.NO_PROXY; connection = control.createMock(HttpURLConnection.class); connection.getURL();
