Example usage for io.netty.channel ChannelPromise tryFailure

List of usage examples for io.netty.channel ChannelPromise tryFailure

Introduction

In this page you can find the example usage for io.netty.channel ChannelPromise tryFailure.

Prototype

boolean tryFailure(Throwable cause);

Source Link

Document

Marks this future as a failure and notifies all listeners.

Usage

From source file:com.linecorp.armeria.client.http.HttpClientPipelineConfigurator.java

License:Apache License

@Override
public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress,
        ChannelPromise promise) throws Exception {

    // Remember the requested remote address for later use.
    this.remoteAddress = (InetSocketAddress) remoteAddress;

    // Configure the pipeline.
    final Channel ch = ctx.channel();

    final ChannelPipeline p = ch.pipeline();
    p.addLast(new FlushConsolidationHandler());
    p.addLast(ReadSuppressingHandler.INSTANCE);

    try {/*  w  w w  .  j  a v a 2s  .  com*/
        if (sslCtx != null) {
            configureAsHttps(ch);
        } else {
            configureAsHttp(ch);
        }
    } catch (Throwable t) {
        promise.tryFailure(t);
        ctx.close();
    } finally {
        if (p.context(this) != null) {
            p.remove(this);
        }
    }

    ctx.connect(remoteAddress, localAddress, promise);
}

From source file:com.linecorp.armeria.client.HttpClientPipelineConfigurator.java

License:Apache License

@Override
public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress,
        ChannelPromise promise) throws Exception {

    // Remember the requested remote address for later use.
    final InetSocketAddress inetRemoteAddr = (InetSocketAddress) remoteAddress;
    this.remoteAddress = inetRemoteAddr;

    // Configure the pipeline.
    final Channel ch = ctx.channel();

    final ChannelPipeline p = ch.pipeline();
    p.addLast(new FlushConsolidationHandler());
    p.addLast(ReadSuppressingHandler.INSTANCE);

    try {/*w  w  w. ja  v  a2s . co m*/
        if (sslCtx != null) {
            configureAsHttps(ch, inetRemoteAddr);
        } else {
            configureAsHttp(ch);
        }
    } catch (Throwable t) {
        promise.tryFailure(t);
        ctx.close();
    } finally {
        if (p.context(this) != null) {
            p.remove(this);
        }
    }

    ctx.connect(remoteAddress, localAddress, promise);
}

From source file:com.linecorp.armeria.client.HttpConfigurator.java

License:Apache License

@Override
public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress,
        ChannelPromise promise) throws Exception {

    // Remember the requested remote address for later use.
    this.remoteAddress = (InetSocketAddress) remoteAddress;

    // Configure the pipeline.
    final Channel ch = ctx.channel();
    try {/* w  w w  . java 2  s  .  c  om*/
        if (sslCtx != null) {
            configureAsHttps(ch);
        } else {
            configureAsHttp(ch);
        }
    } catch (Throwable t) {
        promise.tryFailure(t);
        ctx.close();
    } finally {
        final ChannelPipeline pipeline = ch.pipeline();
        if (pipeline.context(this) != null) {
            pipeline.remove(this);
        }
    }

    ctx.connect(remoteAddress, localAddress, promise);
}

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 w w  . j  av a  2  s .co 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.ApnsClientHandler.java

License:Open Source License

@Override
public void write(final ChannelHandlerContext context, final Object message, final ChannelPromise writePromise)
        throws Http2Exception {
    if (message instanceof PushNotificationAndResponsePromise) {
        final PushNotificationAndResponsePromise pushNotificationAndResponsePromise = (PushNotificationAndResponsePromise) message;

        final ApnsPushNotification pushNotification = pushNotificationAndResponsePromise.getPushNotification();

        if (this.responsePromises.containsKey(pushNotification)) {
            writePromise.tryFailure(new PushNotificationStillPendingException());
        } else {//  w  w w . j ava  2  s  .c o m
            this.responsePromises.put(pushNotification,
                    pushNotificationAndResponsePromise.getResponsePromise());

            pushNotificationAndResponsePromise.getResponsePromise().addListener(
                    new GenericFutureListener<Future<PushNotificationResponse<ApnsPushNotification>>>() {

                        @Override
                        public void operationComplete(
                                final Future<PushNotificationResponse<ApnsPushNotification>> future) {
                            // Regardless of the outcome, when the response promise is finished, we want to remove it from
                            // the map of pending promises.
                            ApnsClientHandler.this.responsePromises.remove(pushNotification);
                        }
                    });

            this.write(context, pushNotification, writePromise);
        }
    } else if (message instanceof ApnsPushNotification) {
        final ApnsPushNotification pushNotification = (ApnsPushNotification) message;

        try {
            final int streamId = (int) this.nextStreamId;

            final Http2Headers headers = new DefaultHttp2Headers().method(HttpMethod.POST.asciiName())
                    .authority(this.authority).path(APNS_PATH_PREFIX + pushNotification.getToken())
                    .addInt(APNS_EXPIRATION_HEADER, pushNotification.getExpiration() == null ? 0
                            : (int) (pushNotification.getExpiration().getTime() / 1000));

            final String authenticationToken = this.apnsClient
                    .getAuthenticationTokenSupplierForTopic(pushNotification.getTopic()).getToken();
            headers.add(APNS_AUTHORIZATION_HEADER, "bearer " + authenticationToken);

            if (pushNotification.getCollapseId() != null) {
                headers.add(APNS_COLLAPSE_ID_HEADER, pushNotification.getCollapseId());
            }

            if (pushNotification.getPriority() != null) {
                headers.addInt(APNS_PRIORITY_HEADER, pushNotification.getPriority().getCode());
            }

            if (pushNotification.getTopic() != null) {
                headers.add(APNS_TOPIC_HEADER, pushNotification.getTopic());
            }

            final ChannelPromise headersPromise = context.newPromise();
            this.encoder().writeHeaders(context, streamId, headers, 0, false, headersPromise);
            log.trace("Wrote headers on stream {}: {}", streamId, headers);

            final ByteBuf payloadBuffer = context.alloc().ioBuffer(INITIAL_PAYLOAD_BUFFER_CAPACITY);
            payloadBuffer.writeBytes(pushNotification.getPayload().getBytes(StandardCharsets.UTF_8));

            final ChannelPromise dataPromise = context.newPromise();
            this.encoder().writeData(context, streamId, payloadBuffer, 0, true, dataPromise);
            log.trace("Wrote payload on stream {}: {}", streamId, pushNotification.getPayload());

            final PromiseCombiner promiseCombiner = new PromiseCombiner();
            promiseCombiner.addAll(headersPromise, dataPromise);
            promiseCombiner.finish(writePromise);

            writePromise.addListener(new GenericFutureListener<ChannelPromise>() {

                @Override
                public void operationComplete(final ChannelPromise future) throws Exception {
                    if (future.isSuccess()) {
                        ApnsClientHandler.this.pushNotificationsByStreamId.put(streamId, pushNotification);
                        ApnsClientHandler.this.authenticationTokensByStreamId.put(streamId,
                                authenticationToken);
                    } else {
                        log.trace("Failed to write push notification on stream {}.", streamId, future.cause());

                        final Promise<PushNotificationResponse<ApnsPushNotification>> responsePromise = ApnsClientHandler.this.responsePromises
                                .get(pushNotification);

                        if (responsePromise != null) {
                            responsePromise.tryFailure(future.cause());
                        } else {
                            log.error("Notification write failed, but no response promise found.");
                        }
                    }
                }
            });

            this.nextStreamId += 2;

            if (this.nextStreamId >= STREAM_ID_RESET_THRESHOLD) {
                // This is very unlikely, but in the event that we run out of stream IDs (the maximum allowed is
                // 2^31, per https://httpwg.github.io/specs/rfc7540.html#StreamIdentifiers), we need to open a new
                // connection. Just closing the context should be enough; automatic reconnection should take things
                // from there.
                context.close();
            }
        } catch (NoKeyForTopicException | SignatureException e) {
            writePromise.tryFailure(e);
        }

    } else {
        // This should never happen, but in case some foreign debris winds up in the pipeline, just pass it through.
        log.error("Unexpected object in pipeline: {}", message);
        context.write(message, writePromise);
    }
}

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

License:Open Source License

private void writePushNotification(final ChannelHandlerContext context,
        final PushNotificationPromise responsePromise, final ChannelPromise writePromise) {
    if (context.channel().isActive()) {
        final int streamId = this.connection().local().incrementAndGetNextStreamId();

        if (streamId > 0) {
            // We'll attach the push notification and response promise to the stream as soon as the stream is created.
            // Because we're using a StreamBufferingEncoder under the hood, there's no guarantee as to when the stream
            // will actually be created, and so we attach these in the onStreamAdded listener to make sure everything
            // is happening in a predictable order.
            this.unattachedResponsePromisesByStreamId.put(streamId, responsePromise);
            final ApnsPushNotification pushNotification = responsePromise.getPushNotification();

            final Http2Headers headers = getHeadersForPushNotification(pushNotification, streamId);

            final ChannelPromise headersPromise = context.newPromise();
            this.encoder().writeHeaders(context, streamId, headers, 0, false, headersPromise);
            log.trace("Wrote headers on stream {}: {}", streamId, headers);

            final ByteBuf payloadBuffer = context.alloc().ioBuffer(INITIAL_PAYLOAD_BUFFER_CAPACITY);
            payloadBuffer.writeBytes(pushNotification.getPayload().getBytes(StandardCharsets.UTF_8));

            final ChannelPromise dataPromise = context.newPromise();
            this.encoder().writeData(context, streamId, payloadBuffer, 0, true, dataPromise);
            log.trace("Wrote payload on stream {}: {}", streamId, pushNotification.getPayload());

            final PromiseCombiner promiseCombiner = new PromiseCombiner();
            promiseCombiner.addAll((ChannelFuture) headersPromise, dataPromise);
            promiseCombiner.finish(writePromise);

            writePromise.addListener(new GenericFutureListener<ChannelPromise>() {

                @Override//from  w w w.  j a v  a  2s  .c  o  m
                public void operationComplete(final ChannelPromise future) {
                    if (!future.isSuccess()) {
                        log.trace("Failed to write push notification on stream {}.", streamId, future.cause());
                        responsePromise.tryFailure(future.cause());
                    }
                }
            });
        } else {
            // This is very unlikely, but in the event that we run out of stream IDs, we need to open a new
            // connection. Just closing the context should be enough; automatic reconnection should take things
            // from there.
            writePromise.tryFailure(STREAMS_EXHAUSTED_EXCEPTION);
            context.channel().close();
        }
    } else {
        writePromise.tryFailure(STREAM_CLOSED_BEFORE_REPLY_EXCEPTION);
    }
}

From source file:divconq.net.ssl.SslHandler.java

License:Apache License

public ChannelFuture close(final ChannelPromise future) {
    final ChannelHandlerContext ctx = this.ctx;
    ctx.executor().execute(new Runnable() {
        @Override/*from  w  ww . ja v  a 2s  .  c o m*/
        public void run() {
            engine.closeOutbound();
            try {
                write(ctx, Unpooled.EMPTY_BUFFER, future);
                flush(ctx);
            } catch (Exception e) {
                if (!future.tryFailure(e)) {
                    logger.warn("flush() raised a masked exception.", e);
                }
            }
        }
    });

    return future;
}

From source file:io.lettuce.core.protocol.ReconnectionHandler.java

License:Apache License

private void reconnect0(CompletableFuture<Channel> result, SocketAddress remoteAddress) {

    ChannelFuture connectFuture = bootstrap.connect(remoteAddress);
    ChannelPromise initFuture = connectFuture.channel().newPromise();

    logger.debug("Reconnecting to Redis at {}", remoteAddress);

    result.whenComplete((c, t) -> {//from  w w w . j  a v  a2  s. c  o m

        if (t instanceof CancellationException) {
            connectFuture.cancel(true);
            initFuture.cancel(true);
        }
    });

    initFuture.addListener((ChannelFuture it) -> {

        if (it.cause() != null) {

            connectFuture.cancel(true);
            close(it.channel());
            result.completeExceptionally(it.cause());
        } else {
            result.complete(connectFuture.channel());
        }
    });

    connectFuture.addListener((ChannelFuture it) -> {

        if (it.cause() != null) {

            initFuture.tryFailure(it.cause());
            return;
        }

        ChannelPipeline pipeline = it.channel().pipeline();
        RedisChannelInitializer channelInitializer = pipeline.get(RedisChannelInitializer.class);

        if (channelInitializer == null) {

            initFuture.tryFailure(new IllegalStateException(
                    "Reconnection attempt without a RedisChannelInitializer in the channel pipeline"));
            return;
        }

        channelInitializer.channelInitialized().whenComplete((state, throwable) -> {

            if (throwable != null) {

                if (isExecutionException(throwable)) {
                    initFuture.tryFailure(throwable);
                    return;
                }

                if (clientOptions.isCancelCommandsOnReconnectFailure()) {
                    connectionFacade.reset();
                }

                if (clientOptions.isSuspendReconnectOnProtocolFailure()) {

                    logger.error("Disabling autoReconnect due to initialization failure", throwable);
                    setReconnectSuspended(true);
                }

                initFuture.tryFailure(throwable);

                return;
            }

            if (logger.isDebugEnabled()) {
                logger.info("Reconnected to {}, Channel {}", remoteAddress,
                        ChannelLogDescriptor.logDescriptor(it.channel()));
            } else {
                logger.info("Reconnected to {}", remoteAddress);
            }

            initFuture.trySuccess();
        });
    });

    Runnable timeoutAction = () -> {
        initFuture.tryFailure(new TimeoutException(
                String.format("Reconnection attempt exceeded timeout of %d %s ", timeout, timeoutUnit)));
    };

    Timeout timeoutHandle = timer.newTimeout(it -> {

        if (connectFuture.isDone() && initFuture.isDone()) {
            return;
        }

        if (reconnectWorkers.isShutdown()) {
            timeoutAction.run();
            return;
        }

        reconnectWorkers.submit(timeoutAction);

    }, this.timeout, timeoutUnit);

    initFuture.addListener(it -> timeoutHandle.cancel());
}

From source file:io.reactivex.netty.protocol.http.client.ClientRequestResponseConverter.java

License:Apache License

private void writeContent(final ChannelHandlerContext ctx, final MultipleFutureListener allWritesListener,
        final Observable<?> contentSource, final ChannelPromise promise) {
    contentSource.subscribe(new Subscriber<Object>() {
        @Override/*from   w ww . j  av a2  s .c  om*/
        public void onCompleted() {
            writeAContentChunk(ctx, allWritesListener, new DefaultLastHttpContent());
        }

        @Override
        public void onError(Throwable e) {
            allWritesListener.cancelPendingFutures(true); // If fetching from content source failed, we should
                                                          // cancel pending writes and fail the write. The state of
                                                          // the connection is left to the writer to decide. Ideally
                                                          // it should be closed because what was written is
                                                          // non-deterministic
            promise.tryFailure(e);
        }

        @Override
        public void onNext(Object chunk) {
            writeAContentChunk(ctx, allWritesListener, chunk);
        }
    });
}

From source file:org.dcache.xrootd.protocol.messages.AsyncResponse.java

License:Open Source License

@Override
public void writeTo(ChannelHandlerContext ctx, final ChannelPromise promise) {
    try {/*from  www .  j ava2s.  c  o m*/
        int dlen = getDataLength();
        ByteBuf header = ctx.alloc().buffer(8 + dlen);
        try {
            header.writeShort(0);
            header.writeShort(kXR_attn);
            header.writeInt(dlen);
            header.writeInt(kXR_asynresp);
            header.writeInt(0);
        } catch (Error | RuntimeException t) {
            promise.setFailure(t);
            header.release();
            return;
        }
        ctx.write(header).addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (!future.isSuccess()) {
                    promise.tryFailure(future.cause());
                }
            }
        });

        ChannelPromise channelPromise = ctx.newPromise();
        channelPromise.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    promise.trySuccess();
                } else {
                    promise.tryFailure(future.cause());
                }
            }
        });
        ReferenceCountUtil.retain(response).writeTo(ctx, channelPromise);
    } finally {
        release();
    }
}