Skip to content

Commit

Permalink
+ Add GrizzlyAsyncHttpProviderConfig and TransportCustomizer. This a…
Browse files Browse the repository at this point in the history
…llows hand tuning of the Grizzly Transport implementation used by the AHC provider instance.

 + Add TransportCustomizer - enables hand tuning of Transport.
 + Add basic javadocs.
  • Loading branch information
rlubke committed Sep 28, 2011
1 parent efe60cb commit b8f3624
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
import com.ning.http.util.AsyncHttpProviderUtils;
import com.ning.http.util.AuthenticatorUtils;
import com.ning.http.util.ProxyUtils;

import com.ning.http.util.SslUtils;

import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.CompletionHandler;
import org.glassfish.grizzly.Connection;
Expand Down Expand Up @@ -111,10 +111,13 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import static com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProviderConfig.Property.TRANSPORT_CUSTOMIZER;

/**
* TODO: Documentation
* A Grizzly 2.0-based implementation of {@link AsyncHttpProvider}.
*
* @author The Grizzly Team
* @since 1.7.0
*/
public class GrizzlyAsyncHttpProvider implements AsyncHttpProvider {

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

this.clientConfig = clientConfig;
final TCPNIOTransportBuilder builder = TCPNIOTransportBuilder.newInstance();
builder.setIOStrategy(SameThreadIOStrategy.getInstance());
clientTransport = builder.build();
initializeTransport(clientConfig);
connectionManager = new ConnectionManager(this, clientTransport);
Expand Down Expand Up @@ -276,6 +278,20 @@ protected <T> ListenableFuture<T> execute(final Connection c,


protected void initializeTransport(AsyncHttpClientConfig clientConfig) {

GrizzlyAsyncHttpProviderConfig providerConfig =
(GrizzlyAsyncHttpProviderConfig) clientConfig.getAsyncHttpProviderConfig();
if (providerConfig != null) {
final TransportCustomizer customizer = (TransportCustomizer)
providerConfig.getProperty(TRANSPORT_CUSTOMIZER);
if (customizer != null) {
customizer.customize(clientTransport);
} else {
clientTransport.setIOStrategy(SameThreadIOStrategy.getInstance());
}
} else {
clientTransport.setIOStrategy(SameThreadIOStrategy.getInstance());
}

final FilterChainBuilder fcb = FilterChainBuilder.stateless();
fcb.add(new AsyncHttpClientTransportFilter());
Expand Down Expand Up @@ -1240,7 +1256,7 @@ public boolean handleStatus(final HttpResponsePacket responsePacket,
final FilterChainContext ctx) {

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

}

/*
Connection obtainTrackedConnection(final Request request,
final GrizzlyResponseFuture requestFuture)
throws IOException, ExecutionException, InterruptedException {
final String url = request.getUrl();
Connection c = pool.poll(AsyncHttpProviderUtils.getBaseUrl(url));
if (c == null) {
if (!connectionMonitor.acquire()) {
throw new IOException("Max connections exceeded");
}
c = obtainConnection0(url, request, requestFuture);
c.addCloseListener(connectionMonitor);
} else {
provider.touchConnection(c, request);
}
return c;
}
*/

Connection obtainConnection(final Request request,
final GrizzlyResponseFuture requestFuture)
throws IOException, ExecutionException, InterruptedException, TimeoutException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.ning.http.client.providers.grizzly;

import com.ning.http.client.AsyncHttpProviderConfig;
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
* {@link AsyncHttpProviderConfig} implementation that allows customization
* of the Grizzly runtime outside of the scope of what the
* {@link com.ning.http.client.AsyncHttpClientConfig} offers.
*
* @see Property
*
* @author The Grizzly Team
* @since 1.7.0
*/
public class GrizzlyAsyncHttpProviderConfig implements AsyncHttpProviderConfig<GrizzlyAsyncHttpProviderConfig.Property,Object> {

/**
* Grizzly-specific customization properties. Each property describes
* what it's used for, what the default value is (if any), and what
* the expected type the value of the property should be.
*/
public static enum Property {

/**
* If this property is specified with a custom {@link TransportCustomizer}
* instance, the {@link TCPNIOTransport} instance that is created by
* {@link GrizzlyAsyncHttpProvider} will be passed to the customizer
* bypassing all default configuration of the transport typically performed
* by the provider. The type of the value associated with this property
* must be <code>TransportCustomizer.class</code>.
*
* @see TransportCustomizer
*/
TRANSPORT_CUSTOMIZER(TransportCustomizer.class);


final Object defaultValue;
final Class<?> type;

private Property(final Class<?> type, final Object defaultValue) {
this.type = type;
this.defaultValue = defaultValue;
}

private Property(final Class<?> type) {
this(type, null);
}

boolean hasDefaultValue() {
return (defaultValue != null);
}


} // END PROPERTY

private final Map<Property,Object> attributes = new HashMap<Property,Object>();

// ------------------------------------ Methods from AsyncHttpProviderConfig

/**
* {@inheritDoc}
*
* @throws IllegalArgumentException if the type of the specified value
* does not match the expected type of the specified {@link Property}.
*/
@Override
public AsyncHttpProviderConfig addProperty(Property name, Object value) {
if (name == null) {
return this;
}
if (value == null) {
if (name.hasDefaultValue()) {
value = name.defaultValue;
} else {
return this;
}
} else {
if (!name.type.isAssignableFrom(value.getClass())) {
throw new IllegalArgumentException(
String.format(
"The value of property [%s] must be of type [%s]. Type of value provided: [%s].",
name.name(),
name.type.getName(),
value.getClass().getName()));
}
}
attributes.put(name, value);
return this;
}

/**
* {@inheritDoc}
*/
@Override
public Object getProperty(Property name) {
Object ret = attributes.get(name);
if (ret == null) {
if (name.hasDefaultValue()) {
ret = name.defaultValue;
}
}
return ret;
}

/**
* {@inheritDoc}
*/
@Override
public Object removeProperty(Property name) {
if (name == null) {
return null;
}
return attributes.remove(name);
}

/**
* {@inheritDoc}
*/
@Override
public Set<Map.Entry<Property,Object>> propertiesSet() {
return attributes.entrySet();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import com.ning.http.client.AsyncHttpClientConfig;
import com.ning.http.client.ConnectionsPool;

import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.Grizzly;
import org.glassfish.grizzly.attributes.Attribute;
Expand All @@ -35,7 +36,12 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;


/**
* {@link ConnectionsPool} implementation.
*
* @author The Grizzly Team
* @since 1.7.0
*/
public class GrizzlyConnectionsPool implements ConnectionsPool<String,Connection> {

private final static Logger LOG = LoggerFactory.getLogger(GrizzlyConnectionsPool.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.ning.http.client.HttpResponseStatus;
import com.ning.http.client.Response;
import com.ning.http.util.AsyncHttpProviderUtils;

import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.http.CookiesBuilder;
import org.glassfish.grizzly.http.util.Charsets;
Expand All @@ -41,7 +42,8 @@
* {@link com.ning.http.client.HttpResponseBodyPart} implementation using the Grizzly 2.0 HTTP client
* codec.
*
* @author Grizzly Team
* @author The Grizzly Team
* @since 1.7.0
*/
public class GrizzlyResponse implements Response {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import com.ning.http.client.AsyncHttpProvider;
import com.ning.http.client.HttpResponseBodyPart;

import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.http.HttpContent;
Expand All @@ -32,6 +33,7 @@
* codec.
*
* @author The Grizzly Team
* @since 1.7.0
*/
public class GrizzlyResponseBodyPart extends HttpResponseBodyPart {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.ning.http.client.AsyncHandler;
import com.ning.http.client.Request;
import com.ning.http.client.listenable.AbstractListenableFuture;

import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.impl.FutureImpl;

Expand All @@ -31,7 +32,8 @@
* {@link AbstractListenableFuture} implementation adaptation of Grizzly's
* {@link FutureImpl}.
*
* @author Grizzly Team
* @author The Grizzly Team
* @since 1.7.0
*/
public class GrizzlyResponseFuture<V> extends AbstractListenableFuture<V> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.ning.http.client.AsyncHttpProvider;
import com.ning.http.client.FluentCaseInsensitiveStringsMap;
import com.ning.http.client.HttpResponseHeaders;

import org.glassfish.grizzly.http.HttpResponsePacket;
import org.glassfish.grizzly.http.util.MimeHeaders;

Expand All @@ -26,7 +27,8 @@
* {@link HttpResponseHeaders} implementation using the Grizzly 2.0 HTTP client
* codec.
*
* @author Grizzly Team
* @author The Grizzly Team
* @since 1.7.0
*/
public class GrizzlyResponseHeaders extends HttpResponseHeaders {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import com.ning.http.client.AsyncHttpProvider;
import com.ning.http.client.HttpResponseStatus;

import org.glassfish.grizzly.http.HttpResponsePacket;

import java.net.URI;
Expand All @@ -23,7 +24,8 @@
* {@link HttpResponseStatus} implementation using the Grizzly 2.0 HTTP client
* codec.
*
* @author Grizzly Team
* @author The Grizzly Team
* @since 1.7.0
*/
public class GrizzlyResponseStatus extends HttpResponseStatus {

Expand Down
Loading

0 comments on commit b8f3624

Please sign in to comment.