Home > Async Http client > What’s new with AsyncHttpClient 1.4.0

What’s new with AsyncHttpClient 1.4.0

AsyncHttpClient 1.4.0 is has just been released and contains many new features , bugs fixes and significant performance improvement.

Request/ResponseFilter

AsyncHttpClient 1.4.0 supports new Filter API that can be used for pre-processing Request and post-processing Response. The new RequestFilter can be used to decorate the original Request and AsyncHandler instance As an example, below is a RequestFilter which throttle requests:


public class ThrottleRequestFilter implements RequestFilter {
    private final int maxConnections;
    private final Semaphore available;
    private final int maxWait;

    public ThrottleRequestFilter(int maxConnections) {
        this.maxConnections = maxConnections;
        this.maxWait = Integer.MAX_VALUE;
        available = new Semaphore(maxConnections, true);
    }

    public ThrottleRequestFilter(int maxConnections, int maxWait) {
        this.maxConnections = maxConnections;
        this.maxWait = maxWait;
        available = new Semaphore(maxConnections, true);
    }

    public FilterContext filter(FilterContext ctx) throws FilterException {

        try {
            if (!available.tryAcquire(maxWait, TimeUnit.MILLISECONDS)) {
                throw new FilterException(
                    String.format("No slot available for Request %s "
                            "with AsyncHandler %s",
                            ctx.getRequest(), ctx.getAsyncHandler()));
            };
        } catch (InterruptedException e) {
            throw new FilterException(
                    String.format("Interrupted Request %s" +
                         "with AsyncHandler %s",
                            ctx.getRequest(), ctx.getAsyncHandler()));
        }

        return new FilterContext(
             new AsyncHandlerWrapper(ctx.getAsyncHandler()), ctx.getRequest());
    }

    private class AsyncHandlerWrapper implements AsyncHandler {

        private final AsyncHandler asyncHandler;

        public AsyncHandlerWrapper(AsyncHandler asyncHandler) {
            this.asyncHandler = asyncHandler;
        }

        public void onThrowable(Throwable t) {
            asyncHandler.onThrowable(t);
        }

        public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart)
                throws Exception {
            return asyncHandler.onBodyPartReceived(bodyPart);
        }

        public STATE onStatusReceived(HttpResponseStatus responseStatus)
              throws Exception {
            return asyncHandler.onStatusReceived(responseStatus);
        }

        public STATE onHeadersReceived(HttpResponseHeaders headers)
              throws Exception {
            return asyncHandler.onHeadersReceived(headers);
        }

        public T onCompleted() throws Exception {
            available.release();
            return asyncHandler.onCompleted();
        }
    }

To add RequestFilter, all you need to do is to configure it on the AsyncHttpClientConfig:


        AsyncHttpClientConfig.Builder b =
                 new AsyncHttpClientConfig.Builder();
        b.addRequestFilter(new ThrottleRequestFilter(100));

        AsyncHttpClient c = new AsyncHttpClient(b.build());

You can also intercept and decorate the response before your AsyncHandler gets invoked, and also before the authorization, authentication or redirects get handled by the library. Below is a simple example of how a challenge for authorization can be handled by a ResponseFilter instead of letting the library doing it:


AsyncHttpClientConfig.Builder b = new AsyncHttpClientConfig.Builder();
final AtomicBoolean replay = new AtomicBoolean(true);

b.addResponseFilter(new ResponseFilter(){

   public FilterContext filter(FilterContext ctx) throws FilterException {

     if (ctx.getResponseStatus() != null &&
         ctx.getResponseStatus().getStatusCode() == 401
           && replay.getAndSet(false)) {

             Request request =
                   new RequestBuilder(ctx.getRequest())
                        .addHeader("Authorization",
                                           "Basic XAEKDYTHS==").build();
            return new FilterContext(ctx.getAsyncHandler(), request, true);
     }
     return ctx;
}});

TransferListener

A new TransferListener API has been added in order to get progress status of downloading or uploading file. AsyncHttpClient always supported that scenario using the AsyncCompletionHandler, but the new API just make it simpler:


        AsyncHttpClient c = new AsyncHttpClient();
        TransferCompletionHandler tl = new TransferCompletionHandler();
        tl.addTransferListener(new TransferListener() {

            public void onRequestHeadersSent(
                FluentCaseInsensitiveStringsMap headers) {
            }

            public void onResponseHeadersReceived(
                FluentCaseInsensitiveStringsMap headers) {
            }

            public void onBytesReceived(ByteBuffer buffer) {
            }

            public void onBytesSent(ByteBuffer buffer) {
            }

            public void onRequestResponseCompleted() {
            }

            public void onThrowable(Throwable t) {
            }
        });

         Response response = c.preparePut(getTargetUrl())
                              .setBody(largeFile)
                              .execute(tl).get();

