Search in sources :

Example 1 with RequestTooBigException

use of org.apache.hadoop.hbase.exceptions.RequestTooBigException in project hbase by apache.

the class SimpleServerRpcConnection method readAndProcess.

/**
 * Read off the wire. If there is not enough data to read, update the connection state with what
 * we have and returns.
 * @return Returns -1 if failure (and caller will close connection), else zero or more.
 * @throws IOException
 * @throws InterruptedException
 */
public int readAndProcess() throws IOException, InterruptedException {
    // If we have not read the connection setup preamble, look to see if that is on the wire.
    if (!connectionPreambleRead) {
        int count = readPreamble();
        if (!connectionPreambleRead) {
            return count;
        }
    }
    // Try and read in an int. it will be length of the data to read (or -1 if a ping). We catch the
    // integer length into the 4-byte this.dataLengthBuffer.
    int count = read4Bytes();
    if (count < 0 || dataLengthBuffer.remaining() > 0) {
        return count;
    }
    // or it is a request.
    if (data == null) {
        dataLengthBuffer.flip();
        int dataLength = dataLengthBuffer.getInt();
        if (dataLength == RpcClient.PING_CALL_ID) {
            if (!useWrap) {
                // covers the !useSasl too
                dataLengthBuffer.clear();
                // ping message
                return 0;
            }
        }
        if (dataLength < 0) {
            // A data length of zero is legal.
            throw new DoNotRetryIOException("Unexpected data length " + dataLength + "!! from " + getHostAddress());
        }
        if (dataLength > this.rpcServer.maxRequestSize) {
            String msg = "RPC data length of " + dataLength + " received from " + getHostAddress() + " is greater than max allowed " + this.rpcServer.maxRequestSize + ". Set \"" + SimpleRpcServer.MAX_REQUEST_SIZE + "\" on server to override this limit (not recommended)";
            SimpleRpcServer.LOG.warn(msg);
            if (connectionHeaderRead && connectionPreambleRead) {
                incRpcCount();
                // Construct InputStream for the non-blocking SocketChannel
                // We need the InputStream because we want to read only the request header
                // instead of the whole rpc.
                ByteBuffer buf = ByteBuffer.allocate(1);
                InputStream is = new InputStream() {

                    @Override
                    public int read() throws IOException {
                        SimpleServerRpcConnection.this.rpcServer.channelRead(channel, buf);
                        buf.flip();
                        int x = buf.get();
                        buf.flip();
                        return x;
                    }
                };
                CodedInputStream cis = CodedInputStream.newInstance(is);
                int headerSize = cis.readRawVarint32();
                Message.Builder builder = RequestHeader.newBuilder();
                ProtobufUtil.mergeFrom(builder, cis, headerSize);
                RequestHeader header = (RequestHeader) builder.build();
                // Notify the client about the offending request
                SimpleServerCall reqTooBig = new SimpleServerCall(header.getCallId(), this.service, null, null, null, null, this, 0, this.addr, EnvironmentEdgeManager.currentTime(), 0, this.rpcServer.bbAllocator, this.rpcServer.cellBlockBuilder, null, responder);
                RequestTooBigException reqTooBigEx = new RequestTooBigException(msg);
                this.rpcServer.metrics.exception(reqTooBigEx);
                // Otherwise, throw a DoNotRetryIOException.
                if (VersionInfoUtil.hasMinimumVersion(connectionHeader.getVersionInfo(), RequestTooBigException.MAJOR_VERSION, RequestTooBigException.MINOR_VERSION)) {
                    reqTooBig.setResponse(null, null, reqTooBigEx, msg);
                } else {
                    reqTooBig.setResponse(null, null, new DoNotRetryIOException(msg), msg);
                }
                // In most cases we will write out the response directly. If not, it is still OK to just
                // close the connection without writing out the reqTooBig response. Do not try to write
                // out directly here, and it will cause deserialization error if the connection is slow
                // and we have a half writing response in the queue.
                reqTooBig.sendResponseIfReady();
            }
            // Close the connection
            return -1;
        }
        // Initialize this.data with a ByteBuff.
        // This call will allocate a ByteBuff to read request into and assign to this.data
        // Also when we use some buffer(s) from pool, it will create a CallCleanup instance also and
        // assign to this.callCleanup
        initByteBuffToReadInto(dataLength);
        // Increment the rpc count. This counter will be decreased when we write
        // the response. If we want the connection to be detected as idle properly, we
        // need to keep the inc / dec correct.
        incRpcCount();
    }
    count = channelDataRead(channel, data);
    if (count >= 0 && data.remaining() == 0) {
        // count==0 if dataLength == 0
        process();
    }
    return count;
}
Also used : Message(org.apache.hbase.thirdparty.com.google.protobuf.Message) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) CodedInputStream(org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream) InputStream(java.io.InputStream) CodedInputStream(org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream) RequestTooBigException(org.apache.hadoop.hbase.exceptions.RequestTooBigException) RequestHeader(org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader) ByteBuffer(java.nio.ByteBuffer)

Example 2 with RequestTooBigException

use of org.apache.hadoop.hbase.exceptions.RequestTooBigException in project hbase by apache.

the class NettyRpcFrameDecoder method handleTooBigRequest.

private void handleTooBigRequest(ByteBuf in) throws IOException {
    in.skipBytes(FRAME_LENGTH_FIELD_LENGTH);
    in.markReaderIndex();
    int preIndex = in.readerIndex();
    int headerSize = readRawVarint32(in);
    if (preIndex == in.readerIndex()) {
        return;
    }
    if (headerSize < 0) {
        throw new IOException("negative headerSize: " + headerSize);
    }
    if (in.readableBytes() < headerSize) {
        NettyRpcServer.LOG.debug("headerSize is larger than readableBytes");
        in.resetReaderIndex();
        return;
    }
    RPCProtos.RequestHeader header = getHeader(in, headerSize);
    NettyRpcServer.LOG.info("BigRequest header is = " + header);
    // Notify the client about the offending request
    NettyServerCall reqTooBig = connection.createCall(header.getCallId(), connection.service, null, null, null, null, 0, connection.addr, 0, null);
    RequestTooBigException reqTooBigEx = new RequestTooBigException(requestTooBigMessage);
    connection.rpcServer.metrics.exception(reqTooBigEx);
    // Otherwise, throw a DoNotRetryIOException.
    if (VersionInfoUtil.hasMinimumVersion(connection.connectionHeader.getVersionInfo(), RequestTooBigException.MAJOR_VERSION, RequestTooBigException.MINOR_VERSION)) {
        reqTooBig.setResponse(null, null, reqTooBigEx, requestTooBigMessage);
    } else {
        reqTooBig.setResponse(null, null, new DoNotRetryIOException(requestTooBigMessage), requestTooBigMessage);
    }
    // To guarantee that the message is written and flushed before closing the channel,
    // we should call channel.writeAndFlush() directly to add the close listener
    // instead of calling reqTooBig.sendResponseIfReady()
    reqTooBig.param = null;
    connection.channel.writeAndFlush(reqTooBig).addListener(ChannelFutureListener.CLOSE);
}
Also used : DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) RequestTooBigException(org.apache.hadoop.hbase.exceptions.RequestTooBigException) RPCProtos(org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) IOException(java.io.IOException)

Aggregations

DoNotRetryIOException (org.apache.hadoop.hbase.DoNotRetryIOException)2 RequestTooBigException (org.apache.hadoop.hbase.exceptions.RequestTooBigException)2 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 ByteBuffer (java.nio.ByteBuffer)1 RPCProtos (org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos)1 RequestHeader (org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader)1 CodedInputStream (org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream)1 Message (org.apache.hbase.thirdparty.com.google.protobuf.Message)1