4545import com .datastax .oss .driver .internal .core .protocol .SegmentToFrameDecoder ;
4646import com .datastax .oss .driver .internal .core .util .ProtocolUtils ;
4747import com .datastax .oss .driver .internal .core .util .concurrent .UncaughtExceptions ;
48+ import com .datastax .oss .driver .shaded .guava .common .annotations .VisibleForTesting ;
4849import com .datastax .oss .protocol .internal .Message ;
4950import com .datastax .oss .protocol .internal .ProtocolConstants ;
5051import com .datastax .oss .protocol .internal .ProtocolConstants .ErrorCode ;
@@ -225,16 +226,15 @@ void onResponse(Message response) {
225226 channel .attr (DriverChannel .OPTIONS_KEY ).set (supported .options );
226227 featureStore = ProtocolFeatureStore .parseSupportedOptions (supported .options );
227228 featureStore .storeInChannel (channel );
228- maybeUpdatePipelineWithProtocolOptions (featureStore .isMetadataIdEnabled ());
229229 step = Step .STARTUP ;
230230 send ();
231231 } else if (step == Step .STARTUP && response instanceof Ready ) {
232- maybeSwitchToModernFraming ();
232+ maybeUpdatePipeline ();
233233 context .getAuthProvider ().ifPresent (provider -> provider .onMissingChallenge (endPoint ));
234234 step = Step .GET_CLUSTER_NAME ;
235235 send ();
236236 } else if (step == Step .STARTUP && response instanceof Authenticate ) {
237- maybeSwitchToModernFraming ();
237+ maybeUpdatePipeline ();
238238 Authenticate authenticate = (Authenticate ) response ;
239239 authenticator = buildAuthenticator (endPoint , authenticate .authenticator );
240240 authenticator
@@ -400,11 +400,18 @@ public String toString() {
400400 }
401401
402402 /**
403- * Rearranges the pipeline to deal with the new framing structure in protocol v5 and above. The
403+ * Conditionally rebuilds pipeline.
404+ *
405+ * <p>Rearranges the pipeline to deal with the new framing structure in protocol v5 and above. The
404406 * first messages still use the legacy format, we only do this after a successful response to the
405407 * first STARTUP message.
408+ *
409+ * <p>If <code>SCYLLA_USE_METADATA_ID</code> feature was negotiated we need to replace {@link
410+ * FrameEncoder} and {@link FrameDecoder} handlers with instances aware of a negotiated protocol
411+ * feature.
406412 */
407- private void maybeSwitchToModernFraming () {
413+ private void maybeUpdatePipeline () {
414+ ProtocolFeatures protocolFeatures = featureStore .getProtocolFeatures ();
408415 if (context
409416 .getProtocolVersionRegistry ()
410417 .supports (initialProtocolVersion , DefaultProtocolFeature .MODERN_FRAMING )) {
@@ -432,20 +439,7 @@ private void maybeSwitchToModernFraming() {
432439 ChannelFactory .BYTES_TO_SEGMENT_DECODER_NAME ,
433440 ChannelFactory .SEGMENT_TO_FRAME_DECODER_NAME ,
434441 new SegmentToFrameDecoder (context .getFrameCodec (), logPrefix ));
435- }
436- }
437-
438- /**
439- * If <code>SCYLLA_USE_METADATA_ID</code> feature was negotiated we need to replace {@link
440- * FrameEncoder} and {@link FrameDecoder} handlers with instances aware of a negotiated protocol
441- * feature.
442- *
443- * @param metadataIdEnabled indicates if feature is successfully negotiated
444- */
445- private void maybeUpdatePipelineWithProtocolOptions (boolean metadataIdEnabled ) {
446- if (metadataIdEnabled ) {
447- ProtocolFeatures protocolFeatures =
448- new ProtocolFeatures .Builder ().setScyllaUseMetadataId ().build ();
442+ } else if (protocolFeatures .isScyllaUseMetadataId ()) {
449443 int maxFrameLength =
450444 (int )
451445 context
@@ -457,7 +451,10 @@ private void maybeUpdatePipelineWithProtocolOptions(boolean metadataIdEnabled) {
457451 pipeline .replace (
458452 ChannelFactory .FRAME_TO_BYTES_ENCODER_NAME ,
459453 ChannelFactory .FRAME_TO_BYTES_ENCODER_NAME ,
460- new FrameEncoder (context .getFrameCodec (), protocolFeatures , maxFrameLength ));
454+ new FrameEncoder (
455+ context .getFrameCodec (),
456+ protocolFeatures , // Passing updated protocol features to alter codecs behaviors
457+ maxFrameLength ));
461458 pipeline .replace (
462459 ChannelFactory .BYTES_TO_FRAME_DECODER_NAME ,
463460 ChannelFactory .BYTES_TO_FRAME_DECODER_NAME ,
@@ -468,4 +465,9 @@ private void maybeUpdatePipelineWithProtocolOptions(boolean metadataIdEnabled) {
468465 private String getString (List <ByteBuffer > row , int i ) {
469466 return TypeCodecs .TEXT .decode (row .get (i ), DefaultProtocolVersion .DEFAULT );
470467 }
468+
469+ @ VisibleForTesting
470+ void setFeatureStore (ProtocolFeatureStore featureStore ) {
471+ this .featureStore = featureStore ;
472+ }
471473}
0 commit comments