com.hubspot.horizon.ning.NingAsyncHttpClient Maven / Gradle / Ivy
package com.hubspot.horizon.ning;
import java.io.IOException;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.asynchttpclient.AsyncHttpClientConfig;
import org.asynchttpclient.DefaultAsyncHttpClient;
import org.asynchttpclient.DefaultAsyncHttpClientConfig;
import org.asynchttpclient.Request;
import org.asynchttpclient.filter.ThrottleRequestFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.ListenableFuture;
import com.hubspot.horizon.AsyncHttpClient;
import com.hubspot.horizon.HttpConfig;
import com.hubspot.horizon.HttpRequest;
import com.hubspot.horizon.HttpRequest.Options;
import com.hubspot.horizon.HttpResponse;
import com.hubspot.horizon.ning.internal.AcceptEncodingRequestFilter;
import com.hubspot.horizon.ning.internal.EmptyCallback;
import com.hubspot.horizon.ning.internal.NingCompletionHandler;
import com.hubspot.horizon.ning.internal.NingFuture;
import com.hubspot.horizon.ning.internal.NingHttpRequestConverter;
import com.hubspot.horizon.ning.internal.NingRetryHandler;
import com.hubspot.horizon.ning.internal.NingSSLContext;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.HashedWheelTimer;
import io.netty.util.concurrent.DefaultThreadFactory;
public class NingAsyncHttpClient implements AsyncHttpClient {
private static final HashedWheelTimer TIMER = new HashedWheelTimer(newThreadFactory("NingAsyncHttpClient-Timer"));
private final org.asynchttpclient.AsyncHttpClient ningClient;
private final NingHttpRequestConverter requestConverter;
private final Options defaultOptions;
private final ObjectMapper mapper;
private final EventLoopGroup eventLoopGroup;
public NingAsyncHttpClient() {
this(HttpConfig.newBuilder().build());
}
public NingAsyncHttpClient(HttpConfig config) {
Preconditions.checkNotNull(config);
this.eventLoopGroup = newEventLoopGroup();
AsyncHttpClientConfig ningConfig = new DefaultAsyncHttpClientConfig.Builder()
.addRequestFilter(new ThrottleRequestFilter(config.getMaxConnections()))
.addRequestFilter(new AcceptEncodingRequestFilter())
.setMaxConnectionsPerHost(config.getMaxConnectionsPerHost())
.setConnectionTtl(config.getConnectionTtlMillis())
.setConnectTimeout(config.getConnectTimeoutMillis())
.setRequestTimeout(config.getRequestTimeoutMillis())
.setReadTimeout(config.getRequestTimeoutMillis())
.setMaxRedirects(config.getMaxRedirects())
.setFollowRedirect(config.isFollowRedirects())
.setSslContext(NingSSLContext.forConfig(config.getSSLConfig()))
.setUserAgent(config.getUserAgent())
.setEventLoopGroup(eventLoopGroup)
.setNettyTimer(TIMER)
.setMaxRequestRetry(0) // we handle retries ourselves
.build();
this.ningClient = new DefaultAsyncHttpClient(ningConfig);
this.requestConverter = new NingHttpRequestConverter(config.getObjectMapper());
this.defaultOptions = config.getOptions();
this.mapper = config.getObjectMapper();
}
@Override
public ListenableFuture execute(HttpRequest request) {
return execute(Preconditions.checkNotNull(request), Options.DEFAULT);
}
@Override
public ListenableFuture execute(HttpRequest request, Options options) {
return internalExecute(request, options, EmptyCallback.INSTANCE);
}
@Override
public void execute(HttpRequest request, Callback callback) {
execute(Preconditions.checkNotNull(request), Options.DEFAULT, callback);
}
@Override
public void execute(HttpRequest request, Options options, Callback callback) {
internalExecute(request, options, callback);
}
private ListenableFuture internalExecute(HttpRequest request, Options options, Callback callback) {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(options);
Preconditions.checkNotNull(callback);
NingRetryHandler retryHandler = new NingRetryHandler(defaultOptions.mergeFrom(options));
NingFuture future = new NingFuture(callback);
final NingCompletionHandler completionHandler = new NingCompletionHandler(request, future, retryHandler, mapper);
final Request ningRequest = requestConverter.convert(request);
Runnable runnable = () -> {
try {
ningClient.executeRequest(ningRequest, completionHandler);
} catch (RuntimeException e) {
completionHandler.onThrowable(e);
}
};
retryHandler.setRetryRunnable(runnable);
runnable.run();
return future;
}
private EventLoopGroup newEventLoopGroup() {
ThreadFactory threadFactory = newThreadFactory("NingAsyncHttpClient");
int workerThreads = Math.min(Runtime.getRuntime().availableProcessors(), 4);
return new NioEventLoopGroup(workerThreads, threadFactory);
}
private static ThreadFactory newThreadFactory(String name) {
return new DefaultThreadFactory(name, true);
}
@Override
public void close() throws IOException {
try {
ningClient.close();
} finally {
eventLoopGroup.shutdownGracefully(0, 5, TimeUnit.SECONDS);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy