Example usage for io.netty.channel ChannelFuture isSuccess

List of usage examples for io.netty.channel ChannelFuture isSuccess

Introduction

In this page you can find the example usage for io.netty.channel ChannelFuture isSuccess.

Prototype

boolean isSuccess();

Source Link

Document

Returns true if and only if the I/O operation was completed successfully.

Usage

From source file:com.relayrides.pushy.apns.ApnsClient.java

License:Open Source License

/**
 * <p>Connects to the given APNs gateway on the given port.</p>
 *
 * <p>Once an initial connection has been established and until the client has been explicitly disconnected via the
 * {@link ApnsClient#disconnect()} method, the client will attempt to reconnect automatically if the connection
 * closes unexpectedly. If the connection closes unexpectedly, callers may monitor the status of the reconnection
 * attempt with the {@code Future} returned by the {@link ApnsClient#getReconnectionFuture()} method.</p>
 *
 * @param host the APNs gateway to which to connect
 * @param port the port on which to connect to the APNs gateway
 *
 * @return a {@code Future} that will succeed when the client has connected to the gateway and is ready to send
 * push notifications//from   w ww .jav a2  s  . c  o m
 *
 * @see ApnsClient#PRODUCTION_APNS_HOST
 * @see ApnsClient#DEVELOPMENT_APNS_HOST
 * @see ApnsClient#DEFAULT_APNS_PORT
 * @see ApnsClient#ALTERNATE_APNS_PORT
 *
 * @since 0.5
 */
public Future<Void> connect(final String host, final int port) {
    final Future<Void> connectionReadyFuture;

    if (this.bootstrap.config().group().isShuttingDown() || this.bootstrap.config().group().isShutdown()) {
        connectionReadyFuture = new FailedFuture<>(GlobalEventExecutor.INSTANCE, new IllegalStateException(
                "Client's event loop group has been shut down and cannot be restarted."));
    } else {
        synchronized (this.bootstrap) {
            // We only want to begin a connection attempt if one is not already in progress or complete; if we already
            // have a connection future, just return the existing promise.
            if (this.connectionReadyPromise == null) {
                this.metricsListener.handleConnectionAttemptStarted(this);

                final ChannelFuture connectFuture = this.bootstrap.connect(host, port);
                this.connectionReadyPromise = connectFuture.channel().newPromise();

                connectFuture.addListener(new GenericFutureListener<ChannelFuture>() {

                    @Override
                    public void operationComplete(final ChannelFuture future) throws Exception {
                        if (!future.isSuccess()) {
                            final ChannelPromise connectionReadyPromise = ApnsClient.this.connectionReadyPromise;

                            if (connectionReadyPromise != null) {
                                // This may seem spurious, but our goal here is to accurately report the cause of
                                // connection failure; if we just wait for connection closure, we won't be able to
                                // tell callers anything more specific about what went wrong.
                                connectionReadyPromise.tryFailure(future.cause());
                            }
                        }
                    }
                });

                connectFuture.channel().closeFuture().addListener(new GenericFutureListener<ChannelFuture>() {

                    @Override
                    public void operationComplete(final ChannelFuture future) throws Exception {
                        synchronized (ApnsClient.this.bootstrap) {
                            if (ApnsClient.this.connectionReadyPromise != null) {
                                // We always want to try to fail the "connection ready" promise if the connection
                                // closes; if it has already succeeded, this will have no effect.
                                ApnsClient.this.connectionReadyPromise.tryFailure(new IllegalStateException(
                                        "Channel closed before HTTP/2 preface completed."));

                                ApnsClient.this.connectionReadyPromise = null;
                            }

                            if (ApnsClient.this.reconnectionPromise != null) {
                                log.debug("Disconnected. Next automatic reconnection attempt in {} seconds.",
                                        ApnsClient.this.reconnectDelaySeconds);

                                ApnsClient.this.scheduledReconnectFuture = future.channel().eventLoop()
                                        .schedule(new Runnable() {

                                            @Override
                                            public void run() {
                                                log.debug("Attempting to reconnect.");
                                                ApnsClient.this.connect(host, port);
                                            }
                                        }, ApnsClient.this.reconnectDelaySeconds, TimeUnit.SECONDS);

                                ApnsClient.this.reconnectDelaySeconds = Math.min(
                                        ApnsClient.this.reconnectDelaySeconds, MAX_RECONNECT_DELAY_SECONDS);
                            }
                        }
                    }
                });

                this.connectionReadyPromise.addListener(new GenericFutureListener<ChannelFuture>() {

                    @Override
                    public void operationComplete(final ChannelFuture future) throws Exception {
                        if (future.isSuccess()) {
                            synchronized (ApnsClient.this.bootstrap) {
                                if (ApnsClient.this.reconnectionPromise != null) {
                                    log.info("Connection to {} restored.", future.channel().remoteAddress());
                                    ApnsClient.this.reconnectionPromise.trySuccess();
                                } else {
                                    log.info("Connected to {}.", future.channel().remoteAddress());
                                }

                                ApnsClient.this.reconnectDelaySeconds = INITIAL_RECONNECT_DELAY_SECONDS;
                                ApnsClient.this.reconnectionPromise = future.channel().newPromise();
                            }

                            ApnsClient.this.metricsListener.handleConnectionAttemptSucceeded(ApnsClient.this);
                        } else {
                            log.info("Failed to connect.", future.cause());

                            ApnsClient.this.metricsListener.handleConnectionAttemptFailed(ApnsClient.this);
                        }
                    }
                });
            }

            connectionReadyFuture = this.connectionReadyPromise;
        }
    }

    return connectionReadyFuture;
}

