All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.edurt.datacap.pinot.com.ning.http.client.providers.netty.request.NettyConnectListener Maven / Gradle / Ivy

There is a newer version: 2024.03.7
Show newest version
/*
 * Copyright (c) 2014 AsyncHttpClient Project. All rights reserved.
 *
 * This program is licensed to you under the Apache License Version 2.0,
 * and you may not use this file except in compliance with the Apache License Version 2.0.
 * You may obtain a copy of the Apache License Version 2.0 at
 *     http://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Apache License Version 2.0 is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
 */
package io.edurt.datacap.pinot.com.ning.http.client.providers.netty.request;

import static io.edurt.datacap.pinot.com.ning.http.util.AsyncHttpProviderUtils.getBaseUrl;

import io.edurt.datacap.pinot.com.ning.http.client.AsyncHandler;
import io.edurt.datacap.pinot.org.jboss.netty.channel.Channel;
import io.edurt.datacap.pinot.org.jboss.netty.channel.ChannelFuture;
import io.edurt.datacap.pinot.org.jboss.netty.channel.ChannelFutureListener;
import io.edurt.datacap.pinot.org.jboss.netty.handler.ssl.SslHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.edurt.datacap.pinot.com.ning.http.client.AsyncHandlerExtensions;
import io.edurt.datacap.pinot.com.ning.http.client.providers.netty.channel.ChannelManager;
import io.edurt.datacap.pinot.com.ning.http.client.providers.netty.channel.Channels;
import io.edurt.datacap.pinot.com.ning.http.client.providers.netty.future.NettyResponseFuture;
import io.edurt.datacap.pinot.com.ning.http.client.providers.netty.future.StackTraceInspector;

import java.net.ConnectException;

/**
 * Non Blocking connect.
 */
public final class NettyConnectListener implements ChannelFutureListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(NettyConnectListener.class);
    private final NettyResponseFuture future;
    private final NettyRequestSender requestSender;
    private final ChannelManager channelManager;
    private final boolean channelPreempted;
    private final String partition;

    public NettyConnectListener(NettyResponseFuture future,//
            NettyRequestSender requestSender,//
            ChannelManager channelManager,//
            boolean channelPreempted,//
            String partition) {
        this.future = future;
        this.requestSender = requestSender;
        this.channelManager = channelManager;
        this.channelPreempted = channelPreempted;
        this.partition = partition;
    }

    public NettyResponseFuture future() {
        return future;
    }

    private void abortChannelPreemption(String partition) {
        if (channelPreempted)
            channelManager.abortChannelPreemption(partition);
    }

    private void writeRequest(Channel channel) {

        LOGGER.debug("Request using non cached Channel '{}':\n{}\n", channel, future.getNettyRequest().getHttpRequest());

        Channels.setAttribute(channel, future);

        if (future.isDone()) {
            abortChannelPreemption(partition);
            return;
        }

        if (future.getAsyncHandler() instanceof AsyncHandlerExtensions)
            AsyncHandlerExtensions.class.cast(future.getAsyncHandler()).onConnectionOpen();

        channelManager.registerOpenChannel(channel, partition);
        future.attachChannel(channel, false);
        requestSender.writeRequest(future, channel);
    }

    private void onFutureSuccess(final Channel channel) throws ConnectException {

        SslHandler sslHandler = channel.getPipeline().get(SslHandler.class);

        if (sslHandler != null) {
            sslHandler.handshake().addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture handshakeFuture) throws Exception {
                    if (handshakeFuture.isSuccess()) {
                        final AsyncHandler asyncHandler = future.getAsyncHandler();
                        if (asyncHandler instanceof AsyncHandlerExtensions)
                            AsyncHandlerExtensions.class.cast(asyncHandler).onSslHandshakeCompleted();

                        writeRequest(channel);
                    } else {
                        onFutureFailure(channel, handshakeFuture.getCause());
                    }
                }
            });

        } else {
            writeRequest(channel);
        }
    }

    private void onFutureFailure(Channel channel, Throwable cause) {
        abortChannelPreemption(partition);

        boolean canRetry = future.canRetry();
        LOGGER.debug("Trying to recover from failing to connect channel {} with a retry value of {} ", channel, canRetry);
        if (canRetry
                && cause != null
                && (future.getState() != NettyResponseFuture.STATE.NEW || StackTraceInspector.recoverOnDisconnectException(cause))) {

            if (requestSender.retry(future))
                return;
        }

        LOGGER.debug("Failed to recover from connect exception: {} with channel {}", cause, channel);

        boolean printCause = cause != null && cause.getMessage() != null;
        String printedCause = printCause ? cause.getMessage() : getBaseUrl(future.getUri());
        ConnectException e = new ConnectException(printedCause);
        if (cause != null) {
            e.initCause(cause);
        }
        future.abort(e);
    }

    public final void operationComplete(ChannelFuture f) throws Exception {
        Channel channel = f.getChannel();
        if (f.isSuccess())
            onFutureSuccess(channel);
        else
            onFutureFailure(channel, f.getCause());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy