Example usage for io.netty.channel ChannelPromise addListener

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

Introduction

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

Prototype

@Override
    ChannelPromise addListener(GenericFutureListener<? extends Future<? super Void>> listener);

Source Link

Usage

From source file:org.apache.dubbo.remoting.transport.netty4.NettyClientHandler.java

License:Apache License

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
    super.write(ctx, msg, promise);
    final NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);
    final boolean isRequest = msg instanceof Request;

    // We add listeners to make sure our out bound event is correct.
    // If our out bound event has an error (in most cases the encoder fails),
    // we need to have the request return directly instead of blocking the invoke process.
    promise.addListener(future -> {
        try {//from  w  w w  .  jav  a  2s .co m
            if (future.isSuccess()) {
                // if our future is success, mark the future to sent.
                handler.sent(channel, msg);
                return;
            }

            Throwable t = future.cause();
            if (t != null && isRequest) {
                Request request = (Request) msg;
                Response response = buildErrorResponse(request, t);
                handler.received(channel, response);
            }
        } finally {
            NettyChannel.removeChannelIfDisconnected(ctx.channel());
        }
    });
}

From source file:org.apache.hyracks.http.server.HttpRequestCapacityController.java

License:Apache License

public static void reject(ChannelHandlerContext ctx) {
    HttpResponseEncoder encoder = new HttpResponseEncoder();
    ChannelPromise promise = ctx.newPromise();
    promise.addListener(ChannelFutureListener.CLOSE);
    DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
            HttpResponseStatus.SERVICE_UNAVAILABLE);
    try {//from  ww  w. j  a  va2s.  c o m
        encoder.write(ctx, response, ctx.voidPromise());
        ctx.writeAndFlush(ctx.alloc().buffer(0), promise);
    } catch (Throwable th) {//NOSONAR
        try {
            LOGGER.log(Level.SEVERE, "Failure during request rejection", th);
        } catch (Throwable loggingFailure) {//NOSONAR
        }
        PromiseNotificationUtil.tryFailure(promise, th, null);
    }
}

From source file:org.apache.tinkerpop.gremlin.driver.Connection.java

License:Apache License

private synchronized void shutdown(final CompletableFuture<Void> future) {
    // shutdown can be called directly from closeAsync() or after write() and therefore this method should only
    // be called once. once shutdown is initiated, it shouldn't be executed a second time or else it sends more
    // messages at the server and leads to ugly log messages over there.
    if (shutdownInitiated.compareAndSet(false, true)) {
        // maybe this should be delegated back to the Client implementation??? kinda weird to instanceof here.....
        if (client instanceof Client.SessionedClient) {
            final boolean forceClose = client.getSettings().getSession().get().isForceClosed();
            final RequestMessage closeMessage = client
                    .buildMessage(RequestMessage.build(Tokens.OPS_CLOSE).addArg(Tokens.ARGS_FORCE, forceClose))
                    .create();/*from ww w . j a v  a 2 s .  com*/

            final CompletableFuture<ResultSet> closed = new CompletableFuture<>();
            write(closeMessage, closed);

            try {
                // make sure we get a response here to validate that things closed as expected.  on error, we'll let
                // the server try to clean up on its own.  the primary error here should probably be related to
                // protocol issues which should not be something a user has to fuss with.
                closed.join().all().get(cluster.connectionPoolSettings().maxWaitForSessionClose,
                        TimeUnit.MILLISECONDS);
            } catch (TimeoutException ex) {
                final String msg = String.format(
                        "Timeout while trying to close connection on %s - force closing - server will close session on shutdown or expiration.",
                        ((Client.SessionedClient) client).getSessionId());
                logger.warn(msg, ex);
            } catch (Exception ex) {
                final String msg = String.format(
                        "Encountered an error trying to close connection on %s - force closing - server will close session on shutdown or expiration.",
                        ((Client.SessionedClient) client).getSessionId());
                logger.warn(msg, ex);
            }
        }

        channelizer.close(channel);

        final ChannelPromise promise = channel.newPromise();
        promise.addListener(f -> {
            if (f.cause() != null)
                future.completeExceptionally(f.cause());
            else
                future.complete(null);
        });

        channel.close(promise);
    }
}

From source file:org.apache.tinkerpop.gremlin.server.handler.HttpGremlinEndpointHandler.java

License:Apache License

