Example usage for io.netty.util ReferenceCountUtil retain

List of usage examples for io.netty.util ReferenceCountUtil retain

Introduction

In this page you can find the example usage for io.netty.util ReferenceCountUtil retain.

Prototype

@SuppressWarnings("unchecked")
public static <T> T retain(T msg) 

Source Link

Document

Try to call ReferenceCounted#retain() if the specified message implements ReferenceCounted .

Usage

From source file:cc.agentx.client.net.nio.XConnectHandler.java

License:Apache License

@Override
public void channelRead0(final ChannelHandlerContext ctx, final SocksCmdRequest request) throws Exception {
    boolean proxyMode = isAgentXNeeded(request.host());
    log.info("\tClient -> Proxy           \tTarget {}:{} [{}]", request.host(), request.port(),
            proxyMode ? "AGENTX" : "DIRECT");
    Promise<Channel> promise = ctx.executor().newPromise();
    promise.addListener(new FutureListener<Channel>() {
        @Override/*  w w  w. j  av  a2s .  c  om*/
        public void operationComplete(final Future<Channel> future) throws Exception {
            final Channel outboundChannel = future.getNow();
            if (future.isSuccess()) {
                ctx.channel().writeAndFlush(new SocksCmdResponse(SocksCmdStatus.SUCCESS, request.addressType()))
                        .addListener(channelFuture -> {
                            ByteBuf byteBuf = Unpooled.buffer();
                            request.encodeAsByteBuf(byteBuf);
                            if (byteBuf.hasArray()) {
                                byte[] xRequestBytes = new byte[byteBuf.readableBytes()];
                                byteBuf.getBytes(0, xRequestBytes);

                                if (proxyMode) {
                                    // handshaking to remote proxy
                                    xRequestBytes = requestWrapper.wrap(xRequestBytes);
                                    outboundChannel.writeAndFlush(Unpooled.wrappedBuffer(
                                            exposeRequest ? xRequestBytes : wrapper.wrap(xRequestBytes)));
                                }

                                // task handover
                                ReferenceCountUtil.retain(request); // auto-release? a trap?
                                ctx.pipeline().remove(XConnectHandler.this);
                                outboundChannel.pipeline().addLast(new XRelayHandler(ctx.channel(),
                                        proxyMode ? wrapper : rawWrapper, false));
                                ctx.pipeline().addLast(new XRelayHandler(outboundChannel,
                                        proxyMode ? wrapper : rawWrapper, true));
                            }
                        });
            } else {
                ctx.channel()
                        .writeAndFlush(new SocksCmdResponse(SocksCmdStatus.FAILURE, request.addressType()));

                if (ctx.channel().isActive()) {
                    ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
                }
            }
        }
    });

    String host = request.host();
    int port = request.port();
    if (host.equals(config.getConsoleDomain())) {
        host = "localhost";
        port = config.getConsolePort();
    } else if (proxyMode) {
        host = config.getServerHost();
        port = config.getServerPort();
    }

    // ping target
    bootstrap.group(ctx.channel().eventLoop()).channel(NioSocketChannel.class)
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000).option(ChannelOption.SO_KEEPALIVE, true)
            .handler(new XPingHandler(promise, System.currentTimeMillis())).connect(host, port)
            .addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (!future.isSuccess()) {
                        ctx.channel().writeAndFlush(
                                new SocksCmdResponse(SocksCmdStatus.FAILURE, request.addressType()));
                        if (ctx.channel().isActive()) {
                            ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
                        }
                    }
                }
            });
}

From source file:com.bloom.zerofs.rest.NettyMultipartRequest.java

License:Open Source License

/**
 * Adds content that will be decoded on a call to {@link #prepare()}.
 * </p>/*ww w .  j a v  a 2s.c  om*/
 * All content has to be added before {@link #prepare()} can be called.
 * @param httpContent the {@link HttpContent} that needs to be added.
 * @throws RestServiceException if request channel has been closed.
 */
@Override
public void addContent(HttpContent httpContent) throws RestServiceException {
    if (!isOpen()) {
        nettyMetrics.multipartRequestAlreadyClosedError.inc();
        throw new RestServiceException("The request has been closed and is not accepting content",
                RestServiceErrorCode.RequestChannelClosed);
    } else {
        rawRequestContents.add(ReferenceCountUtil.retain(httpContent));
    }
}

From source file:com.bloom.zerofs.rest.NettyMultipartRequest.java

License:Open Source License

/**
 * Processes a single decoded part in a multipart request. Exposes the data in the part either through the channel
 * itself (if it is the blob part) or via {@link #getArgs()}.
 * @param part the {@link InterfaceHttpData} that needs to be processed.
 * @throws RestServiceException if the request channel is closed, if there is more than one part of the same name, if
 *                              the size obtained from the headers does not match the actual size of the blob part or
 *                              if {@code part} is not of the expected type ({@link FileUpload}).
 *//*from  w w w.  j ava 2  s .c  o  m*/
private void processPart(InterfaceHttpData part) throws RestServiceException {
    if (part.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
        FileUpload fileUpload = (FileUpload) part;
        if (fileUpload.getName().equals(RestUtils.MultipartPost.BLOB_PART)) {
            // this is actual data.
            if (hasBlob) {
                nettyMetrics.repeatedPartsError.inc();
                throw new RestServiceException("Request has more than one " + RestUtils.MultipartPost.BLOB_PART,
                        RestServiceErrorCode.BadRequest);
            } else {
                hasBlob = true;
                if (fileUpload.length() != getSize()) {
                    nettyMetrics.multipartRequestSizeMismatchError.inc();
                    throw new RestServiceException("Request size [" + fileUpload.length()
                            + "] does not match Content-Length [" + getSize() + "]",
                            RestServiceErrorCode.BadRequest);
                } else {
                    contentLock.lock();
                    try {
                        if (isOpen()) {
                            requestContents.add(
                                    new DefaultHttpContent(ReferenceCountUtil.retain(fileUpload.content())));
                        } else {
                            nettyMetrics.multipartRequestAlreadyClosedError.inc();
                            throw new RestServiceException("Request is closed",
                                    RestServiceErrorCode.RequestChannelClosed);
                        }
                    } finally {
                        contentLock.unlock();
                    }
                }
            }
        } else {
            // this is any kind of data. (For Amber, this will be user metadata).
            // TODO: find a configurable way of rejecting unexpected file parts.
            String name = fileUpload.getName();
            if (allArgs.containsKey(name)) {
                nettyMetrics.repeatedPartsError.inc();
                throw new RestServiceException("Request already has a component named " + name,
                        RestServiceErrorCode.BadRequest);
            } else {
                ByteBuffer buffer = ByteBuffer.allocate(fileUpload.content().readableBytes());
                // TODO: Possible optimization - Upgrade ByteBufferReadableStreamChannel to take a list of ByteBuffer. This
                // TODO: will avoid the copy.
                fileUpload.content().readBytes(buffer);
                buffer.flip();
                allArgs.put(name, buffer);
            }
        }
    } else {
        nettyMetrics.unsupportedPartError.inc();
        throw new RestServiceException("Unexpected HTTP data", RestServiceErrorCode.BadRequest);
    }
}

From source file:com.bloom.zerofs.rest.NettyRequest.java

License:Open Source License

/**
 * Adds some content in the form of {@link HttpContent} to this RestRequest. This content will be available to read
 * through the read operations./*  w w w .  ja v  a 2  s  .  c  om*/
 * @param httpContent the {@link HttpContent} that needs to be added.
 * @throws IllegalStateException if content is being added when it is not expected (GET, DELETE, HEAD).
 * @throws RestServiceException if request channel has been closed.
 */
protected void addContent(HttpContent httpContent) throws RestServiceException {
    if (!getRestMethod().equals(RestMethod.POST)
            && (!(httpContent instanceof LastHttpContent) || httpContent.content().readableBytes() > 0)) {
        throw new IllegalStateException("There is no content expected for " + getRestMethod());
    } else {
        validateState(httpContent);
        contentLock.lock();
        try {
            if (!isOpen()) {
                nettyMetrics.requestAlreadyClosedError.inc();
                throw new RestServiceException("The request has been closed and is not accepting content",
                        RestServiceErrorCode.RequestChannelClosed);
            } else if (writeChannel != null) {
                writeContent(writeChannel, callbackWrapper, httpContent);
            } else {
                requestContents.add(ReferenceCountUtil.retain(httpContent));
            }
        } finally {
            contentLock.unlock();
        }
    }
}

From source file:com.bloom.zerofs.rest.NettyRequest.java

License:Open Source License

/**
 * Writes the data in the provided {@code httpContent} to the given {@code writeChannel}.
 * @param writeChannel the {@link AsyncWritableChannel} to write the data of {@code httpContent} to.
 * @param callbackWrapper the {@link ReadIntoCallbackWrapper} for the read operation.
 * @param httpContent the piece of {@link HttpContent} that needs to be written to the {@code writeChannel}.
 *//*from  w  ww  .  j  av a  2 s  .c  o  m*/
protected void writeContent(AsyncWritableChannel writeChannel, ReadIntoCallbackWrapper callbackWrapper,
        HttpContent httpContent) {
    boolean retained = false;
    ByteBuffer[] contentBuffers;
    Callback<Long>[] writeCallbacks;
    // LastHttpContent in the end marker in netty http world.
    boolean isLast = httpContent instanceof LastHttpContent;
    if (httpContent.content().nioBufferCount() > 0) {
        // not a copy.
        httpContent = ReferenceCountUtil.retain(httpContent);
        retained = true;
        contentBuffers = httpContent.content().nioBuffers();
        writeCallbacks = new ContentWriteCallback[contentBuffers.length];
        int i = 0;
        for (; i < contentBuffers.length - 1; i++) {
            writeCallbacks[i] = new ContentWriteCallback(null, false, callbackWrapper);
        }
        writeCallbacks[i] = new ContentWriteCallback(httpContent, isLast, callbackWrapper);
    } else {
        // this will not happen (looking at current implementations of ByteBuf in Netty), but if it does, we cannot avoid
        // a copy (or we can introduce a read(GatheringByteChannel) method in ReadableStreamChannel if required).
        nettyMetrics.contentCopyCount.inc();
        logger.warn("HttpContent had to be copied because ByteBuf did not have a backing ByteBuffer");
        ByteBuffer contentBuffer = ByteBuffer.allocate(httpContent.content().readableBytes());
        httpContent.content().readBytes(contentBuffer);
        // no need to retain httpContent since we have a copy.
        ContentWriteCallback writeCallback = new ContentWriteCallback(null, isLast, callbackWrapper);
        contentBuffers = new ByteBuffer[] { contentBuffer };
        writeCallbacks = new ContentWriteCallback[] { writeCallback };
    }
    boolean asyncWritesCalled = false;
    try {
        for (int i = 0; i < contentBuffers.length; i++) {
            if (digest != null) {
                long startTime = System.currentTimeMillis();
                int savedPosition = contentBuffers[i].position();
                digest.update(contentBuffers[i]);
                contentBuffers[i].position(savedPosition);
                digestCalculationTimeInMs += (System.currentTimeMillis() - startTime);
            }
            writeChannel.write(contentBuffers[i], writeCallbacks[i]);
        }
        asyncWritesCalled = true;
    } finally {
        if (retained && !asyncWritesCalled) {
            ReferenceCountUtil.release(httpContent);
        }
    }
    allContentReceived = isLast;
}

From source file:com.caricah.iotracah.server.netty.channelgroup.IotChannelGroup.java

License:Apache License

private static Object safeDuplicate(Object message) {
    if (message instanceof ByteBuf) {
        return ((ByteBuf) message).duplicate().retain();
    } else if (message instanceof ByteBufHolder) {
        return ((ByteBufHolder) message).duplicate().retain();
    } else {/*  w  ww  .  j  av  a2 s  .  c om*/
        return ReferenceCountUtil.retain(message);
    }
}

From source file:com.flysoloing.learning.network.netty.http2.helloworld.multiplex.server.Http2ServerInitializer.java

License:Apache License

/**
 * Configure the pipeline for a cleartext upgrade from HTTP to HTTP/2.0
 *///w  w w . ja va  2s  .  co m
private void configureClearText(SocketChannel ch) {
    final ChannelPipeline p = ch.pipeline();
    final HttpServerCodec sourceCodec = new HttpServerCodec();

    p.addLast(sourceCodec);
    p.addLast(new HttpServerUpgradeHandler(sourceCodec, upgradeCodecFactory));
    p.addLast(new SimpleChannelInboundHandler<HttpMessage>() {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, HttpMessage msg) throws Exception {
            // If this handler is hit then no upgrade has been attempted and the client is just talking HTTP.
            System.err.println("Directly talking: " + msg.protocolVersion() + " (no upgrade was attempted)");
            ChannelPipeline pipeline = ctx.pipeline();
            ChannelHandlerContext thisCtx = pipeline.context(this);
            pipeline.addAfter(thisCtx.name(), null,
                    new HelloWorldHttp1Handler("Direct. No Upgrade Attempted."));
            pipeline.replace(this, null, new HttpObjectAggregator(maxHttpContentLength));
            ctx.fireChannelRead(ReferenceCountUtil.retain(msg));
        }
    });

    p.addLast(new UserEventLogger());
}

From source file:com.github.ambry.rest.NettyMessageProcessorTest.java

License:Open Source License

/**
 * Tests the case where raw bytes are POSTed as chunks.
 * @throws InterruptedException/* w  ww .  j  a v a 2  s  .  c o m*/
 */
@Test
public void rawBytesPostTest() throws InterruptedException {
    Random random = new Random();
    // request also contains content.
    ByteBuffer content = ByteBuffer.wrap(RestTestUtils.getRandomBytes(random.nextInt(128) + 128));
    HttpRequest postRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/",
            Unpooled.wrappedBuffer(content));
    HttpHeaders.setHeader(postRequest, RestUtils.Headers.SERVICE_ID, "rawBytesPostTest");
    HttpHeaders.setHeader(postRequest, RestUtils.Headers.BLOB_SIZE, content.remaining());
    postRequest = ReferenceCountUtil.retain(postRequest);
    ByteBuffer receivedContent = doPostTest(postRequest, null);
    compareContent(receivedContent, Collections.singletonList(content));

    // request and content separate.
    final int NUM_CONTENTS = 5;
    postRequest = RestTestUtils.createRequest(HttpMethod.POST, "/", null);
    List<ByteBuffer> contents = new ArrayList<ByteBuffer>(NUM_CONTENTS);
    int blobSize = 0;
    for (int i = 0; i < NUM_CONTENTS; i++) {
        ByteBuffer buffer = ByteBuffer.wrap(RestTestUtils.getRandomBytes(random.nextInt(128) + 128));
        blobSize += buffer.remaining();
        contents.add(i, buffer);
    }
    HttpHeaders.setHeader(postRequest, RestUtils.Headers.SERVICE_ID, "rawBytesPostTest");
    HttpHeaders.setHeader(postRequest, RestUtils.Headers.BLOB_SIZE, blobSize);
    receivedContent = doPostTest(postRequest, contents);
    compareContent(receivedContent, contents);
}

From source file:com.github.ambry.rest.NettyMultipartRequest.java

License:Open Source License

/**
 * Processes a single decoded part in a multipart request. Exposes the data in the part either through the channel
 * itself (if it is the blob part) or via {@link #getArgs()}.
 * @param part the {@link InterfaceHttpData} that needs to be processed.
 * @throws RestServiceException if the request channel is closed, if there is more than one part of the same name, if
 *                              the size obtained from the headers does not match the actual size of the blob part or
 *                              if {@code part} is not of the expected type ({@link FileUpload}).
 *///from  ww  w. j av  a2  s  . c  o  m
private void processPart(InterfaceHttpData part) throws RestServiceException {
    if (part.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
        FileUpload fileUpload = (FileUpload) part;
        if (fileUpload.getName().equals(RestUtils.MultipartPost.BLOB_PART)) {
            // this is actual data.
            if (hasBlob) {
                nettyMetrics.repeatedPartsError.inc();
                throw new RestServiceException("Request has more than one " + RestUtils.MultipartPost.BLOB_PART,
                        RestServiceErrorCode.BadRequest);
            } else {
                hasBlob = true;
                if (fileUpload.length() != getSize()) {
                    nettyMetrics.multipartRequestSizeMismatchError.inc();
                    throw new RestServiceException("Request size [" + fileUpload.length()
                            + "] does not match Content-Length [" + getSize() + "]",
                            RestServiceErrorCode.BadRequest);
                } else {
                    contentLock.lock();
                    try {
                        if (isOpen()) {
                            requestContents.add(
                                    new DefaultHttpContent(ReferenceCountUtil.retain(fileUpload.content())));
                        } else {
                            nettyMetrics.multipartRequestAlreadyClosedError.inc();
                            throw new RestServiceException("Request is closed",
                                    RestServiceErrorCode.RequestChannelClosed);
                        }
                    } finally {
                        contentLock.unlock();
                    }
                }
            }
        } else {
            // this is any kind of data. (For ambry, this will be user metadata).
            // TODO: find a configurable way of rejecting unexpected file parts.
            String name = fileUpload.getName();
            if (allArgs.containsKey(name)) {
                nettyMetrics.repeatedPartsError.inc();
                throw new RestServiceException("Request already has a component named " + name,
                        RestServiceErrorCode.BadRequest);
            } else {
                ByteBuffer buffer = ByteBuffer.allocate(fileUpload.content().readableBytes());
                // TODO: Possible optimization - Upgrade ByteBufferReadableStreamChannel to take a list of ByteBuffer. This
                // TODO: will avoid the copy.
                fileUpload.content().readBytes(buffer);
                buffer.flip();
                allArgs.put(name, buffer);
            }
        }
    } else {
        nettyMetrics.unsupportedPartError.inc();
        throw new RestServiceException("Unexpected HTTP data", RestServiceErrorCode.BadRequest);
    }
}

From source file:com.github.ambry.rest.NettyRequest.java

License:Open Source License

/**
 * Writes the data in the provided {@code httpContent} to the given {@code writeChannel}.
 * @param writeChannel the {@link AsyncWritableChannel} to write the data of {@code httpContent} to.
 * @param callbackWrapper the {@link ReadIntoCallbackWrapper} for the read operation.
 * @param httpContent the piece of {@link HttpContent} that needs to be written to the {@code writeChannel}.
 *///from   w  ww .java  2  s  .  c om
protected void writeContent(AsyncWritableChannel writeChannel, ReadIntoCallbackWrapper callbackWrapper,
        HttpContent httpContent) {
    boolean retained = false;
    ByteBuffer[] contentBuffers;
    Callback<Long>[] writeCallbacks;
    // LastHttpContent in the end marker in netty http world.
    boolean isLast = httpContent instanceof LastHttpContent;
    if (httpContent.content().nioBufferCount() > 0) {
        // not a copy.
        httpContent = ReferenceCountUtil.retain(httpContent);
        retained = true;
        contentBuffers = httpContent.content().nioBuffers();
        writeCallbacks = new ContentWriteCallback[contentBuffers.length];
        int i = 0;
        for (; i < contentBuffers.length - 1; i++) {
            writeCallbacks[i] = new ContentWriteCallback(null, false, callbackWrapper);
        }
        writeCallbacks[i] = new ContentWriteCallback(httpContent, isLast, callbackWrapper);
    } else {
        // this will not happen (looking at current implementations of ByteBuf in Netty), but if it does, we cannot avoid
        // a copy (or we can introduce a read(GatheringByteChannel) method in ReadableStreamChannel if required).
        nettyMetrics.contentCopyCount.inc();
        logger.warn("HttpContent had to be copied because ByteBuf did not have a backing ByteBuffer");
        ByteBuffer contentBuffer = ByteBuffer.allocate(httpContent.content().readableBytes());
        httpContent.content().readBytes(contentBuffer);
        // no need to retain httpContent since we have a copy.
        ContentWriteCallback writeCallback = new ContentWriteCallback(null, isLast, callbackWrapper);
        contentBuffers = new ByteBuffer[] { contentBuffer };
        writeCallbacks = new ContentWriteCallback[] { writeCallback };
    }
    boolean asyncWritesCalled = false;
    try {
        for (int i = 0; i < contentBuffers.length; i++) {
            writeChannel.write(contentBuffers[i], writeCallbacks[i]);
        }
        asyncWritesCalled = true;
    } finally {
        if (retained && !asyncWritesCalled) {
            ReferenceCountUtil.release(httpContent);
        }
    }
}