From 5cca72f5cddac163d714c4b54487fe6ae5d49ff0 Mon Sep 17 00:00:00 2001 From: OmnipotentOwl <1769881+OmnipotentOwl@users.noreply.github.com> Date: Sat, 26 Oct 2024 19:11:30 -0400 Subject: [PATCH 1/3] chore: Organize Comos Db Clustering files into existing provider folder structures --- .../CosmosClusteringOptions.cs | 17 ---------- .../CosmosGatewayListProvider.cs | 0 .../{ => Membership}/CosmosMembershipTable.cs | 0 .../Options/CosmosClusteringOptions.cs | 32 +++++++++++++++++++ 4 files changed, 32 insertions(+), 17 deletions(-) delete mode 100644 src/Azure/Orleans.Clustering.Cosmos/CosmosClusteringOptions.cs rename src/Azure/Orleans.Clustering.Cosmos/{ => Membership}/CosmosGatewayListProvider.cs (100%) rename src/Azure/Orleans.Clustering.Cosmos/{ => Membership}/CosmosMembershipTable.cs (100%) create mode 100644 src/Azure/Orleans.Clustering.Cosmos/Options/CosmosClusteringOptions.cs diff --git a/src/Azure/Orleans.Clustering.Cosmos/CosmosClusteringOptions.cs b/src/Azure/Orleans.Clustering.Cosmos/CosmosClusteringOptions.cs deleted file mode 100644 index 0398c7fce8..0000000000 --- a/src/Azure/Orleans.Clustering.Cosmos/CosmosClusteringOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Orleans.Clustering.Cosmos; - -/// -/// Options for configuring Azure Cosmos DB clustering. -/// -public class CosmosClusteringOptions : CosmosOptions -{ - private const string ORLEANS_CLUSTER_CONTAINER = "OrleansCluster"; - - /// - /// Initializes a new instance. - /// - public CosmosClusteringOptions() - { - ContainerName = ORLEANS_CLUSTER_CONTAINER; - } -} diff --git a/src/Azure/Orleans.Clustering.Cosmos/CosmosGatewayListProvider.cs b/src/Azure/Orleans.Clustering.Cosmos/Membership/CosmosGatewayListProvider.cs similarity index 100% rename from src/Azure/Orleans.Clustering.Cosmos/CosmosGatewayListProvider.cs rename to src/Azure/Orleans.Clustering.Cosmos/Membership/CosmosGatewayListProvider.cs diff --git a/src/Azure/Orleans.Clustering.Cosmos/CosmosMembershipTable.cs b/src/Azure/Orleans.Clustering.Cosmos/Membership/CosmosMembershipTable.cs similarity index 100% rename from src/Azure/Orleans.Clustering.Cosmos/CosmosMembershipTable.cs rename to src/Azure/Orleans.Clustering.Cosmos/Membership/CosmosMembershipTable.cs diff --git a/src/Azure/Orleans.Clustering.Cosmos/Options/CosmosClusteringOptions.cs b/src/Azure/Orleans.Clustering.Cosmos/Options/CosmosClusteringOptions.cs new file mode 100644 index 0000000000..5ffc7419f5 --- /dev/null +++ b/src/Azure/Orleans.Clustering.Cosmos/Options/CosmosClusteringOptions.cs @@ -0,0 +1,32 @@ +namespace Orleans.Clustering.Cosmos; + +/// +/// Options for configuring Azure Cosmos DB clustering. +/// +public class CosmosClusteringOptions : CosmosOptions +{ + private const string ORLEANS_CLUSTER_CONTAINER = "OrleansCluster"; + + /// + /// Initializes a new instance. + /// + public CosmosClusteringOptions() + { + ContainerName = ORLEANS_CLUSTER_CONTAINER; + } +} + +/// +/// Configuration validator for . +/// +public class CosmosClusteringOptionsValidator : CosmosOptionsValidator +{ + /// + /// Initializes a new instance of the class. + /// + /// The option to be validated. + /// The option name to be validated. + public CosmosClusteringOptionsValidator(CosmosClusteringOptions options, string name) : base(options, name) + { + } +} \ No newline at end of file From 2c1aee296f8e690f14bdd34b0e49656a4b9fa067 Mon Sep 17 00:00:00 2001 From: OmnipotentOwl <1769881+OmnipotentOwl@users.noreply.github.com> Date: Sat, 26 Oct 2024 19:11:41 -0400 Subject: [PATCH 2/3] Add InternalsVisibleTo attribute for Tester.AzureUtils Added a `using` directive for `System.Runtime.CompilerServices` and an assembly attribute `[assembly: InternalsVisibleTo("Tester.AzureUtils")]` to make internal types visible to the `Tester.AzureUtils` assembly. --- src/Azure/Orleans.Clustering.Cosmos/Properties/AssemblyInfo.cs | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/Azure/Orleans.Clustering.Cosmos/Properties/AssemblyInfo.cs diff --git a/src/Azure/Orleans.Clustering.Cosmos/Properties/AssemblyInfo.cs b/src/Azure/Orleans.Clustering.Cosmos/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..3a3d99f3cc --- /dev/null +++ b/src/Azure/Orleans.Clustering.Cosmos/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Tester.AzureUtils")] From ff3874cffb1a9ac8949f5dc1fa7336e58b35a055 Mon Sep 17 00:00:00 2001 From: OmnipotentOwl <1769881+OmnipotentOwl@users.noreply.github.com> Date: Sat, 26 Oct 2024 19:12:40 -0400 Subject: [PATCH 3/3] Add CosmosClusteringProviderBuilder for Orleans clustering Introduce CosmosClusteringProviderBuilder class implementing IProviderBuilder and IProviderBuilder interfaces. Register the class as a provider for both "Silo" and "Client" roles. Implement Configure methods to set up Cosmos DB clustering options and client configuration. Import necessary namespaces to support the new functionality. This adds support for using the Cosmos DB Clustering Provider from Orleans IConfiguration setup. --- .../CosmosClusteringProviderBuilder.cs | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/Azure/Orleans.Clustering.Cosmos/CosmosClusteringProviderBuilder.cs diff --git a/src/Azure/Orleans.Clustering.Cosmos/CosmosClusteringProviderBuilder.cs b/src/Azure/Orleans.Clustering.Cosmos/CosmosClusteringProviderBuilder.cs new file mode 100644 index 0000000000..87d343474f --- /dev/null +++ b/src/Azure/Orleans.Clustering.Cosmos/CosmosClusteringProviderBuilder.cs @@ -0,0 +1,115 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Orleans; +using Orleans.Clustering.Cosmos; +using Orleans.Hosting; +using Orleans.Providers; + +[assembly: RegisterProvider("Cosmos", "Clustering", "Silo", typeof(CosmosClusteringProviderBuilder))] +[assembly: RegisterProvider("Cosmos", "Clustering", "Client", typeof(CosmosClusteringProviderBuilder))] + +namespace Orleans.Hosting; + +internal sealed class CosmosClusteringProviderBuilder : IProviderBuilder, IProviderBuilder +{ + public void Configure(ISiloBuilder builder, string name, IConfigurationSection configurationSection) => + builder.UseCosmosClustering(optionsBuilder => + optionsBuilder.Configure((options, services) => + { + var databaseName = configurationSection[nameof(options.DatabaseName)]; + if (!string.IsNullOrEmpty(databaseName)) + { + options.DatabaseName = databaseName; + } + var containerName = configurationSection[nameof(options.ContainerName)]; + if (!string.IsNullOrEmpty(containerName)) + { + options.ContainerName = containerName; + } + if (bool.TryParse(configurationSection[nameof(options.IsResourceCreationEnabled)], out var irce)) + { + options.IsResourceCreationEnabled = irce; + } + if(int.TryParse(configurationSection[nameof(options.DatabaseThroughput)], out var dt)) + { + options.DatabaseThroughput = dt; + } + if(bool.TryParse(configurationSection[nameof(options.CleanResourcesOnInitialization)], out var croi)) + { + options.CleanResourcesOnInitialization = croi; + } + + var serviceKey = configurationSection["ServiceKey"]; + if(!string.IsNullOrEmpty(serviceKey)) + { + options.ConfigureCosmosClient(sp=> + new ValueTask(sp.GetRequiredKeyedService(serviceKey))); + } + else + { + var connectionName = configurationSection["ConnectionName"]; + var connectionString = configurationSection["ConnectionString"]; + if (!string.IsNullOrEmpty(connectionName) && string.IsNullOrEmpty(connectionString)) + { + var rootConfiguration = services.GetRequiredService(); + connectionString = rootConfiguration.GetConnectionString(connectionName); + } + + if (!string.IsNullOrEmpty(connectionString)) + { + options.ConfigureCosmosClient(connectionString); + } + } + })); + + public void Configure(IClientBuilder builder, string name, IConfigurationSection configurationSection) => + builder.UseCosmosGatewayListProvider(optionsBuilder => + optionsBuilder.Configure((options, services) => + { + var databaseName = configurationSection[nameof(options.DatabaseName)]; + if (!string.IsNullOrEmpty(databaseName)) + { + options.DatabaseName = databaseName; + } + var containerName = configurationSection[nameof(options.ContainerName)]; + if (!string.IsNullOrEmpty(containerName)) + { + options.ContainerName = containerName; + } + if (bool.TryParse(configurationSection[nameof(options.IsResourceCreationEnabled)], out var irce)) + { + options.IsResourceCreationEnabled = irce; + } + if (int.TryParse(configurationSection[nameof(options.DatabaseThroughput)], out var dt)) + { + options.DatabaseThroughput = dt; + } + if (bool.TryParse(configurationSection[nameof(options.CleanResourcesOnInitialization)], out var croi)) + { + options.CleanResourcesOnInitialization = croi; + } + + var serviceKey = configurationSection["ServiceKey"]; + if (!string.IsNullOrEmpty(serviceKey)) + { + options.ConfigureCosmosClient(sp => + new ValueTask(sp.GetRequiredKeyedService(serviceKey))); + } + else + { + // Construct a connection multiplexer from a connection string. + var connectionName = configurationSection["ConnectionName"]; + var connectionString = configurationSection["ConnectionString"]; + if (!string.IsNullOrEmpty(connectionName) && string.IsNullOrEmpty(connectionString)) + { + var rootConfiguration = services.GetRequiredService(); + connectionString = rootConfiguration.GetConnectionString(connectionName); + } + + if (!string.IsNullOrEmpty(connectionString)) + { + options.ConfigureCosmosClient(connectionString); + } + } + })); +} \ No newline at end of file