diff --git a/src/Cassandra.Tests/Connections/TestHelpers/FakeSupportedOptionsInitializer.cs b/src/Cassandra.Tests/Connections/TestHelpers/FakeSupportedOptionsInitializer.cs index 17b664b37..97c9fbc67 100644 --- a/src/Cassandra.Tests/Connections/TestHelpers/FakeSupportedOptionsInitializer.cs +++ b/src/Cassandra.Tests/Connections/TestHelpers/FakeSupportedOptionsInitializer.cs @@ -43,5 +43,11 @@ public ShardingInfo GetShardingInfo() { return null; } + + public TabletInfo GetTabletInfo() + { + return null; + + } } } \ No newline at end of file diff --git a/src/Cassandra/Connections/Connection.cs b/src/Cassandra/Connections/Connection.cs index ccf4fab31..5a6c98739 100644 --- a/src/Cassandra/Connections/Connection.cs +++ b/src/Cassandra/Connections/Connection.cs @@ -577,6 +577,11 @@ public ShardingInfo ShardingInfo() return _supportedOptionsInitializer.GetShardingInfo(); } + public TabletInfo TabletInfo() + { + return _supportedOptionsInitializer.GetTabletInfo(); + } + private void ReadHandler(byte[] buffer, int bytesReceived) { if (_isClosed) @@ -853,7 +858,7 @@ private Task SendOptions() /// private Task Startup() { - var request = _startupRequestFactory.CreateStartupRequest(Options); + var request = _startupRequestFactory.CreateStartupRequest(Options, _supportedOptionsInitializer); // Use the Connect timeout for the startup request timeout return Send(request, Configuration.SocketOptions.ConnectTimeoutMillis); } diff --git a/src/Cassandra/Connections/Control/ISupportedOptionsInitializer.cs b/src/Cassandra/Connections/Control/ISupportedOptionsInitializer.cs index 4741c708e..b92d5389d 100644 --- a/src/Cassandra/Connections/Control/ISupportedOptionsInitializer.cs +++ b/src/Cassandra/Connections/Control/ISupportedOptionsInitializer.cs @@ -23,5 +23,6 @@ internal interface ISupportedOptionsInitializer Task ApplySupportedOptionsAsync(IConnection connection); void ApplySupportedFromResponse(Response response); ShardingInfo GetShardingInfo(); + TabletInfo GetTabletInfo(); } } diff --git a/src/Cassandra/Connections/Control/SupportedOptionsInitializer.cs b/src/Cassandra/Connections/Control/SupportedOptionsInitializer.cs index 08364fa68..44b805dfd 100644 --- a/src/Cassandra/Connections/Control/SupportedOptionsInitializer.cs +++ b/src/Cassandra/Connections/Control/SupportedOptionsInitializer.cs @@ -37,6 +37,7 @@ internal class SupportedOptionsInitializer : ISupportedOptionsInitializer private const string ScyllaShardAwarePortSSL = "SCYLLA_SHARD_AWARE_PORT_SSL"; private ShardingInfo _shardingInfo; + private TabletInfo _tabletInfo; public SupportedOptionsInitializer(Metadata metadata) { @@ -65,6 +66,7 @@ public void ApplySupportedFromResponse(Response response) ApplyProductTypeOption(supportedResponse.Output.Options); ApplyScyllaShardingOption(supportedResponse.Output.Options); + ApplyScyllaTabletOption(supportedResponse.Output.Options); } public ShardingInfo GetShardingInfo() @@ -72,6 +74,11 @@ public ShardingInfo GetShardingInfo() return _shardingInfo; } + public TabletInfo GetTabletInfo() + { + return _tabletInfo; + } + private void ApplyProductTypeOption(IDictionary options) { if (!options.TryGetValue(SupportedOptionsInitializer.SupportedProductTypeKey, out var productTypeOptions)) @@ -90,6 +97,11 @@ private void ApplyProductTypeOption(IDictionary options) } } + private void ApplyScyllaTabletOption(IDictionary options) + { + _tabletInfo = TabletInfo.ParseTabletInfo(options); + } + private void ApplyScyllaShardingOption(IDictionary options) { if (!options.TryGetValue(SupportedOptionsInitializer.ScyllaShard, out var scyllaShard)) diff --git a/src/Cassandra/Connections/TabletInfo.cs b/src/Cassandra/Connections/TabletInfo.cs new file mode 100644 index 000000000..aa633afee --- /dev/null +++ b/src/Cassandra/Connections/TabletInfo.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; + +namespace Cassandra.Connections +{ + public class TabletInfo + { + private const string SCYLLA_TABLETS_STARTUP_OPTION_KEY = "TABLETS_ROUTING_V1"; + private const string SCYLLA_TABLETS_STARTUP_OPTION_VALUE = ""; + public const string TABLETS_ROUTING_V1_CUSTOM_PAYLOAD_KEY = "tablets-routing-v1"; + + private bool enabled; + + private TabletInfo(bool enabled) + { + this.enabled = enabled; + } + + // Currently pertains only to TABLETS_ROUTING_V1 + public bool IsEnabled() + { + return enabled; + } + + public static TabletInfo ParseTabletInfo(IDictionary supported) + { + if (supported.TryGetValue(SCYLLA_TABLETS_STARTUP_OPTION_KEY, out var values)) + { + return new TabletInfo( + values != null && + values.Length == 1 && + values[0] == SCYLLA_TABLETS_STARTUP_OPTION_VALUE + ); + } + + return new TabletInfo(false); + } + } +} diff --git a/src/Cassandra/Requests/IStartupOptionsFactory.cs b/src/Cassandra/Requests/IStartupOptionsFactory.cs index e1efbe8b5..5a49edfb0 100644 --- a/src/Cassandra/Requests/IStartupOptionsFactory.cs +++ b/src/Cassandra/Requests/IStartupOptionsFactory.cs @@ -15,11 +15,12 @@ // using System.Collections.Generic; +using Cassandra.Connections.Control; namespace Cassandra.Requests { internal interface IStartupOptionsFactory { - IReadOnlyDictionary CreateStartupOptions(ProtocolOptions options); + IReadOnlyDictionary CreateStartupOptions(ProtocolOptions options, ISupportedOptionsInitializer supportedOptionsInitializer); } } \ No newline at end of file diff --git a/src/Cassandra/Requests/IStartupRequestFactory.cs b/src/Cassandra/Requests/IStartupRequestFactory.cs index a875c72c5..18b5cab64 100644 --- a/src/Cassandra/Requests/IStartupRequestFactory.cs +++ b/src/Cassandra/Requests/IStartupRequestFactory.cs @@ -14,10 +14,12 @@ // limitations under the License. // +using Cassandra.Connections.Control; + namespace Cassandra.Requests { internal interface IStartupRequestFactory { - IRequest CreateStartupRequest(ProtocolOptions protocolOptions); + IRequest CreateStartupRequest(ProtocolOptions protocolOptions, ISupportedOptionsInitializer supportedOptionsInitializer); } } \ No newline at end of file diff --git a/src/Cassandra/Requests/StartupOptionsFactory.cs b/src/Cassandra/Requests/StartupOptionsFactory.cs index db28ed058..5cecfe56f 100644 --- a/src/Cassandra/Requests/StartupOptionsFactory.cs +++ b/src/Cassandra/Requests/StartupOptionsFactory.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using Cassandra.Helpers; +using Cassandra.Connections.Control; namespace Cassandra.Requests { @@ -31,6 +32,7 @@ internal class StartupOptionsFactory : IStartupOptionsFactory public const string ApplicationNameOption = "APPLICATION_NAME"; public const string ApplicationVersionOption = "APPLICATION_VERSION"; public const string ClientIdOption = "CLIENT_ID"; + public const string TabletsRoutingV1Option = "TABLETS_ROUTING_V1"; public const string CqlVersion = "3.0.0"; public const string SnappyCompression = "snappy"; @@ -47,7 +49,7 @@ public StartupOptionsFactory(Guid clusterId, string appVersion, string appName) _clusterId = clusterId; } - public IReadOnlyDictionary CreateStartupOptions(ProtocolOptions options) + public IReadOnlyDictionary CreateStartupOptions(ProtocolOptions options, ISupportedOptionsInitializer supportedOptionsInitializer = null) { var startupOptions = new Dictionary { @@ -75,6 +77,11 @@ public IReadOnlyDictionary CreateStartupOptions(ProtocolOptions startupOptions.Add(StartupOptionsFactory.NoCompactOption, "true"); } + if (supportedOptionsInitializer?.GetTabletInfo() != null && supportedOptionsInitializer.GetTabletInfo().IsEnabled()) + { + startupOptions.Add(StartupOptionsFactory.TabletsRoutingV1Option, "true"); + } + startupOptions.Add(StartupOptionsFactory.DriverNameOption, AssemblyHelpers.GetAssemblyTitle(typeof(StartupOptionsFactory))); startupOptions.Add( StartupOptionsFactory.DriverVersionOption, AssemblyHelpers.GetAssemblyInformationalVersion(typeof(StartupOptionsFactory))); diff --git a/src/Cassandra/Requests/StartupRequestFactory.cs b/src/Cassandra/Requests/StartupRequestFactory.cs index e443fdbd2..b2b01ad70 100644 --- a/src/Cassandra/Requests/StartupRequestFactory.cs +++ b/src/Cassandra/Requests/StartupRequestFactory.cs @@ -14,6 +14,8 @@ // limitations under the License. // +using Cassandra.Connections.Control; + namespace Cassandra.Requests { internal class StartupRequestFactory : IStartupRequestFactory @@ -25,9 +27,9 @@ public StartupRequestFactory(IStartupOptionsFactory optionsFactory) _optionsFactory = optionsFactory; } - public IRequest CreateStartupRequest(ProtocolOptions protocolOptions) + public IRequest CreateStartupRequest(ProtocolOptions protocolOptions, ISupportedOptionsInitializer supportedOptionsInitializer) { - return new StartupRequest(_optionsFactory.CreateStartupOptions(protocolOptions)); + return new StartupRequest(_optionsFactory.CreateStartupOptions(protocolOptions, supportedOptionsInitializer)); } } } \ No newline at end of file