Search in sources :

Example 1 with ErrorMessage

use of org.apache.cassandra.transport.messages.ErrorMessage in project cassandra by apache.

the class InitialConnectionHandler method decode.

protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> list) throws Exception {
    Envelope inbound = decoder.decode(buffer);
    if (inbound == null)
        return;
    try {
        Envelope outbound;
        switch(inbound.header.type) {
            case OPTIONS:
                logger.trace("OPTIONS received {}", inbound.header.version);
                List<String> cqlVersions = new ArrayList<>();
                cqlVersions.add(QueryProcessor.CQL_VERSION.toString());
                List<String> compressions = new ArrayList<>();
                if (Compressor.SnappyCompressor.instance != null)
                    compressions.add("snappy");
                // LZ4 is always available since worst case scenario it default to a pure JAVA implem.
                compressions.add("lz4");
                Map<String, List<String>> supportedOptions = new HashMap<>();
                supportedOptions.put(StartupMessage.CQL_VERSION, cqlVersions);
                supportedOptions.put(StartupMessage.COMPRESSION, compressions);
                supportedOptions.put(StartupMessage.PROTOCOL_VERSIONS, ProtocolVersion.supportedVersions());
                SupportedMessage supported = new SupportedMessage(supportedOptions);
                supported.setStreamId(inbound.header.streamId);
                outbound = supported.encode(inbound.header.version);
                ctx.writeAndFlush(outbound);
                break;
            case STARTUP:
                Attribute<Connection> attrConn = ctx.channel().attr(Connection.attributeKey);
                Connection connection = attrConn.get();
                if (connection == null) {
                    connection = factory.newConnection(ctx.channel(), inbound.header.version);
                    attrConn.set(connection);
                }
                assert connection instanceof ServerConnection;
                StartupMessage startup = (StartupMessage) Message.Decoder.decodeMessage(ctx.channel(), inbound);
                InetAddress remoteAddress = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress();
                final ClientResourceLimits.Allocator allocator = ClientResourceLimits.getAllocatorForEndpoint(remoteAddress);
                ChannelPromise promise;
                if (inbound.header.version.isGreaterOrEqualTo(ProtocolVersion.V5)) {
                    // in this case we need to defer configuring the pipeline until after the response
                    // has been sent, as the frame encoding specified in v5 should not be applied to
                    // the STARTUP response.
                    allocator.allocate(inbound.header.bodySizeInBytes);
                    promise = AsyncChannelPromise.withListener(ctx, future -> {
                        if (future.isSuccess()) {
                            logger.trace("Response to STARTUP sent, configuring pipeline for {}", inbound.header.version);
                            configurator.configureModernPipeline(ctx, allocator, inbound.header.version, startup.options);
                            allocator.release(inbound.header.bodySizeInBytes);
                        } else {
                            Throwable cause = future.cause();
                            if (null == cause)
                                cause = new ServerError("Unexpected error establishing connection");
                            logger.warn("Writing response to STARTUP failed, unable to configure pipeline", cause);
                            ErrorMessage error = ErrorMessage.fromException(cause);
                            Envelope response = error.encode(inbound.header.version);
                            ChannelPromise closeChannel = AsyncChannelPromise.withListener(ctx, f -> ctx.close());
                            ctx.writeAndFlush(response, closeChannel);
                            if (ctx.channel().isOpen())
                                ctx.channel().close();
                        }
                    });
                } else {
                    // no need to configure the pipeline asynchronously in this case
                    // the capacity obtained from allocator for the STARTUP message
                    // is released when flushed by the legacy dispatcher/flusher so
                    // there's no need to explicitly release that here either.
                    configurator.configureLegacyPipeline(ctx, allocator);
                    promise = new VoidChannelPromise(ctx.channel(), false);
                }
                final Message.Response response = Dispatcher.processRequest(ctx.channel(), startup, Overload.NONE);
                outbound = response.encode(inbound.header.version);
                ctx.writeAndFlush(outbound, promise);
                logger.trace("Configured pipeline: {}", ctx.pipeline());
                break;
            default:
                ErrorMessage error = ErrorMessage.fromException(new ProtocolException(String.format("Unexpected message %s, expecting STARTUP or OPTIONS", inbound.header.type)));
                outbound = error.encode(inbound.header.version);
                ctx.writeAndFlush(outbound);
        }
    } finally {
        inbound.release();
    }
}
Also used : Attribute(io.netty.util.Attribute) Logger(org.slf4j.Logger) AsyncChannelPromise(org.apache.cassandra.net.AsyncChannelPromise) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) Overload(org.apache.cassandra.transport.ClientResourceLimits.Overload) QueryProcessor(org.apache.cassandra.cql3.QueryProcessor) InetSocketAddress(java.net.InetSocketAddress) ArrayList(java.util.ArrayList) InetAddress(java.net.InetAddress) VoidChannelPromise(io.netty.channel.VoidChannelPromise) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) List(java.util.List) ByteBuf(io.netty.buffer.ByteBuf) ChannelPromise(io.netty.channel.ChannelPromise) Map(java.util.Map) StartupMessage(org.apache.cassandra.transport.messages.StartupMessage) SupportedMessage(org.apache.cassandra.transport.messages.SupportedMessage) ErrorMessage(org.apache.cassandra.transport.messages.ErrorMessage) ByteToMessageDecoder(io.netty.handler.codec.ByteToMessageDecoder) StartupMessage(org.apache.cassandra.transport.messages.StartupMessage) SupportedMessage(org.apache.cassandra.transport.messages.SupportedMessage) ErrorMessage(org.apache.cassandra.transport.messages.ErrorMessage) HashMap(java.util.HashMap) InetSocketAddress(java.net.InetSocketAddress) ArrayList(java.util.ArrayList) StartupMessage(org.apache.cassandra.transport.messages.StartupMessage) VoidChannelPromise(io.netty.channel.VoidChannelPromise) AsyncChannelPromise(org.apache.cassandra.net.AsyncChannelPromise) VoidChannelPromise(io.netty.channel.VoidChannelPromise) ChannelPromise(io.netty.channel.ChannelPromise) ArrayList(java.util.ArrayList) List(java.util.List) SupportedMessage(org.apache.cassandra.transport.messages.SupportedMessage) ErrorMessage(org.apache.cassandra.transport.messages.ErrorMessage) InetAddress(java.net.InetAddress)

Example 2 with ErrorMessage

use of org.apache.cassandra.transport.messages.ErrorMessage in project cassandra by apache.

the class ErrorMessageTest method testV4CasWriteResultUnknownSerDeser.

@Test
public void testV4CasWriteResultUnknownSerDeser() {
    int receivedBlockFor = 3;
    ConsistencyLevel consistencyLevel = ConsistencyLevel.SERIAL;
    CasWriteUnknownResultException ex = new CasWriteUnknownResultException(consistencyLevel, receivedBlockFor, receivedBlockFor);
    ErrorMessage deserialized = encodeThenDecode(ErrorMessage.fromException(ex), ProtocolVersion.V4);
    assertTrue(deserialized.error instanceof WriteTimeoutException);
    assertFalse(deserialized.error instanceof CasWriteUnknownResultException);
    WriteTimeoutException deserializedEx = (WriteTimeoutException) deserialized.error;
    assertEquals(consistencyLevel, deserializedEx.consistency);
    assertEquals(receivedBlockFor, deserializedEx.received);
    assertEquals(receivedBlockFor, deserializedEx.blockFor);
}
Also used : ConsistencyLevel(org.apache.cassandra.db.ConsistencyLevel) CasWriteTimeoutException(org.apache.cassandra.exceptions.CasWriteTimeoutException) WriteTimeoutException(org.apache.cassandra.exceptions.WriteTimeoutException) ErrorMessage(org.apache.cassandra.transport.messages.ErrorMessage) CasWriteUnknownResultException(org.apache.cassandra.exceptions.CasWriteUnknownResultException) Test(org.junit.Test)

Example 3 with ErrorMessage

use of org.apache.cassandra.transport.messages.ErrorMessage in project cassandra by apache.

the class ErrorMessageTest method testV5CasWriteResultUnknownSerDeser.

@Test
public void testV5CasWriteResultUnknownSerDeser() {
    int receivedBlockFor = 3;
    ConsistencyLevel consistencyLevel = ConsistencyLevel.SERIAL;
    CasWriteUnknownResultException ex = new CasWriteUnknownResultException(consistencyLevel, receivedBlockFor, receivedBlockFor);
    ErrorMessage deserialized = encodeThenDecode(ErrorMessage.fromException(ex), ProtocolVersion.V5);
    assertTrue(deserialized.error instanceof CasWriteUnknownResultException);
    CasWriteUnknownResultException deserializedEx = (CasWriteUnknownResultException) deserialized.error;
    assertEquals(consistencyLevel, deserializedEx.consistency);
    assertEquals(receivedBlockFor, deserializedEx.received);
    assertEquals(receivedBlockFor, deserializedEx.blockFor);
    assertEquals(ex.getMessage(), deserializedEx.getMessage());
    assertTrue(deserializedEx.getMessage().contains("CAS operation result is unknown"));
}
Also used : ConsistencyLevel(org.apache.cassandra.db.ConsistencyLevel) ErrorMessage(org.apache.cassandra.transport.messages.ErrorMessage) CasWriteUnknownResultException(org.apache.cassandra.exceptions.CasWriteUnknownResultException) Test(org.junit.Test)

Example 4 with ErrorMessage

use of org.apache.cassandra.transport.messages.ErrorMessage in project cassandra by apache.

the class ErrorMessageTest method testV5ReadFailureSerDeser.

@Test
public void testV5ReadFailureSerDeser() {
    int receivedBlockFor = 3;
    ConsistencyLevel consistencyLevel = ConsistencyLevel.ALL;
    boolean dataPresent = false;
    ReadFailureException rfe = new ReadFailureException(consistencyLevel, receivedBlockFor, receivedBlockFor, dataPresent, failureReasonMap1);
    ErrorMessage deserialized = encodeThenDecode(ErrorMessage.fromException(rfe), ProtocolVersion.V5);
    ReadFailureException deserializedRfe = (ReadFailureException) deserialized.error;
    assertEquals(failureReasonMap1, deserializedRfe.failureReasonByEndpoint);
    assertEquals(receivedBlockFor, deserializedRfe.received);
    assertEquals(receivedBlockFor, deserializedRfe.blockFor);
    assertEquals(consistencyLevel, deserializedRfe.consistency);
    assertEquals(dataPresent, deserializedRfe.dataPresent);
}
Also used : ConsistencyLevel(org.apache.cassandra.db.ConsistencyLevel) ReadFailureException(org.apache.cassandra.exceptions.ReadFailureException) ErrorMessage(org.apache.cassandra.transport.messages.ErrorMessage) Test(org.junit.Test)

Example 5 with ErrorMessage

use of org.apache.cassandra.transport.messages.ErrorMessage in project cassandra by apache.

the class ErrorMessageTest method testV4CasWriteTimeoutSerDeser.

@Test
public void testV4CasWriteTimeoutSerDeser() {
    int contentions = 1;
    int receivedBlockFor = 3;
    ConsistencyLevel consistencyLevel = ConsistencyLevel.SERIAL;
    CasWriteTimeoutException ex = new CasWriteTimeoutException(WriteType.CAS, consistencyLevel, receivedBlockFor, receivedBlockFor, contentions);
    ErrorMessage deserialized = encodeThenDecode(ErrorMessage.fromException(ex), ProtocolVersion.V4);
    assertTrue(deserialized.error instanceof WriteTimeoutException);
    assertFalse(deserialized.error instanceof CasWriteTimeoutException);
    WriteTimeoutException deserializedEx = (WriteTimeoutException) deserialized.error;
    assertEquals(WriteType.CAS, deserializedEx.writeType);
    assertEquals(consistencyLevel, deserializedEx.consistency);
    assertEquals(receivedBlockFor, deserializedEx.received);
    assertEquals(receivedBlockFor, deserializedEx.blockFor);
}
Also used : ConsistencyLevel(org.apache.cassandra.db.ConsistencyLevel) CasWriteTimeoutException(org.apache.cassandra.exceptions.CasWriteTimeoutException) WriteTimeoutException(org.apache.cassandra.exceptions.WriteTimeoutException) ErrorMessage(org.apache.cassandra.transport.messages.ErrorMessage) CasWriteTimeoutException(org.apache.cassandra.exceptions.CasWriteTimeoutException) Test(org.junit.Test)

Aggregations

ErrorMessage (org.apache.cassandra.transport.messages.ErrorMessage)8 Test (org.junit.Test)7 ConsistencyLevel (org.apache.cassandra.db.ConsistencyLevel)6 CasWriteTimeoutException (org.apache.cassandra.exceptions.CasWriteTimeoutException)3 ByteBuf (io.netty.buffer.ByteBuf)2 CasWriteUnknownResultException (org.apache.cassandra.exceptions.CasWriteUnknownResultException)2 WriteTimeoutException (org.apache.cassandra.exceptions.WriteTimeoutException)2 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 ChannelPromise (io.netty.channel.ChannelPromise)1 VoidChannelPromise (io.netty.channel.VoidChannelPromise)1 ByteToMessageDecoder (io.netty.handler.codec.ByteToMessageDecoder)1 Attribute (io.netty.util.Attribute)1 InetAddress (java.net.InetAddress)1 InetSocketAddress (java.net.InetSocketAddress)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 QueryProcessor (org.apache.cassandra.cql3.QueryProcessor)1 WriteType (org.apache.cassandra.db.WriteType)1