Skip to content

Commit 44ef934

Browse files
committed
Merge pull request AsyncHttpClient#25 from rlubke/master
Adding Grizzly specific provider configuration. Test updates to support these changes.
2 parents f973ff2 + f830861 commit 44ef934

15 files changed

+287
-43
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: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright (c) 2011 Sonatype, Inc. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing,
9+
* software distributed under the Apache License Version 2.0 is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
14+
package com.ning.http.client.providers.grizzly;
15+
16+
import com.ning.http.client.AsyncHttpProviderConfig;
17+
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
18+
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
import java.util.Set;
22+
23+
/**
24+
* {@link AsyncHttpProviderConfig} implementation that allows customization
25+
* of the Grizzly runtime outside of the scope of what the
26+
* {@link com.ning.http.client.AsyncHttpClientConfig} offers.
27+
*
28+
* @see Property
29+
*
30+
* @author The Grizzly Team
31+
* @since 1.7.0
32+
*/
33+
public class GrizzlyAsyncHttpProviderConfig implements AsyncHttpProviderConfig<GrizzlyAsyncHttpProviderConfig.Property,Object> {
34+
35+
/**
36+
* Grizzly-specific customization properties. Each property describes
37+
* what it's used for, what the default value is (if any), and what
38+
* the expected type the value of the property should be.
39+
*/
40+
public static enum Property {
41+
42+
/**
43+
* If this property is specified with a custom {@link TransportCustomizer}
44+
* instance, the {@link TCPNIOTransport} instance that is created by
45+
* {@link GrizzlyAsyncHttpProvider} will be passed to the customizer
46+
* bypassing all default configuration of the transport typically performed
47+
* by the provider. The type of the value associated with this property
48+
* must be <code>TransportCustomizer.class</code>.
49+
*
50+
* @see TransportCustomizer
51+
*/
52+
TRANSPORT_CUSTOMIZER(TransportCustomizer.class);
53+
54+
55+
final Object defaultValue;
56+
final Class<?> type;
57+
58+
private Property(final Class<?> type, final Object defaultValue) {
59+
this.type = type;
60+
this.defaultValue = defaultValue;
61+
}
62+
63+
private Property(final Class<?> type) {
64+
this(type, null);
65+
}
66+
67+
boolean hasDefaultValue() {
68+
return (defaultValue != null);
69+
}
70+
71+
72+
} // END PROPERTY
73+
74+
private final Map<Property,Object> attributes = new HashMap<Property,Object>();
75+
76+
// ------------------------------------ Methods from AsyncHttpProviderConfig
77+
78+
/**
79+
* {@inheritDoc}
80+
*
81+
* @throws IllegalArgumentException if the type of the specified value
82+
* does not match the expected type of the specified {@link Property}.
83+
*/
84+
@Override
85+
public AsyncHttpProviderConfig addProperty(Property name, Object value) {
86+
if (name == null) {
87+
return this;
88+
}
89+
if (value == null) {
90+
if (name.hasDefaultValue()) {
91+
value = name.defaultValue;
92+
} else {
93+
return this;
94+
}
95+
} else {
96+
if (!name.type.isAssignableFrom(value.getClass())) {
97+
throw new IllegalArgumentException(
98+
String.format(
99+
"The value of property [%s] must be of type [%s]. Type of value provided: [%s].",
100+
name.name(),
101+
name.type.getName(),
102+
value.getClass().getName()));
103+
}
104+
}
105+
attributes.put(name, value);
106+
return this;
107+
}
108+
109+
/**
110+
* {@inheritDoc}
111+
*/
112+
@Override
113+
public Object getProperty(Property name) {
114+
Object ret = attributes.get(name);
115+
if (ret == null) {
116+
if (name.hasDefaultValue()) {
117+
ret = name.defaultValue;
118+
}
119+
}
120+
return ret;
121+
}
122+
123+
/**
124+
* {@inheritDoc}
125+
*/
126+
@Override
127+
public Object removeProperty(Property name) {
128+
if (name == null) {
129+
return null;
130+
}
131+
return attributes.remove(name);
132+
}
133+
134+
/**
135+
* {@inheritDoc}
136+
*/
137+
@Override
138+
public Set<Map.Entry<Property,Object>> propertiesSet() {
139+
return attributes.entrySet();
140+
}
141+
142+
}

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2011 Sonatype, Inc. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing,
9+
* software distributed under the Apache License Version 2.0 is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
14+
package com.ning.http.client.providers.grizzly;
15+
16+
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
17+
18+
/**
19+
* This class may be provided as an option to the {@link GrizzlyAsyncHttpProviderConfig}
20+
* and allows low-level customization of the {@link TCPNIOTransport} beyond the
21+
* defaults typically used.
22+
*
23+
* @author The Grizzly Team
24+
* @since 1.7.0
25+
*/
26+
public interface TransportCustomizer {
27+
28+
/**
29+
* Customizes the configuration of the provided {@link TCPNIOTransport}
30+
* instance.
31+
*
32+
* @param transport the {@link TCPNIOTransport} instance for this client.
33+
*/
34+
void customize(final TCPNIOTransport transport);
35+
36+
}

0 commit comments

Comments
 (0)