Skip to content

Commit b8f3624

Browse files
committed
+ Add GrizzlyAsyncHttpProviderConfig and TransportCustomizer. This allows hand tuning of the Grizzly Transport implementation used by the AHC provider instance.
+ Add TransportCustomizer - enables hand tuning of Transport. + Add basic javadocs.
1 parent efe60cb commit b8f3624

9 files changed

+271
-30
lines changed

src/main/java/com/ning/http/client/providers/grizzly/GrizzlyAsyncHttpProvider.java

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
import com.ning.http.util.AsyncHttpProviderUtils;
4242
import com.ning.http.util.AuthenticatorUtils;
4343
import com.ning.http.util.ProxyUtils;
44-
4544
import com.ning.http.util.SslUtils;
45+
4646
import org.glassfish.grizzly.Buffer;
4747
import org.glassfish.grizzly.CompletionHandler;
4848
import org.glassfish.grizzly.Connection;
@@ -111,10 +111,13 @@
111111
import java.util.concurrent.atomic.AtomicInteger;
112112
import java.util.concurrent.atomic.AtomicLong;
113113

114+
import static com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProviderConfig.Property.TRANSPORT_CUSTOMIZER;
115+
114116
/**
115-
* TODO: Documentation
117+
* A Grizzly 2.0-based implementation of {@link AsyncHttpProvider}.
116118
*
117119
* @author The Grizzly Team
120+
* @since 1.7.0
118121
*/
119122
public class GrizzlyAsyncHttpProvider implements AsyncHttpProvider {
120123

@@ -141,7 +144,6 @@ public GrizzlyAsyncHttpProvider(final AsyncHttpClientConfig clientConfig) {
141144

142145
this.clientConfig = clientConfig;
143146
final TCPNIOTransportBuilder builder = TCPNIOTransportBuilder.newInstance();
144-
builder.setIOStrategy(SameThreadIOStrategy.getInstance());
145147
clientTransport = builder.build();
146148
initializeTransport(clientConfig);
147149
connectionManager = new ConnectionManager(this, clientTransport);
@@ -276,6 +278,20 @@ protected <T> ListenableFuture<T> execute(final Connection c,
276278

277279

278280
protected void initializeTransport(AsyncHttpClientConfig clientConfig) {
281+
282+
GrizzlyAsyncHttpProviderConfig providerConfig =
283+
(GrizzlyAsyncHttpProviderConfig) clientConfig.getAsyncHttpProviderConfig();
284+
if (providerConfig != null) {
285+
final TransportCustomizer customizer = (TransportCustomizer)
286+
providerConfig.getProperty(TRANSPORT_CUSTOMIZER);
287+
if (customizer != null) {
288+
customizer.customize(clientTransport);
289+
} else {
290+
clientTransport.setIOStrategy(SameThreadIOStrategy.getInstance());
291+
}
292+
} else {
293+
clientTransport.setIOStrategy(SameThreadIOStrategy.getInstance());
294+
}
279295

280296
final FilterChainBuilder fcb = FilterChainBuilder.stateless();
281297
fcb.add(new AsyncHttpClientTransportFilter());
@@ -1240,7 +1256,7 @@ public boolean handleStatus(final HttpResponsePacket responsePacket,
12401256
final FilterChainContext ctx) {
12411257

12421258
responsePacket.setSkipRemainder(true); // ignore the remainder of the response
1243-
final String auth = responsePacket.getHeader("WWW-Authenticate");
1259+
final String auth = responsePacket.getHeader(Header.WWWAuthenticate);
12441260
if (auth == null) {
12451261
throw new IllegalStateException("401 response received, but no WWW-Authenticate header was present");
12461262
}
@@ -1995,27 +2011,6 @@ void doAsyncTrackedConnection(final Request request,
19952011

19962012
}
19972013

1998-
/*
1999-
Connection obtainTrackedConnection(final Request request,
2000-
final GrizzlyResponseFuture requestFuture)
2001-
throws IOException, ExecutionException, InterruptedException {
2002-
2003-
final String url = request.getUrl();
2004-
Connection c = pool.poll(AsyncHttpProviderUtils.getBaseUrl(url));
2005-
if (c == null) {
2006-
if (!connectionMonitor.acquire()) {
2007-
throw new IOException("Max connections exceeded");
2008-
}
2009-
c = obtainConnection0(url, request, requestFuture);
2010-
c.addCloseListener(connectionMonitor);
2011-
} else {
2012-
provider.touchConnection(c, request);
2013-
}
2014-
return c;
2015-
2016-
}
2017-
*/
2018-
20192014
Connection obtainConnection(final Request request,
20202015
final GrizzlyResponseFuture requestFuture)
20212016
throws IOException, ExecutionException, InterruptedException, TimeoutException {
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3+
*
4+
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
5+
*
6+
* The contents of this file are subject to the terms of either the GNU
7+
* General Public License Version 2 only ("GPL") or the Common Development
8+
* and Distribution License("CDDL") (collectively, the "License"). You
9+
* may not use this file except in compliance with the License. You can
10+
* obtain a copy of the License at
11+
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
12+
* or packager/legal/LICENSE.txt. See the License for the specific
13+
* language governing permissions and limitations under the License.
14+
*
15+
* When distributing the software, include this License Header Notice in each
16+
* file and include the License file at packager/legal/LICENSE.txt.
17+
*
18+
* GPL Classpath Exception:
19+
* Oracle designates this particular file as subject to the "Classpath"
20+
* exception as provided by Oracle in the GPL Version 2 section of the License
21+
* file that accompanied this code.
22+
*
23+
* Modifications:
24+
* If applicable, add the following below the License Header, with the fields
25+
* enclosed by brackets [] replaced by your own identifying information:
26+
* "Portions Copyright [year] [name of copyright owner]"
27+
*
28+
* Contributor(s):
29+
* If you wish your version of this file to be governed by only the CDDL or
30+
* only the GPL Version 2, indicate your decision by adding "[Contributor]
31+
* elects to include this software in this distribution under the [CDDL or GPL
32+
* Version 2] license." If you don't indicate a single choice of license, a
33+
* recipient has the option to distribute your version of this file under
34+
* either the CDDL, the GPL Version 2 or to extend the choice of license to
35+
* its licensees as provided above. However, if you add GPL Version 2 code
36+
* and therefore, elected the GPL Version 2 license, then the option applies
37+
* only if the new code is made subject to such option by the copyright
38+
* holder.
39+
*/
40+
package com.ning.http.client.providers.grizzly;
41+
42+
import com.ning.http.client.AsyncHttpProviderConfig;
43+
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
44+
45+
import java.util.HashMap;
46+
import java.util.Map;
47+
import java.util.Set;
48+
49+
/**
50+
* {@link AsyncHttpProviderConfig} implementation that allows customization
51+
* of the Grizzly runtime outside of the scope of what the
52+
* {@link com.ning.http.client.AsyncHttpClientConfig} offers.
53+
*
54+
* @see Property
55+
*
56+
* @author The Grizzly Team
57+
* @since 1.7.0
58+
*/
59+
public class GrizzlyAsyncHttpProviderConfig implements AsyncHttpProviderConfig<GrizzlyAsyncHttpProviderConfig.Property,Object> {
60+
61+
/**
62+
* Grizzly-specific customization properties. Each property describes
63+
* what it's used for, what the default value is (if any), and what
64+
* the expected type the value of the property should be.
65+
*/
66+
public static enum Property {
67+
68+
/**
69+
* If this property is specified with a custom {@link TransportCustomizer}
70+
* instance, the {@link TCPNIOTransport} instance that is created by
71+
* {@link GrizzlyAsyncHttpProvider} will be passed to the customizer
72+
* bypassing all default configuration of the transport typically performed
73+
* by the provider. The type of the value associated with this property
74+
* must be <code>TransportCustomizer.class</code>.
75+
*
76+
* @see TransportCustomizer
77+
*/
78+
TRANSPORT_CUSTOMIZER(TransportCustomizer.class);
79+
80+
81+
final Object defaultValue;
82+
final Class<?> type;
83+
84+
private Property(final Class<?> type, final Object defaultValue) {
85+
this.type = type;
86+
this.defaultValue = defaultValue;
87+
}
88+
89+
private Property(final Class<?> type) {
90+
this(type, null);
91+
}
92+
93+
boolean hasDefaultValue() {
94+
return (defaultValue != null);
95+
}
96+
97+
98+
} // END PROPERTY
99+
100+
private final Map<Property,Object> attributes = new HashMap<Property,Object>();
101+
102+
// ------------------------------------ Methods from AsyncHttpProviderConfig
103+
104+
/**
105+
* {@inheritDoc}
106+
*
107+
* @throws IllegalArgumentException if the type of the specified value
108+
* does not match the expected type of the specified {@link Property}.
109+
*/
110+
@Override
111+
public AsyncHttpProviderConfig addProperty(Property name, Object value) {
112+
if (name == null) {
113+
return this;
114+
}
115+
if (value == null) {
116+
if (name.hasDefaultValue()) {
117+
value = name.defaultValue;
118+
} else {
119+
return this;
120+
}
121+
} else {
122+
if (!name.type.isAssignableFrom(value.getClass())) {
123+
throw new IllegalArgumentException(
124+
String.format(
125+
"The value of property [%s] must be of type [%s]. Type of value provided: [%s].",
126+
name.name(),
127+
name.type.getName(),
128+
value.getClass().getName()));
129+
}
130+
}
131+
attributes.put(name, value);
132+
return this;
133+
}
134+
135+
/**
136+
* {@inheritDoc}
137+
*/
138+
@Override
139+
public Object getProperty(Property name) {
140+
Object ret = attributes.get(name);
141+
if (ret == null) {
142+
if (name.hasDefaultValue()) {
143+
ret = name.defaultValue;
144+
}
145+
}
146+
return ret;
147+
}
148+
149+
/**
150+
* {@inheritDoc}
151+
*/
152+
@Override
153+
public Object removeProperty(Property name) {
154+
if (name == null) {
155+
return null;
156+
}
157+
return attributes.remove(name);
158+
}
159+
160+
/**
161+
* {@inheritDoc}
162+
*/
163+
@Override
164+
public Set<Map.Entry<Property,Object>> propertiesSet() {
165+
return attributes.entrySet();
166+
}
167+
168+
}

src/main/java/com/ning/http/client/providers/grizzly/GrizzlyConnectionsPool.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import com.ning.http.client.AsyncHttpClientConfig;
1717
import com.ning.http.client.ConnectionsPool;
18+
1819
import org.glassfish.grizzly.Connection;
1920
import org.glassfish.grizzly.Grizzly;
2021
import org.glassfish.grizzly.attributes.Attribute;
@@ -35,7 +36,12 @@
3536
import java.util.concurrent.atomic.AtomicBoolean;
3637
import java.util.concurrent.atomic.AtomicInteger;
3738

38-
39+
/**
40+
* {@link ConnectionsPool} implementation.
41+
*
42+
* @author The Grizzly Team
43+
* @since 1.7.0
44+
*/
3945
public class GrizzlyConnectionsPool implements ConnectionsPool<String,Connection> {
4046

4147
private final static Logger LOG = LoggerFactory.getLogger(GrizzlyConnectionsPool.class);

src/main/java/com/ning/http/client/providers/grizzly/GrizzlyResponse.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.ning.http.client.HttpResponseStatus;
2121
import com.ning.http.client.Response;
2222
import com.ning.http.util.AsyncHttpProviderUtils;
23+
2324
import org.glassfish.grizzly.Buffer;
2425
import org.glassfish.grizzly.http.CookiesBuilder;
2526
import org.glassfish.grizzly.http.util.Charsets;
@@ -41,7 +42,8 @@
4142
* {@link com.ning.http.client.HttpResponseBodyPart} implementation using the Grizzly 2.0 HTTP client
4243
* codec.
4344
*
44-
* @author Grizzly Team
45+
* @author The Grizzly Team
46+
* @since 1.7.0
4547
*/
4648
public class GrizzlyResponse implements Response {
4749

src/main/java/com/ning/http/client/providers/grizzly/GrizzlyResponseBodyPart.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import com.ning.http.client.AsyncHttpProvider;
1717
import com.ning.http.client.HttpResponseBodyPart;
18+
1819
import org.glassfish.grizzly.Buffer;
1920
import org.glassfish.grizzly.Connection;
2021
import org.glassfish.grizzly.http.HttpContent;
@@ -32,6 +33,7 @@
3233
* codec.
3334
*
3435
* @author The Grizzly Team
36+
* @since 1.7.0
3537
*/
3638
public class GrizzlyResponseBodyPart extends HttpResponseBodyPart {
3739

src/main/java/com/ning/http/client/providers/grizzly/GrizzlyResponseFuture.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.ning.http.client.AsyncHandler;
1717
import com.ning.http.client.Request;
1818
import com.ning.http.client.listenable.AbstractListenableFuture;
19+
1920
import org.glassfish.grizzly.Connection;
2021
import org.glassfish.grizzly.impl.FutureImpl;
2122

@@ -31,7 +32,8 @@
3132
* {@link AbstractListenableFuture} implementation adaptation of Grizzly's
3233
* {@link FutureImpl}.
3334
*
34-
* @author Grizzly Team
35+
* @author The Grizzly Team
36+
* @since 1.7.0
3537
*/
3638
public class GrizzlyResponseFuture<V> extends AbstractListenableFuture<V> {
3739

src/main/java/com/ning/http/client/providers/grizzly/GrizzlyResponseHeaders.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.ning.http.client.AsyncHttpProvider;
1717
import com.ning.http.client.FluentCaseInsensitiveStringsMap;
1818
import com.ning.http.client.HttpResponseHeaders;
19+
1920
import org.glassfish.grizzly.http.HttpResponsePacket;
2021
import org.glassfish.grizzly.http.util.MimeHeaders;
2122

@@ -26,7 +27,8 @@
2627
* {@link HttpResponseHeaders} implementation using the Grizzly 2.0 HTTP client
2728
* codec.
2829
*
29-
* @author Grizzly Team
30+
* @author The Grizzly Team
31+
* @since 1.7.0
3032
*/
3133
public class GrizzlyResponseHeaders extends HttpResponseHeaders {
3234

src/main/java/com/ning/http/client/providers/grizzly/GrizzlyResponseStatus.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import com.ning.http.client.AsyncHttpProvider;
1717
import com.ning.http.client.HttpResponseStatus;
18+
1819
import org.glassfish.grizzly.http.HttpResponsePacket;
1920

2021
import java.net.URI;
@@ -23,7 +24,8 @@
2324
* {@link HttpResponseStatus} implementation using the Grizzly 2.0 HTTP client
2425
* codec.
2526
*
26-
* @author Grizzly Team
27+
* @author The Grizzly Team
28+
* @since 1.7.0
2729
*/
2830
public class GrizzlyResponseStatus extends HttpResponseStatus {
2931

0 commit comments

Comments
 (0)