Example usage for io.netty.util.concurrent PromiseCombiner PromiseCombiner

List of usage examples for io.netty.util.concurrent PromiseCombiner PromiseCombiner

Introduction

In this page you can find the example usage for io.netty.util.concurrent PromiseCombiner PromiseCombiner.

Prototype

@Deprecated
public PromiseCombiner() 

Source Link

Document

Deprecated use PromiseCombiner#PromiseCombiner(EventExecutor) .

Usage

From source file:com.linkedin.r2.transport.http.client.Http2StreamCodec.java

License:Apache License

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
    if (!(msg instanceof RequestWithCallback)) {
        ctx.write(msg, promise);/*from w  w w .  j  a  va 2  s  .c o  m*/
        return;
    }

    Request request = ((RequestWithCallback) msg).request();
    Http2ConnectionEncoder encoder = encoder();
    int streamId = connection().local().incrementAndGetNextStreamId();
    if (request instanceof StreamRequest) {
        LOG.debug("Writing StreamRequest...");
        StreamRequest streamRequest = (StreamRequest) request;
        Http2Headers http2Headers = NettyRequestAdapter.toHttp2Headers(streamRequest);
        BufferedReader reader = new BufferedReader(ctx, encoder, streamId,
                ((RequestWithCallback) msg).handle());
        streamRequest.getEntityStream().setReader(reader);
        encoder.writeHeaders(ctx, streamId, http2Headers, NO_PADDING, NOT_END_STREAM, promise)
                .addListener(future -> reader.request());
        LOG.debug("Sent HTTP/2 HEADERS frame, stream={}, end={}, headers={}, padding={}bytes",
                new Object[] { streamId, NOT_END_STREAM, http2Headers.size(), NO_PADDING });
    } else if (request instanceof RestRequest) {
        LOG.debug("Writing RestRequest...");
        PromiseCombiner promiseCombiner = new PromiseCombiner();
        ChannelPromise headersPromise = ctx.channel().newPromise();
        ChannelPromise dataPromise = ctx.channel().newPromise();
        promiseCombiner.add(headersPromise);
        promiseCombiner.add(dataPromise);
        promiseCombiner.finish(promise);

        RestRequest restRequest = (RestRequest) request;
        Http2Headers headers = NettyRequestAdapter.toHttp2Headers(restRequest);
        encoder.writeHeaders(ctx, streamId, headers, NO_PADDING, NOT_END_STREAM, headersPromise);
        LOG.debug("Sent HTTP/2 HEADERS frame, stream={}, end={}, headers={}, padding={}bytes",
                new Object[] { streamId, NOT_END_STREAM, headers.size(), NO_PADDING });
        ByteBuf data = Unpooled.wrappedBuffer(restRequest.getEntity().asByteBuffer());
        encoder.writeData(ctx, streamId, data, NO_PADDING, END_STREAM, dataPromise);
        LOG.debug("Sent HTTP/2 DATA frame, stream={}, end={}, data={}bytes, padding={}bytes",
                new Object[] { streamId, END_STREAM, data.readableBytes(), NO_PADDING });
    } else {
        // Request type is not supported. Returns channel back to the pool and throws exception.
        ctx.fireChannelRead(((RequestWithCallback) msg).handle());
        throw new IllegalArgumentException("Request is neither StreamRequest or RestRequest");
    }

    // Sets TransportCallback as a stream property to be retrieved later
    TransportCallback<?> callback = ((RequestWithCallback) msg).callback();
    Http2Connection.PropertyKey callbackKey = ctx.channel()
            .attr(Http2ClientPipelineInitializer.CALLBACK_ATTR_KEY).get();
    connection().stream(streamId).setProperty(callbackKey, callback);

    // Sets AsyncPoolHandle as a stream property to be retrieved later
    AsyncPoolHandle<?> handle = ((RequestWithCallback) msg).handle();
    Http2Connection.PropertyKey handleKey = ctx.channel()
            .attr(Http2ClientPipelineInitializer.CHANNEL_POOL_HANDLE_ATTR_KEY).get();
    connection().stream(streamId).setProperty(handleKey, handle);
}

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 {//from   w w  w .  j a v a  2  s. co 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.AbstractClientServerTest.java

License:Open Source License

@AfterClass
public static void tearDownAfterClass() throws Exception {
    final PromiseCombiner combiner = new PromiseCombiner();
    combiner.addAll(CLIENT_EVENT_LOOP_GROUP.shutdownGracefully(), SERVER_EVENT_LOOP_GROUP.shutdownGracefully());

    final Promise<Void> shutdownPromise = new DefaultPromise<>(GlobalEventExecutor.INSTANCE);
    combiner.finish(shutdownPromise);/*from   ww  w  .  j  av  a  2 s.co  m*/
    shutdownPromise.await();
}

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

License:Open Source License

@Override
public void write(final ChannelHandlerContext context, final Object message, final ChannelPromise writePromise)
        throws Exception {
    if (message instanceof AcceptNotificationResponse) {
        final AcceptNotificationResponse acceptNotificationResponse = (AcceptNotificationResponse) message;
        this.encoder().writeHeaders(context, acceptNotificationResponse.getStreamId(), SUCCESS_HEADERS, 0, true,
                writePromise);//from   w  w  w  .  j  a  v a  2 s .c om

        log.trace("Accepted push notification on stream {}", acceptNotificationResponse.getStreamId());
    } else if (message instanceof RejectNotificationResponse) {
        final RejectNotificationResponse rejectNotificationResponse = (RejectNotificationResponse) message;

        final Http2Headers headers = new DefaultHttp2Headers();
        headers.status(rejectNotificationResponse.getErrorReason().getHttpResponseStatus().codeAsText());
        headers.add(HttpHeaderNames.CONTENT_TYPE, "application/json");

        if (rejectNotificationResponse.getApnsId() != null) {
            headers.add(APNS_ID_HEADER, rejectNotificationResponse.getApnsId().toString());
        }

        final byte[] payloadBytes;
        {
            final ErrorResponse errorResponse = new ErrorResponse(
                    rejectNotificationResponse.getErrorReason().getReasonText(),
                    rejectNotificationResponse.getTimestamp());

            payloadBytes = GSON.toJson(errorResponse).getBytes();
        }

        final ChannelPromise headersPromise = context.newPromise();
        this.encoder().writeHeaders(context, rejectNotificationResponse.getStreamId(), headers, 0, false,
                headersPromise);

        final ChannelPromise dataPromise = context.newPromise();
        this.encoder().writeData(context, rejectNotificationResponse.getStreamId(),
                Unpooled.wrappedBuffer(payloadBytes), 0, true, dataPromise);

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

        log.trace("Rejected push notification on stream {}: {}", rejectNotificationResponse.getStreamId(),
                rejectNotificationResponse.getErrorReason());
    } else if (message instanceof InternalServerErrorResponse) {
        final InternalServerErrorResponse internalServerErrorResponse = (InternalServerErrorResponse) message;

        final Http2Headers headers = new DefaultHttp2Headers();
        headers.status(HttpResponseStatus.INTERNAL_SERVER_ERROR.codeAsText());

        this.encoder().writeHeaders(context, internalServerErrorResponse.getStreamId(), headers, 0, true,
                writePromise);

        log.trace("Encountered an internal error on stream {}", internalServerErrorResponse.getStreamId());
    } else {
        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/*  ww w  .  j  av  a  2 s  . 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:com.turo.pushy.apns.server.MockApnsServerHandler.java

License:Open Source License

@Override
public void write(final ChannelHandlerContext context, final Object message,
        final ChannelPromise writePromise) {
    if (message instanceof AcceptNotificationResponse) {
        final AcceptNotificationResponse acceptNotificationResponse = (AcceptNotificationResponse) message;

        final Http2Headers headers = new DefaultHttp2Headers().status(HttpResponseStatus.OK.codeAsText())
                .add(APNS_ID_HEADER, FastUUID.toString(acceptNotificationResponse.getApnsId()));

        this.encoder().writeHeaders(context, acceptNotificationResponse.getStreamId(), headers, 0, true,
                writePromise);//  w  w  w. j  a  v a  2  s .c  om

        log.trace("Accepted push notification on stream {}", acceptNotificationResponse.getStreamId());
    } else if (message instanceof RejectNotificationResponse) {
        final RejectNotificationResponse rejectNotificationResponse = (RejectNotificationResponse) message;

        final Http2Headers headers = new DefaultHttp2Headers()
                .status(rejectNotificationResponse.getErrorReason().getHttpResponseStatus().codeAsText())
                .add(HttpHeaderNames.CONTENT_TYPE, "application/json")
                .add(APNS_ID_HEADER, FastUUID.toString(rejectNotificationResponse.getApnsId()));

        final byte[] payloadBytes;
        {
            final ErrorPayload errorPayload = new ErrorPayload(
                    rejectNotificationResponse.getErrorReason().getReasonText(),
                    rejectNotificationResponse.getTimestamp());

            payloadBytes = GSON.toJson(errorPayload).getBytes();
        }

        final ChannelPromise headersPromise = context.newPromise();
        this.encoder().writeHeaders(context, rejectNotificationResponse.getStreamId(), headers, 0, false,
                headersPromise);

        final ChannelPromise dataPromise = context.newPromise();
        this.encoder().writeData(context, rejectNotificationResponse.getStreamId(),
                Unpooled.wrappedBuffer(payloadBytes), 0, true, dataPromise);

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

        log.trace("Rejected push notification on stream {}: {}", rejectNotificationResponse.getStreamId(),
                rejectNotificationResponse.getErrorReason());
    } else {
        context.write(message, writePromise);
    }
}

From source file:org.apache.hadoop.hbase.ipc.NettyRpcDuplexHandler.java

License:Apache License

private void writeRequest(ChannelHandlerContext ctx, Call call, ChannelPromise promise) throws IOException {
    id2Call.put(call.id, call);/* ww  w.j  a  v a2  s  .co m*/
    ByteBuf cellBlock = cellBlockBuilder.buildCellBlock(codec, compressor, call.cells, ctx.alloc());
    CellBlockMeta cellBlockMeta;
    if (cellBlock != null) {
        CellBlockMeta.Builder cellBlockMetaBuilder = CellBlockMeta.newBuilder();
        cellBlockMetaBuilder.setLength(cellBlock.writerIndex());
        cellBlockMeta = cellBlockMetaBuilder.build();
    } else {
        cellBlockMeta = null;
    }
    RequestHeader requestHeader = IPCUtil.buildRequestHeader(call, cellBlockMeta);
    int sizeWithoutCellBlock = IPCUtil.getTotalSizeWhenWrittenDelimited(requestHeader, call.param);
    int totalSize = cellBlock != null ? sizeWithoutCellBlock + cellBlock.writerIndex() : sizeWithoutCellBlock;
    ByteBuf buf = ctx.alloc().buffer(sizeWithoutCellBlock + 4);
    buf.writeInt(totalSize);
    ByteBufOutputStream bbos = new ByteBufOutputStream(buf);
    requestHeader.writeDelimitedTo(bbos);
    if (call.param != null) {
        call.param.writeDelimitedTo(bbos);
    }
    if (cellBlock != null) {
        ChannelPromise withoutCellBlockPromise = ctx.newPromise();
        ctx.write(buf, withoutCellBlockPromise);
        ChannelPromise cellBlockPromise = ctx.newPromise();
        ctx.write(cellBlock, cellBlockPromise);
        PromiseCombiner combiner = new PromiseCombiner();
        combiner.addAll(withoutCellBlockPromise, cellBlockPromise);
        combiner.finish(promise);
    } else {
        ctx.write(buf, promise);
    }
}

From source file:org.apache.hadoop.hbase.security.CryptoAESWrapHandler.java

License:Apache License

@Override
public void flush(ChannelHandlerContext ctx) throws Exception {
    if (queue.isEmpty()) {
        return;/*from  www . j a  v  a  2 s.  co m*/
    }
    ByteBuf buf = null;
    try {
        ChannelPromise promise = ctx.newPromise();
        int readableBytes = queue.readableBytes();
        buf = queue.remove(readableBytes, promise);
        byte[] bytes = new byte[readableBytes];
        buf.readBytes(bytes);
        byte[] wrapperBytes = cryptoAES.wrap(bytes, 0, bytes.length);
        ChannelPromise lenPromise = ctx.newPromise();
        ctx.write(ctx.alloc().buffer(4).writeInt(wrapperBytes.length), lenPromise);
        ChannelPromise contentPromise = ctx.newPromise();
        ctx.write(Unpooled.wrappedBuffer(wrapperBytes), contentPromise);
        PromiseCombiner combiner = new PromiseCombiner();
        combiner.addAll(lenPromise, contentPromise);
        combiner.finish(promise);
        ctx.flush();
    } finally {
        if (buf != null) {
            ReferenceCountUtil.safeRelease(buf);
        }
    }
}

From source file:org.apache.hadoop.hbase.security.SaslWrapHandler.java

License:Apache License

@Override
public void flush(ChannelHandlerContext ctx) throws Exception {
    if (queue.isEmpty()) {
        return;/*  w  ww. j  a  v a  2 s.  c  o m*/
    }
    ByteBuf buf = null;
    try {
        ChannelPromise promise = ctx.newPromise();
        int readableBytes = queue.readableBytes();
        buf = queue.remove(readableBytes, promise);
        byte[] bytes = new byte[readableBytes];
        buf.readBytes(bytes);
        byte[] wrapperBytes = saslClient.wrap(bytes, 0, bytes.length);
        ChannelPromise lenPromise = ctx.newPromise();
        ctx.write(ctx.alloc().buffer(4).writeInt(wrapperBytes.length), lenPromise);
        ChannelPromise contentPromise = ctx.newPromise();
        ctx.write(Unpooled.wrappedBuffer(wrapperBytes), contentPromise);
        PromiseCombiner combiner = new PromiseCombiner();
        combiner.addAll(lenPromise, contentPromise);
        combiner.finish(promise);
        ctx.flush();
    } finally {
        if (buf != null) {
            ReferenceCountUtil.safeRelease(buf);
        }
    }
}