package com.vistarmedia.api.transport; import java.io.IOException; import java.net.URL; import java.util.concurrent.Semaphore; import com.ning.http.client.AsyncCompletionHandler; import com.ning.http.client.AsyncHttpClient; import com.ning.http.client.AsyncHttpClientConfig; import com.ning.http.client.Response; import com.vistarmedia.api.ApiClient; /** * Transport implementation using Ning's async-http-client. This is the * preferred {@link Transport} to use, as we can rest assured its requests are * indeed happening asynchronously. */ public class AsyncHttpClientTransport implements Transport { private AsyncHttpClient client; private static final int MAX_CONNECTIONS = 3; private static final Semaphore conLock = new Semaphore(MAX_CONNECTIONS); private static final String USER_AGENT = String.format( "VistarClientAPI/%s.async", ApiClient.VERSION); public AsyncHttpClientTransport() { AsyncHttpClientConfig config = new AsyncHttpClientConfig.Builder() .setMaximumConnectionsTotal(MAX_CONNECTIONS).setUserAgent(USER_AGENT) .build(); this.client = new AsyncHttpClient(config); } /** * Factory method to create a new {@link ApiClient} configured for this * transport. * * @param host * Vistar Media API endpoint host * @param port * Vistar Media API endpoint port * @return a properly configured {@link ApiClient} for this transport. */ public static ApiClient connect(String host, int port) { return new ApiClient(host, port, new AsyncHttpClientTransport()); } public void post(final URL url, final byte[] body, final TransportResponseHandler handler) throws IOException { AsyncHttpClient.BoundRequestBuilder request = client.preparePost(url.toString()) // .setBody(body) // .addHeader("Content-Type", "application/octet-stream"); executeRequest(request, handler); } public void get(URL url, final TransportResponseHandler handler) throws IOException { executeRequest(client.prepareGet(url.toString()), handler); } private void executeRequest(AsyncHttpClient.BoundRequestBuilder requestBuilder, final TransportResponseHandler handler) throws IOException { try { conLock.acquire(); requestBuilder.execute(new AsyncCompletionHandler<Void>() { @Override public void onThrowable(Throwable t) { conLock.release(); handler.onThrowable(t); } @Override public Void onCompleted(Response response) throws Exception { conLock.release(); handler.onResponse(response.getStatusCode(), response.getStatusText(), response.getResponseBodyAsStream()); return null; } }); } catch (InterruptedException e) { handler.onThrowable(new RuntimeException( "Interrupted acquiring connection lock")); } } }