@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
    if (msg instanceof FullHttpRequest) {
        final FullHttpRequest req = (FullHttpRequest) msg;

        if ("/favicon.ico".equals(req.getUri())) {
            sendError(ctx, NOT_FOUND, "Gremlin Server doesn't have a favicon.ico");
            ReferenceCountUtil.release(msg);
            return;
        }//from w w w .  j  av a  2 s .co  m

        if (is100ContinueExpected(req)) {
            ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
        }

        if (req.getMethod() != GET && req.getMethod() != POST) {
            sendError(ctx, METHOD_NOT_ALLOWED, METHOD_NOT_ALLOWED.toString());
            ReferenceCountUtil.release(msg);
            return;
        }

        final Quartet<String, Map<String, Object>, String, Map<String, String>> requestArguments;
        try {
            requestArguments = getRequestArguments(req);
        } catch (IllegalArgumentException iae) {
            sendError(ctx, BAD_REQUEST, iae.getMessage());
            ReferenceCountUtil.release(msg);
            return;
        }

        final String acceptString = Optional.ofNullable(req.headers().get("Accept")).orElse("application/json");
        final Pair<String, MessageTextSerializer> serializer = chooseSerializer(acceptString);
        if (null == serializer) {
            sendError(ctx, BAD_REQUEST,
                    String.format("no serializer for requested Accept header: %s", acceptString));
            ReferenceCountUtil.release(msg);
            return;
        }

        final String origin = req.headers().get(ORIGIN);
        final boolean keepAlive = isKeepAlive(req);

        // not using the req any where below here - assume it is safe to release at this point.
        ReferenceCountUtil.release(msg);

        try {
            logger.debug("Processing request containing script [{}] and bindings of [{}] on {}",
                    requestArguments.getValue0(), requestArguments.getValue1(),
                    Thread.currentThread().getName());
            final ChannelPromise promise = ctx.channel().newPromise();
            final AtomicReference<Object> resultHolder = new AtomicReference<>();
            promise.addListener(future -> {
                // if failed then the error was already written back to the client as part of the eval future
                // processing of the exception
                if (future.isSuccess()) {
                    logger.debug(
                            "Preparing HTTP response for request with script [{}] and bindings of [{}] with result of [{}] on [{}]",
                            requestArguments.getValue0(), requestArguments.getValue1(), resultHolder.get(),
                            Thread.currentThread().getName());
                    final FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK,
                            (ByteBuf) resultHolder.get());
                    response.headers().set(CONTENT_TYPE, serializer.getValue0());
                    response.headers().set(CONTENT_LENGTH, response.content().readableBytes());

                    // handle cors business
                    if (origin != null)
                        response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN, origin);

                    if (!keepAlive) {
                        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
                    } else {
                        response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
                        ctx.writeAndFlush(response);
                    }
                }
            });

            final Timer.Context timerContext = evalOpTimer.time();

            final Bindings bindings;
            try {
                bindings = createBindings(requestArguments.getValue1(), requestArguments.getValue3());
            } catch (IllegalStateException iae) {
                sendError(ctx, BAD_REQUEST, iae.getMessage());
                ReferenceCountUtil.release(msg);
                return;
            }

            // provide a transform function to serialize to message - this will force serialization to occur
            // in the same thread as the eval. after the CompletableFuture is returned from the eval the result
            // is ready to be written as a ByteBuf directly to the response.  nothing should be blocking here.
            final CompletableFuture<Object> evalFuture = gremlinExecutor.eval(requestArguments.getValue0(),
                    requestArguments.getValue2(), bindings, FunctionUtils.wrapFunction(o -> {
                        // stopping the timer here is roughly equivalent to where the timer would have been stopped for
                        // this metric in other contexts.  we just want to measure eval time not serialization time.
                        timerContext.stop();

                        logger.debug(
                                "Transforming result of request with script [{}] and bindings of [{}] with result of [{}] on [{}]",
                                requestArguments.getValue0(), requestArguments.getValue1(), o,
                                Thread.currentThread().getName());
                        final ResponseMessage responseMessage = ResponseMessage.build(UUID.randomUUID())
                                .code(ResponseStatusCode.SUCCESS).result(IteratorUtils.asList(o)).create();

                        // http server is sessionless and must handle commit on transactions. the commit occurs
                        // before serialization to be consistent with how things work for websocket based
                        // communication.  this means that failed serialization does not mean that you won't get
                        // a commit to the database
                        attemptCommit(requestArguments.getValue3(), graphManager,
                                settings.strictTransactionManagement);

                        try {
                            return Unpooled.wrappedBuffer(serializer.getValue1()
                                    .serializeResponseAsString(responseMessage).getBytes(UTF8));
                        } catch (Exception ex) {
                            logger.warn(String.format("Error during serialization for %s", responseMessage),
                                    ex);
                            throw ex;
                        }
                    }));

            evalFuture.exceptionally(t -> {
                if (t.getMessage() != null)
                    sendError(ctx, INTERNAL_SERVER_ERROR, t.getMessage(), Optional.of(t));
                else
                    sendError(ctx, INTERNAL_SERVER_ERROR, String
                            .format("Error encountered evaluating script: %s", requestArguments.getValue0()),
                            Optional.of(t));
                promise.setFailure(t);
                return null;
            });

            evalFuture.thenAcceptAsync(r -> {
                // now that the eval/serialization is done in the same thread - complete the promise so we can
                // write back the HTTP response on the same thread as the original request
                resultHolder.set(r);
                promise.setSuccess();
            }, gremlinExecutor.getExecutorService());
        } catch (Exception ex) {
            // tossed to exceptionCaught which delegates to sendError method
            final Throwable t = ExceptionUtils.getRootCause(ex);
            throw new RuntimeException(null == t ? ex : t);
        }
    }
}

From source file:org.ballerinalang.test.util.websocket.server.WebSocketHeadersHandler.java

License:Open Source License

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
    if (msg instanceof HttpResponse) {
        HttpResponse response = (HttpResponse) msg;
        response.headers().add("X-server-header", "server-header-value");
        promise.addListener(future -> ctx.pipeline().remove(ctx.name()));
    }/*from www .j  a  v a2s.c  om*/
    super.write(ctx, msg, promise);
}

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

License:Open Source License

@Override
public void writeTo(ChannelHandlerContext ctx, final ChannelPromise promise) {
    try {/* ww  w.j a  va2s .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();
    }
}

From source file:org.elasticsearch.hadoop.http.netty4.Netty4HttpChannel.java

License:Apache License

@Override
public void sendResponse(RestResponse response) {
    // if the response object was created upstream, then use it;
    // otherwise, create a new one
    ByteBuf buffer = Netty4Utils.toByteBuf(response.content());
    FullHttpResponse resp = newResponse(buffer);
    resp.setStatus(getStatus(response.status()));

    Netty4CorsHandler.setCorsResponseHeaders(nettyRequest, resp, transport.getCorsConfig());

    String opaque = nettyRequest.headers().get("X-Opaque-Id");
    if (opaque != null) {
        setHeaderField(resp, "X-Opaque-Id", opaque);
    }//from   ww w .j a v a2 s .  co m

    // Add all custom headers
    addCustomHeaders(resp, response.getHeaders());
    addCustomHeaders(resp, threadContext.getResponseHeaders());

    BytesReference content = response.content();
    boolean release = content instanceof Releasable;
    try {
        // If our response doesn't specify a content-type header, set one
        setHeaderField(resp, HttpHeaderNames.CONTENT_TYPE.toString(), response.contentType(), false);
        // If our response has no content-length, calculate and set one
        setHeaderField(resp, HttpHeaderNames.CONTENT_LENGTH.toString(), String.valueOf(buffer.readableBytes()),
                false);

        addCookies(resp);

        final ChannelPromise promise = channel.newPromise();

        if (release) {
            promise.addListener(f -> ((Releasable) content).close());
            release = false;
        }

        if (isCloseConnection()) {
            promise.addListener(ChannelFutureListener.CLOSE);
        }

        if (pipelinedRequest != null) {
            channel.writeAndFlush(pipelinedRequest.createHttpResponse(resp, promise));
        } else {
            channel.writeAndFlush(resp, promise);
        }

    } finally {
        if (release) {
            ((Releasable) content).close();
        }
        if (pipelinedRequest != null) {
            pipelinedRequest.release();
        }
    }
}

From source file:org.elasticsearch.hadoop.transport.netty4.Netty4MessageChannelHandler.java

License:Apache License

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
    if (msg instanceof ByteBuf && transportServiceAdapter != null) {
        // record the number of bytes send on the channel
        promise.addListener(f -> transportServiceAdapter.addBytesSent(((ByteBuf) msg).readableBytes()));
    }//ww  w .j  a  v a2  s. c  o  m
    ctx.write(msg, promise);
}

From source file:org.elasticsearch.http.nio.NettyAdaptor.java

License:Apache License

NettyAdaptor(ChannelHandler... handlers) {
    nettyChannel = new EmbeddedChannel();
    nettyChannel.pipeline().addLast("write_captor", new ChannelOutboundHandlerAdapter() {

        @Override//w w  w .  j a  v  a 2  s . co  m
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
            // This is a little tricky. The embedded channel will complete the promise once it writes the message
            // to its outbound buffer. We do not want to complete the promise until the message is sent. So we
            // intercept the promise and pass a different promise back to the rest of the pipeline.

            try {
                ByteBuf message = (ByteBuf) msg;
                promise.addListener((f) -> message.release());
                NettyListener listener = NettyListener.fromChannelPromise(promise);
                flushOperations.add(new FlushOperation(message.nioBuffers(), listener));
            } catch (Exception e) {
                promise.setFailure(e);
            }
        }
    });
    nettyChannel.pipeline().addLast(handlers);
}

From source file:org.elasticsearch.http.nio.NettyListener.java

License:Apache License

public static NettyListener fromBiConsumer(BiConsumer<Void, Exception> biConsumer, Channel channel) {
    if (biConsumer instanceof NettyListener) {
        return (NettyListener) biConsumer;
    } else {//from  ww  w.  j av  a2 s  .  c om
        ChannelPromise channelPromise = channel.newPromise();
        channelPromise.addListener(f -> {
            Throwable cause = f.cause();
            if (cause == null) {
                biConsumer.accept(null, null);
            } else {
                if (cause instanceof Error) {
                    ExceptionsHelper.dieOnError(cause);
                    biConsumer.accept(null, new Exception(cause));
                } else {
                    biConsumer.accept(null, (Exception) cause);
                }
            }
        });

        return new NettyListener(channelPromise);
    }
}