From source file:com.relayrides.pushy.apns.ApnsClient.java

License:Open Source License

/**
 * <p>Sends a push notification to the APNs gateway.</p>
 *
 * <p>This method returns a {@code Future} that indicates whether the notification was accepted or rejected by the
 * gateway. If the notification was accepted, it may be delivered to its destination device at some time in the
 * future, but final delivery is not guaranteed. Rejections should be considered permanent failures, and callers
 * should <em>not</em> attempt to re-send the notification.</p>
 *
 * <p>The returned {@code Future} may fail with an exception if the notification could not be sent. Failures to
 * <em>send</em> a notification to the gatewayi.e. those that fail with exceptionsshould generally be considered
 * non-permanent, and callers should attempt to re-send the notification when the underlying problem has been
 * resolved.</p>/*w w  w .  jav a  2  s.c o m*/
 *
 * <p>In particular, attempts to send a notification when the client is not connected will fail with a
 * {@link ClientNotConnectedException}. If the client was previously connected and has not been explicitly
 * disconnected (via the {@link ApnsClient#disconnect()} method), the client will attempt to reconnect
 * automatically. Callers may wait for a reconnection attempt to complete by waiting for the {@code Future} returned
 * by the {@link ApnsClient#getReconnectionFuture()} method.</p>
 *
 * @param notification the notification to send to the APNs gateway
 *
 * @param <T> the type of notification to be sent
 *
 * @return a {@code Future} that will complete when the notification has been either accepted or rejected by the
 * APNs gateway
 *
 * @since 0.8
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public <T extends ApnsPushNotification> Future<PushNotificationResponse<T>> sendNotification(
        final T notification) {
    final Future<PushNotificationResponse<T>> responseFuture;
    final long notificationId = this.nextNotificationId.getAndIncrement();

    // Instead of synchronizing here, we keep a final reference to the connection ready promise. We can get away
    // with this because we're not changing the state of the connection or its promises. Keeping a reference ensures
    // we won't suddenly "lose" the channel and get a NullPointerException, but risks sending a notification after
    // things have shut down. In that case, though, the returned futures should fail quickly, and the benefit of
    // not synchronizing for every write seems worth it.
    final ChannelPromise connectionReadyPromise = this.connectionReadyPromise;

    if (connectionReadyPromise != null && connectionReadyPromise.isSuccess()
            && connectionReadyPromise.channel().isActive()) {
        final Channel channel = connectionReadyPromise.channel();
        final Promise<PushNotificationResponse<ApnsPushNotification>> responsePromise = new DefaultPromise(
                channel.eventLoop());

        channel.writeAndFlush(new PushNotificationAndResponsePromise(notification, responsePromise))
                .addListener(new GenericFutureListener<ChannelFuture>() {

                    @Override
                    public void operationComplete(final ChannelFuture future) throws Exception {
                        if (future.isSuccess()) {
                            ApnsClient.this.metricsListener.handleNotificationSent(ApnsClient.this,
                                    notificationId);
                        } else {
                            responsePromise.tryFailure(future.cause());
                        }
                    }
                });

        responseFuture = (Future) responsePromise;
    } else {
        log.debug("Failed to send push notification because client is not connected: {}", notification);
        responseFuture = new FailedFuture<>(GlobalEventExecutor.INSTANCE, NOT_CONNECTED_EXCEPTION);
    }

    responseFuture.addListener(new GenericFutureListener<Future<PushNotificationResponse<T>>>() {

        @Override
        public void operationComplete(final Future<PushNotificationResponse<T>> future) throws Exception {
            if (future.isSuccess()) {
                final PushNotificationResponse<T> response = future.getNow();

                if (response.isAccepted()) {
                    ApnsClient.this.metricsListener.handleNotificationAccepted(ApnsClient.this, notificationId);
                } else {
                    ApnsClient.this.metricsListener.handleNotificationRejected(ApnsClient.this, notificationId);
                }
            } else {
                ApnsClient.this.metricsListener.handleWriteFailure(ApnsClient.this, notificationId);
            }
        }
    });

    return responseFuture;
}

From source file:com.relayrides.pushy.apns.ApnsClientHandler.java

License:Open Source License

@Override
public void userEventTriggered(final ChannelHandlerContext context, final Object event) throws Exception {
    if (event instanceof IdleStateEvent) {
        assert PING_TIMEOUT < ApnsClient.PING_IDLE_TIME_MILLIS;

        log.trace("Sending ping due to inactivity.");

        final ByteBuf pingDataBuffer = context.alloc().ioBuffer(8, 8);
        pingDataBuffer.writeLong(this.nextPingId++);

        this.encoder().writePing(context, false, pingDataBuffer, context.newPromise())
                .addListener(new GenericFutureListener<ChannelFuture>() {

                    @Override/*w  w w. ja v a  2s.c  o  m*/
                    public void operationComplete(final ChannelFuture future) throws Exception {
                        if (future.isSuccess()) {
                            ApnsClientHandler.this.pingTimeoutFuture = future.channel().eventLoop()
                                    .schedule(new Runnable() {

                                        @Override
                                        public void run() {
                                            log.debug("Closing channel due to ping timeout.");
                                            future.channel().close();
                                        }
                                    }, PING_TIMEOUT, TimeUnit.SECONDS);
                        } else {
                            log.debug("Failed to write PING frame.", future.cause());
                            future.channel().close();
                        }
                    }
                });

        this.flush(context);
    }

    super.userEventTriggered(context, event);
}

From source file:com.relayrides.pushy.apns.ApnsConnection.java

License:Open Source License

/**
 * Asynchronously connects to the APNs gateway in this connection's environment. The outcome of the connection
 * attempt is reported via this connection's listener.
 *
 * @see ApnsConnectionListener#handleConnectionSuccess(ApnsConnection)
 * @see ApnsConnectionListener#handleConnectionFailure(ApnsConnection, Throwable)
 *///  w  ww . j a  v a 2 s  .c  o m
@SuppressWarnings("deprecation")
public synchronized void connect() {

    final ApnsConnection<T> apnsConnection = this;

    if (this.connectFuture != null) {
        throw new IllegalStateException(String.format("%s already started a connection attempt.", this.name));
    }

    final Bootstrap bootstrap = new Bootstrap();
    bootstrap.group(this.eventLoopGroup);
    bootstrap.channel(NioSocketChannel.class);
    bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
    bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

    // TODO Remove this when Netty 5 is available
    bootstrap.option(ChannelOption.AUTO_CLOSE, false);

    bootstrap.handler(new ChannelInitializer<SocketChannel>() {

        @Override
        protected void initChannel(final SocketChannel channel) {
            final ChannelPipeline pipeline = channel.pipeline();

            final SSLEngine sslEngine = apnsConnection.sslContext.createSSLEngine();
            sslEngine.setUseClientMode(true);

            pipeline.addLast("ssl", new SslHandler(sslEngine));
            pipeline.addLast("decoder", new RejectedNotificationDecoder());
            pipeline.addLast("encoder", new ApnsPushNotificationEncoder());
            pipeline.addLast("handler", new ApnsConnectionHandler(apnsConnection));
        }
    });

    log.debug("{} beginning connection process.", apnsConnection.name);
    this.connectFuture = bootstrap.connect(this.environment.getApnsGatewayHost(),
            this.environment.getApnsGatewayPort());
    this.connectFuture.addListener(new GenericFutureListener<ChannelFuture>() {

        public void operationComplete(final ChannelFuture connectFuture) {
            if (connectFuture.isSuccess()) {
                log.debug("{} connected; waiting for TLS handshake.", apnsConnection.name);

                final SslHandler sslHandler = connectFuture.channel().pipeline().get(SslHandler.class);

                try {
                    sslHandler.handshakeFuture().addListener(new GenericFutureListener<Future<Channel>>() {

                        public void operationComplete(final Future<Channel> handshakeFuture) {
                            if (handshakeFuture.isSuccess()) {
                                log.debug("{} successfully completed TLS handshake.", apnsConnection.name);

                                apnsConnection.handshakeCompleted = true;
                                apnsConnection.listener.handleConnectionSuccess(apnsConnection);
                            } else {
                                log.debug("{} failed to complete TLS handshake with APNs gateway.",
                                        apnsConnection.name, handshakeFuture.cause());

                                connectFuture.channel().close();
                                apnsConnection.listener.handleConnectionFailure(apnsConnection,
                                        handshakeFuture.cause());
                            }
                        }
                    });
                } catch (NullPointerException e) {
                    log.warn("{} failed to get SSL handler and could not wait for a TLS handshake.",
                            apnsConnection.name);

                    connectFuture.channel().close();
                    apnsConnection.listener.handleConnectionFailure(apnsConnection, e);
                }
            } else {
                log.debug("{} failed to connect to APNs gateway.", apnsConnection.name, connectFuture.cause());

                apnsConnection.listener.handleConnectionFailure(apnsConnection, connectFuture.cause());
            }
        }
    });
}

From source file:com.relayrides.pushy.apns.ApnsConnection.java

License:Open Source License

/**
 * Asynchronously sends a push notification to the connected APNs gateway. Successful notifications are
 * <strong>not</strong> acknowledged by the APNs gateway; failed attempts to write push notifications to the
 * outbound buffer and notification rejections are reported via this connection's listener.
 *
 * @param notification the notification to send
 *
 * @see ApnsConnectionListener#handleWriteFailure(ApnsConnection, ApnsPushNotification, Throwable)
 * @see ApnsConnectionListener#handleRejectedNotification(ApnsConnection, ApnsPushNotification, RejectedNotificationReason)
 *//*from www.j  a v a 2s. c om*/
public synchronized void sendNotification(final T notification) {
    final ApnsConnection<T> apnsConnection = this;

    if (!this.handshakeCompleted) {
        throw new IllegalStateException(String.format("%s has not completed handshake.", this.name));
    }

    this.connectFuture.channel().eventLoop().execute(new Runnable() {

        public void run() {
            final SendableApnsPushNotification<T> sendableNotification = new SendableApnsPushNotification<T>(
                    notification, apnsConnection.sequenceNumber++);

            log.trace("{} sending {}", apnsConnection.name, sendableNotification);

            apnsConnection.pendingWriteCount += 1;

            apnsConnection.connectFuture.channel().writeAndFlush(sendableNotification)
                    .addListener(new GenericFutureListener<ChannelFuture>() {

                        public void operationComplete(final ChannelFuture writeFuture) {
                            if (writeFuture.isSuccess()) {
                                log.trace("{} successfully wrote notification {}", apnsConnection.name,
                                        sendableNotification.getSequenceNumber());

                                if (apnsConnection.rejectionReceived) {
                                    // Even though the write succeeded, we know for sure that this notification was never
                                    // processed by the gateway because it had already rejected another notification from
                                    // this connection.
                                    apnsConnection.listener.handleUnprocessedNotifications(apnsConnection,
                                            java.util.Collections.singletonList(notification));
                                } else {
                                    apnsConnection.sentNotificationBuffer
                                            .addSentNotification(sendableNotification);
                                }
                            } else {
                                log.trace("{} failed to write notification {}", apnsConnection.name,
                                        sendableNotification, writeFuture.cause());

                                // Assume this is a temporary failure (we know it's not a permanent rejection because we didn't
                                // even manage to write the notification to the wire) and re-enqueue for another send attempt.
                                apnsConnection.listener.handleWriteFailure(apnsConnection, notification,
                                        writeFuture.cause());
                            }

                            apnsConnection.pendingWriteCount -= 1;
                            assert apnsConnection.pendingWriteCount >= 0;

                            if (apnsConnection.pendingWriteCount == 0) {
                                synchronized (apnsConnection.pendingWriteMonitor) {
                                    apnsConnection.pendingWriteMonitor.notifyAll();
                                }
                            }
                        }
                    });
        }
    });
}

From source file:com.relayrides.pushy.apns.ApnsConnection.java

License:Open Source License

/**
 * <p>Gracefully and asynchronously shuts down this connection. Graceful disconnection is triggered by sending a
 * known-bad notification to the APNs gateway; when the gateway rejects the notification, it is guaranteed that
 * preceding notifications were processed successfully and that all following notifications were not processed at
 * all. The gateway will close the connection after rejecting the notification, and this connection's listener will
 * be notified when the connection is closed.</p>
 *
 * <p>Note that if/when the known-bad notification is rejected by the APNs gateway, this connection's listener will
 * <em>not</em> be notified of the rejection.</p>
 *
 * <p>Calling this method before establishing a connection with the APNs gateway or while a graceful shutdown
 * attempt is already in progress has no effect.</p>
 *
 * @see ApnsConnectionListener#handleRejectedNotification(ApnsConnection, ApnsPushNotification, RejectedNotificationReason)
 * @see ApnsConnectionListener#handleConnectionClosure(ApnsConnection)
 *//*from  ww  w.  jav a2 s  .c o m*/
public synchronized void shutdownGracefully() {

    final ApnsConnection<T> apnsConnection = this;

    // We only need to send a known-bad notification if we were ever connected in the first place and if we're
    // still connected.
    if (this.handshakeCompleted && this.connectFuture.channel().isActive()) {

        this.connectFuture.channel().eventLoop().execute(new Runnable() {

            public void run() {
                // Don't send a second shutdown notification if we've already started the graceful shutdown process.
                if (apnsConnection.shutdownNotification == null) {

                    log.debug("{} sending known-bad notification to shut down.", apnsConnection.name);

                    apnsConnection.shutdownNotification = new SendableApnsPushNotification<KnownBadPushNotification>(
                            new KnownBadPushNotification(), apnsConnection.sequenceNumber++);

                    apnsConnection.pendingWriteCount += 1;

                    apnsConnection.connectFuture.channel().writeAndFlush(apnsConnection.shutdownNotification)
                            .addListener(new GenericFutureListener<ChannelFuture>() {

                                public void operationComplete(final ChannelFuture future) {
                                    if (future.isSuccess()) {
                                        log.trace("{} successfully wrote known-bad notification {}",
                                                apnsConnection.name,
                                                apnsConnection.shutdownNotification.getSequenceNumber());
                                    } else {
                                        log.trace("{} failed to write known-bad notification {}",
                                                apnsConnection.name, apnsConnection.shutdownNotification,
                                                future.cause());

                                        // Try again!
                                        apnsConnection.shutdownNotification = null;
                                        apnsConnection.shutdownGracefully();
                                    }

                                    apnsConnection.pendingWriteCount -= 1;
                                    assert apnsConnection.pendingWriteCount >= 0;

                                    if (apnsConnection.pendingWriteCount == 0) {
                                        synchronized (apnsConnection.pendingWriteMonitor) {
                                            apnsConnection.pendingWriteMonitor.notifyAll();
                                        }
                                    }
                                }
                            });
                }
            }
        });
    } else {
        // While we can't guarantee that the handshake won't complete in another thread, we CAN guarantee that no
        // new notifications will be sent until shutdownImmediately happens because everything is synchronized.
        this.shutdownImmediately();
    }
}

From source file:com.relayrides.pushy.apns.FeedbackServiceClient.java

License:Open Source License

/**
 * <p>Retrieves a list of expired tokens from the APNs feedback service. Be warned that this is a
 * <strong>destructive operation</strong>. According to Apple's documentation:</p>
 *
 * <blockquote>The feedback service's list is cleared after you read it. Each time you connect to the feedback
 * service, the information it returns lists only the failures that have happened since you last
 * connected.</blockquote>/*from w  w  w . j a v  a 2s  .  c o m*/
 *
 * @param timeout the time after the last received data after which the connection to the feedback service should
 * be closed
 * @param timeoutUnit the unit of time in which the given {@code timeout} is measured
 *
 * @return a list of tokens that have expired since the last connection to the feedback service
 *
 * @throws InterruptedException if interrupted while waiting for a response from the feedback service
 * @throws FeedbackConnectionException if the connection to the feedback service failed for any reason
 */
public synchronized List<ExpiredToken> getExpiredTokens(final long timeout, final TimeUnit timeoutUnit)
        throws InterruptedException, FeedbackConnectionException {

    this.expiredTokens.clear();

    final Bootstrap bootstrap = new Bootstrap();
    bootstrap.group(this.eventLoopGroup);
    bootstrap.channel(NioSocketChannel.class);

    final FeedbackServiceClient feedbackClient = this;
    bootstrap.handler(new ChannelInitializer<SocketChannel>() {

        @Override
        protected void initChannel(final SocketChannel channel) throws Exception {
            final ChannelPipeline pipeline = channel.pipeline();

            final SSLEngine sslEngine = feedbackClient.sslContext.createSSLEngine();
            sslEngine.setUseClientMode(true);

            pipeline.addLast("ssl", new SslHandler(sslEngine));
            pipeline.addLast("readTimeoutHandler", new ReadTimeoutHandler(timeout, timeoutUnit));
            pipeline.addLast("decoder", new ExpiredTokenDecoder());
            pipeline.addLast("handler", new FeedbackClientHandler(feedbackClient));
        }

    });

    final ChannelFuture connectFuture = bootstrap
            .connect(this.environment.getFeedbackHost(), this.environment.getFeedbackPort()).await();

    if (connectFuture.isSuccess()) {
        log.debug("Connected to feedback service.");

        final SslHandler sslHandler = connectFuture.channel().pipeline().get(SslHandler.class);

        if (sslHandler != null) {
            final Future<Channel> handshakeFuture = sslHandler.handshakeFuture().await();

            if (handshakeFuture.isSuccess()) {
                log.debug("Completed TLS handshake with feedback service.");

                // The feedback service will send us a list of device tokens as soon as we complete the SSL
                // handshake, then hang up. While we're waiting to sync with the connection closure, we'll be
                // receiving messages from the feedback service from another thread.
                connectFuture.channel().closeFuture().await();
            } else {
                log.debug("Failed to complete TLS handshake with feedback service.", handshakeFuture.cause());

                connectFuture.channel().close().await();
                throw new FeedbackConnectionException(handshakeFuture.cause());
            }
        } else {
            log.warn("Feedback client failed to get SSL handler and could not wait for TLS handshake.");

            connectFuture.channel().close().await();
            throw new FeedbackConnectionException(null);
        }
    } else {
        log.debug("Failed to connect to feedback service.", connectFuture.cause());
        throw new FeedbackConnectionException(connectFuture.cause());
    }

    return new ArrayList<ExpiredToken>(this.expiredTokens);
}

From source file:com.relayrides.pushy.apns.FeedbackServiceConnection.java

License:Open Source License

/**
 * <p>Connects to the APNs feedback service and waits for expired tokens to arrive. Be warned that this is a
 * <strong>destructive operation</strong>. According to Apple's documentation:</p>
 *
 * <blockquote>The feedback service's list is cleared after you read it. Each time you connect to the feedback
 * service, the information it returns lists only the failures that have happened since you last
 * connected.</blockquote>/*from  w  w  w  . j  a v  a2 s.  c  o m*/
 */
public synchronized void connect() {

    if (this.connectFuture != null) {
        throw new IllegalStateException(String.format("%s already started a connection attempt.", this.name));
    }

    final Bootstrap bootstrap = new Bootstrap();
    bootstrap.group(this.eventLoopGroup);
    bootstrap.channel(NioSocketChannel.class);

    final FeedbackServiceConnection feedbackConnection = this;
    bootstrap.handler(new ChannelInitializer<SocketChannel>() {

        @Override
        protected void initChannel(final SocketChannel channel) throws Exception {
            final ChannelPipeline pipeline = channel.pipeline();

            final SSLEngine sslEngine = feedbackConnection.sslContext.createSSLEngine();
            sslEngine.setUseClientMode(true);

            pipeline.addLast("ssl", new SslHandler(sslEngine));
            pipeline.addLast("readTimeoutHandler",
                    new ReadTimeoutHandler(feedbackConnection.configuration.getReadTimeout()));
            pipeline.addLast("decoder", new ExpiredTokenDecoder());
            pipeline.addLast("handler", new FeedbackClientHandler(feedbackConnection));
        }
    });

    this.connectFuture = bootstrap.connect(this.environment.getFeedbackHost(),
            this.environment.getFeedbackPort());
    this.connectFuture.addListener(new GenericFutureListener<ChannelFuture>() {

        @Override
        public void operationComplete(final ChannelFuture connectFuture) {

            if (connectFuture.isSuccess()) {
                log.debug("{} connected; waiting for TLS handshake.", feedbackConnection.name);

                final SslHandler sslHandler = connectFuture.channel().pipeline().get(SslHandler.class);

                try {
                    sslHandler.handshakeFuture().addListener(new GenericFutureListener<Future<Channel>>() {

                        @Override
                        public void operationComplete(final Future<Channel> handshakeFuture) {
                            if (handshakeFuture.isSuccess()) {
                                log.debug("{} successfully completed TLS handshake.", feedbackConnection.name);

                                if (feedbackConnection.listener != null) {
                                    feedbackConnection.listener.handleConnectionSuccess(feedbackConnection);
                                }

                            } else {
                                log.debug("{} failed to complete TLS handshake with APNs feedback service.",
                                        feedbackConnection.name, handshakeFuture.cause());

                                connectFuture.channel().close();

                                if (feedbackConnection.listener != null) {
                                    feedbackConnection.listener.handleConnectionFailure(feedbackConnection,
                                            handshakeFuture.cause());
                                }
                            }
                        }
                    });
                } catch (NullPointerException e) {
                    log.warn("{} failed to get SSL handler and could not wait for a TLS handshake.",
                            feedbackConnection.name);

                    connectFuture.channel().close();

                    if (feedbackConnection.listener != null) {
                        feedbackConnection.listener.handleConnectionFailure(feedbackConnection, e);
                    }
                }
            } else {
                log.debug("{} failed to connect to APNs feedback service.", feedbackConnection.name,
                        connectFuture.cause());

                if (feedbackConnection.listener != null) {
                    feedbackConnection.listener.handleConnectionFailure(feedbackConnection,
                            connectFuture.cause());
                }
            }
        }
    });
}

From source file:com.repo.netty.proxy.HexDumpProxyFrontendHandler.java

License:Apache License

@Override
public void channelActive(ChannelHandlerContext ctx) {
    final Channel inboundChannel = ctx.channel();

    // Start the connection attempt.
    Bootstrap b = new Bootstrap();
    b.group(inboundChannel.eventLoop()).channel(ctx.channel().getClass())
            .handler(new HexDumpProxyBackendHandler(inboundChannel)).option(ChannelOption.AUTO_READ, false);
    ChannelFuture f = b.connect(remoteHost, remotePort);
    outboundChannel = f.channel();//from   w  w  w .j  a  va  2  s .  co m
    f.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) {
            if (future.isSuccess()) {
                // connection complete start to read first data
                inboundChannel.read();
            } else {
                // Close the connection if the connection attempt has failed.
                inboundChannel.close();
            }
        }
    });
}

From source file:com.sangupta.swift.netty.proxy.ProxyBackendHandler.java

License:Apache License

@Override
public void channelRead(final ChannelHandlerContext channelHandlerContext, Object message) {
    inboundChannel.writeAndFlush(message).addListener(new ChannelFutureListener() {

        @Override/*from   ww  w  .  j  a va2 s. c  o m*/
        public void operationComplete(ChannelFuture future) {
            if (future.isSuccess()) {
                channelHandlerContext.channel().read();
            } else {
                future.channel().close();
            }
        }

    });
}