Apache HttpClient Support

The Apache Http Client Library is now supported. If you can’t use Netty (which is still the recommended provider), all you need to do is:

   AsyncHttpClient c = new AsyncHttpClient(new ApacheAsyncHttpProvider());

Per Provider Configuration

It is now possible to configure AsyncHttpProvider with their respective configuration. For Netty, you can do:


AsyncHttpClientProviderConfig c = new NettyAsyncHttpClientProviderConfig();
c.addProperty(NettyAsyncHttpClientProviderConfig.USE_BLOCKING_IO,"true");

AsyncHttpClientConfig.Builder config = new AsyncHttpClientConfig.Builder();
builder.setAsyncHttpClientProviderConfig(c);

AsyncHttpClient client = new AsyncHttpClient(config.build());

Bug fixes and Performance Improvements

A lot of bugs and improvements are listed here. We did improve support for http to https redirection, realm/proxy authentication support, NTLM support, OAuth support etc.  On the performance side, the library has been heavily tested and we are tracking performance improvement/regression using that simple load application. So far the Netty provider gives excellent results comparing to other Http Client library.

For any questions you can use our Google Group, on irc.freenode.net #asynchttpclient or use Twitter to reach me! You can checkout the code on Github, download the jars from Maven Central or use Maven:

<dependency>
    <groupId>com.ning</groupId>
    <artifactId>async-http-client</artifactId>
    <version>1.4.0</version>
</dependency>

About these ads
Categories: Async Http client
  1. November 25, 2010 at 4:02 pm | #1

    Hello,
    I don’t know how to contact you, so I try it this way. In the past I created a ReSTful web application which works great. But I now I got a requirement to support async HTTP. There I would like use your framework.
    I removed my jersey libs/dependencies from my project and added the atmosphere-jersey dependency.
    In addition I changed my config (web.xml) this way:

    Mobile Server
    org.atmosphere.cpr.AtmosphereServlet

    com.sun.jersey.config.property.packages
    de.evonik.rest

    org.atmosphere.core.servlet-mapping
    /services

    com.sun.jersey.spi.container.ContainerRequestFilters
    com.sun.jersey.api.container.filter.PostReplaceFilter;
    com.sun.jersey.api.container.filter.LoggingFilter;

    com.sun.jersey.config.property.MediaTypeMappings
    xml : application/xml,
    json : application/json,
    img : image/*,
    html : text/html

    com.sun.jersey.config.feature.logging.DisableEntitylogging
    false

    com.sun.jersey.config.feature.ImplicitViewables
    true

    Mobile Server
    /services/*

    But if I try to use my jersey application without any Atmosphere stuff (like these resume and broadcast exception) I get the following Exception:

    INFO: Initiating Jersey application, version ‘Jersey: 1.5-ea01 10/08/2010 10:54 AM’
    25.11.2010 16:42:19 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
    INFO: Adding the following classes declared in META-INF/services/jersey-server-components to the resource configuration:
    class org.atmosphere.jersey.BroadcasterInjector
    class org.atmosphere.jersey.AtmosphereProviders$BroadcasterProvider
    class org.atmosphere.jersey.BroadcasterFactoryInjector
    class org.atmosphere.jersey.AtmosphereResourceInjector
    class org.atmosphere.jersey.AtmosphereResourceConfigurator
    25.11.2010 16:42:19 org.atmosphere.cpr.AtmosphereServlet init
    SCHWERWIEGEND:
    java.lang.NullPointerException
    at org.atmosphere.jersey.AtmosphereFilter.create(AtmosphereFilter.java:541)
    at com.sun.jersey.server.impl.container.filter.FilterFactory.getResourceFilters(FilterFactory.java:108)
    at com.sun.jersey.server.impl.model.ResourceUriRules.(ResourceUriRules.java:158)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.newResourceUriRules(WebApplicationImpl.java:653)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.access$500(WebApplicationImpl.java:161)
    at com.sun.jersey.server.impl.application.WebApplicationImpl$8.f(WebApplicationImpl.java:512)
    at com.sun.jersey.server.impl.application.WebApplicationImpl$8.f(WebApplicationImpl.java:510)
    at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:197)

    It would be great if you could help me.
    And perhaps it would be great if you could write guide how to enhance existing jersey applications with atmosphere async http framwork.

    King Regards,

    Bernd

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 50 other followers

%d bloggers like this: