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();
}
}
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);
}
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"));
}
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);
}
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);
}
Aggregations