com.king.platform.net.http.netty.HttpClientCallerImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of king-http-client Show documentation
Show all versions of king-http-client Show documentation
A asyncronous http client built ontop of netty.
package com.king.platform.net.http.netty;
import com.king.platform.net.http.*;
import com.king.platform.net.http.netty.backpressure.BackPressure;
import com.king.platform.net.http.netty.eventbus.*;
import com.king.platform.net.http.netty.metric.TimeStampRecorder;
import com.king.platform.net.http.netty.request.NettyHttpClientRequest;
import com.king.platform.net.http.netty.requestbuilder.UploadCallbackInvoker;
import com.king.platform.net.http.netty.util.TimeProvider;
import io.netty.handler.codec.http.HttpMethod;
import org.slf4j.Logger;
import java.nio.ByteBuffer;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import static org.slf4j.LoggerFactory.getLogger;
public class HttpClientCallerImpl implements HttpClientCaller {
private final Logger logger = getLogger(getClass());
private final RootEventBus rootEventBus;
private final boolean executeOnCallingThread;
private final ChannelManager channelManager;
private final BackPressure executionBackPressure;
private final TimeProvider timeProvider;
HttpClientCallerImpl(RootEventBus rootEventBus, boolean executeOnCallingThread, ChannelManager channelManager, BackPressure executionBackPressure, TimeProvider timeProvider) {
this.rootEventBus = rootEventBus;
this.executeOnCallingThread = executeOnCallingThread;
this.channelManager = channelManager;
this.executionBackPressure = executionBackPressure;
this.timeProvider = timeProvider;
}
@Override
public CompletableFuture> execute(HttpMethod httpMethod, final NettyHttpClientRequest nettyHttpClientRequest,
HttpCallback httpCallback, final NioCallback nioCallback, UploadCallback uploadCallback,
ResponseBodyConsumer responseBodyConsumer, Executor callbackExecutor,
ExternalEventTrigger externalEventTrigger, CustomCallbackSubscriber customCallbackSubscriber, int idleTimeoutMillis, int totalRequestTimeoutMillis,
boolean followRedirects, boolean keepAlive) {
final RequestEventBus requestRequestEventBus = rootEventBus.createRequestEventBus();
if (externalEventTrigger != null) {
externalEventTrigger.registerEventListener(new EventListener() {
@Override
public void onEvent(Event1 event, E payload) {
requestRequestEventBus.triggerEvent(event, payload);
}
@Override
public void onEvent(Event2 event, E1 payload1, E2 payload2) {
requestRequestEventBus.triggerEvent(event, payload1, payload2);
}
});
}
subscribeToHttpCallbackEvents(callbackExecutor, httpCallback, requestRequestEventBus);
subscribeToNioCallbackEvents(nioCallback, requestRequestEventBus);
subscribeToUploadCallbacksEvents(callbackExecutor, uploadCallback, requestRequestEventBus);
if (customCallbackSubscriber != null) {
customCallbackSubscriber.subscribeOn(requestRequestEventBus);
}
if (responseBodyConsumer == null) {
responseBodyConsumer = getResponseBodyConsumer();
}
final HttpRequestContext httpRequestContext = new HttpRequestContext<>(httpMethod, nettyHttpClientRequest, requestRequestEventBus,
responseBodyConsumer,
idleTimeoutMillis, totalRequestTimeoutMillis, followRedirects, keepAlive, new TimeStampRecorder(timeProvider));
ResponseFuture future = new ResponseFuture<>(requestRequestEventBus, httpRequestContext, callbackExecutor);
if (!executionBackPressure.acquireSlot(nettyHttpClientRequest.getServerInfo())) {
requestRequestEventBus.triggerEvent(Event.ERROR, httpRequestContext, new KingHttpException("Too many concurrent connections"));
return future;
}
logger.trace("Executing httpRequest {}", httpRequestContext);
if (executeOnCallingThread) {
sendRequest(requestRequestEventBus, httpRequestContext);
} else {
callbackExecutor.execute(() -> sendRequest(requestRequestEventBus, httpRequestContext));
}
return future;
}
@SuppressWarnings("unchecked")
private ResponseBodyConsumer getResponseBodyConsumer() {
return (ResponseBodyConsumer) EMPTY_RESPONSE_BODY_CONSUMER;
}
private void subscribeToHttpCallbackEvents(final Executor callbackExecutor, final HttpCallback httpCallback, RequestEventBus
requestRequestEventBus) {
if (httpCallback == null) {
return;
}
HttpCallbackInvoker httpCallbackInvoker = new HttpCallbackInvoker<>(callbackExecutor, httpCallback);
requestRequestEventBus.subscribePermanently(Event.onHttpResponseDone, httpCallbackInvoker::onHttpResponseDone);
requestRequestEventBus.subscribePermanently(Event.ERROR, httpCallbackInvoker::onError);
}
private void subscribeToNioCallbackEvents(final NioCallback nioCallback, RequestEventBus requestRequestEventBus) {
if (nioCallback == null) {
return;
}
requestRequestEventBus.subscribePermanently(Event.onConnecting, (payload) -> nioCallback.onConnecting());
requestRequestEventBus.subscribePermanently(Event.onConnected, (payload) -> nioCallback.onConnected());
requestRequestEventBus.subscribePermanently(Event.onWroteHeaders, (payload) -> nioCallback.onWroteHeaders());
requestRequestEventBus.subscribePermanently(Event.onWroteContentProgressed, nioCallback::onWroteContentProgressed);
requestRequestEventBus.subscribePermanently(Event.onWroteContentCompleted, (payload) -> nioCallback.onWroteContentCompleted());
requestRequestEventBus.subscribePermanently(Event.onReceivedStatus, nioCallback::onReceivedStatus);
requestRequestEventBus.subscribePermanently(Event.onReceivedHeaders, nioCallback::onReceivedHeaders);
requestRequestEventBus.subscribePermanently(Event.onReceivedContentPart, nioCallback::onReceivedContentPart);
requestRequestEventBus.subscribePermanently(Event.onReceivedCompleted, nioCallback::onReceivedCompleted);
requestRequestEventBus.subscribePermanently(Event.ERROR, (httpRequestContext, throwable) -> nioCallback.onError(throwable));
}
private void subscribeToUploadCallbacksEvents(Executor callbackExecutor, UploadCallback uploadCallback, RequestEventBus requestRequestEventBus) {
if (uploadCallback == null) {
return;
}
UploadCallbackInvoker uploadCallbackInvoker = new UploadCallbackInvoker(uploadCallback, callbackExecutor);
requestRequestEventBus.subscribe(Event.onWroteContentStarted, uploadCallbackInvoker::onUploadStarted);
requestRequestEventBus.subscribe(Event.onWroteContentProgressed, uploadCallbackInvoker::onUploadProgressed);
requestRequestEventBus.subscribe(Event.onWroteContentCompleted, uploadCallbackInvoker::onUploadComplete);
}
private void sendRequest(RequestEventBus requestRequestEventBus, HttpRequestContext httpRequestContext) {
try {
channelManager.sendOnChannel(httpRequestContext, requestRequestEventBus);
} catch (Throwable throwable) {
requestRequestEventBus.triggerEvent(Event.ERROR, httpRequestContext, throwable);
}
}
private static final ResponseBodyConsumer EMPTY_RESPONSE_BODY_CONSUMER = new ResponseBodyConsumer() {
@Override
public void onBodyStart(String contentType, String charset, long contentLength) throws Exception {
}
@Override
public void onReceivedContentPart(ByteBuffer buffer) throws Exception {
}
@Override
public void onCompletedBody() throws Exception {
}
@Override
public Void getBody() {
return null;
}
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy