Rearranges the pipeline to deal with the new framing structure in protocol v5 and above. The * first messages still use the legacy format, we only do this after a successful response to the * first STARTUP message. + * + *
If SCYLLA_USE_METADATA_ID feature was negotiated we need to replace {@link
+ * FrameEncoder} and {@link FrameDecoder} handlers with instances aware of a negotiated protocol
+ * feature.
*/
- private void maybeSwitchToModernFraming() {
+ private void maybeUpdatePipeline() {
+ ProtocolFeatures protocolFeatures = featureStore.getProtocolFeatures();
if (context
.getProtocolVersionRegistry()
.supports(initialProtocolVersion, DefaultProtocolFeature.MODERN_FRAMING)) {
@@ -428,6 +438,26 @@ private void maybeSwitchToModernFraming() {
ChannelFactory.BYTES_TO_SEGMENT_DECODER_NAME,
ChannelFactory.SEGMENT_TO_FRAME_DECODER_NAME,
new SegmentToFrameDecoder(context.getFrameCodec(), logPrefix));
+ } else if (protocolFeatures.isScyllaUseMetadataId()) {
+ int maxFrameLength =
+ (int)
+ context
+ .getConfig()
+ .getDefaultProfile()
+ .getBytes(DefaultDriverOption.PROTOCOL_MAX_FRAME_LENGTH);
+
+ ChannelPipeline pipeline = ctx.pipeline();
+ pipeline.replace(
+ ChannelFactory.FRAME_TO_BYTES_ENCODER_NAME,
+ ChannelFactory.FRAME_TO_BYTES_ENCODER_NAME,
+ new FrameEncoder(
+ context.getFrameCodec(),
+ protocolFeatures, // Passing updated protocol features to alter codecs behaviors
+ maxFrameLength));
+ pipeline.replace(
+ ChannelFactory.BYTES_TO_FRAME_DECODER_NAME,
+ ChannelFactory.BYTES_TO_FRAME_DECODER_NAME,
+ new FrameDecoder(context.getFrameCodec(), protocolFeatures, maxFrameLength));
}
}
diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/protocol/FrameDecoder.java b/core/src/main/java/com/datastax/oss/driver/internal/core/protocol/FrameDecoder.java
index 20816ba581b..add57fa9fc6 100644
--- a/core/src/main/java/com/datastax/oss/driver/internal/core/protocol/FrameDecoder.java
+++ b/core/src/main/java/com/datastax/oss/driver/internal/core/protocol/FrameDecoder.java
@@ -22,6 +22,7 @@
import com.datastax.oss.protocol.internal.Frame;
import com.datastax.oss.protocol.internal.FrameCodec;
import com.datastax.oss.protocol.internal.ProtocolConstants;
+import com.datastax.oss.protocol.internal.ProtocolFeatures;
import com.datastax.oss.protocol.internal.response.Error;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -41,11 +42,16 @@ public class FrameDecoder extends LengthFieldBasedFrameDecoder {
private static final int LENGTH_FIELD_LENGTH = 4;
private final FrameCodec