diff --git a/Samples/Dapper/ElasticDapper.csproj b/Samples/Dapper/ElasticDapper.csproj index 8305c65..6eed8f5 100644 --- a/Samples/Dapper/ElasticDapper.csproj +++ b/Samples/Dapper/ElasticDapper.csproj @@ -5,14 +5,13 @@ - - - - - + + + + \ No newline at end of file diff --git a/Samples/Dapper/Program.cs b/Samples/Dapper/Program.cs index dafc787..f60417c 100644 --- a/Samples/Dapper/Program.cs +++ b/Samples/Dapper/Program.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using Dapper; using DapperExtensions; using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement; @@ -67,89 +67,74 @@ public static void Main() Console.Write("Enter a name for a new Blog: "); var name = Console.ReadLine(); - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey( + key: s_tenantId1, + connectionString: connStrBldr.ConnectionString, + options: ConnectionOptions.Validate)) { - using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey( - key: s_tenantId1, - connectionString: connStrBldr.ConnectionString, - options: ConnectionOptions.Validate)) - { - var blog = new Blog { Name = name }; - sqlconn.Insert(blog); - } - }); + var blog = new Blog { Name = name }; + sqlconn.Insert(blog); + } - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey( + key: s_tenantId1, + connectionString: connStrBldr.ConnectionString, + options: ConnectionOptions.Validate)) { - using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey( - key: s_tenantId1, - connectionString: connStrBldr.ConnectionString, - options: ConnectionOptions.Validate)) + // Display all Blogs for tenant 1 + IEnumerable result = sqlconn.Query(@" + SELECT * + FROM Blog + ORDER BY Name"); + + Console.WriteLine("All blogs for tenant id {0}:", s_tenantId1); + foreach (var item in result) { - // Display all Blogs for tenant 1 - IEnumerable result = sqlconn.Query(@" - SELECT * - FROM Blog - ORDER BY Name"); - - Console.WriteLine("All blogs for tenant id {0}:", s_tenantId1); - foreach (var item in result) - { - Console.WriteLine(item.Name); - } + Console.WriteLine(item.Name); } - }); + } // Do work for tenant 2 :-) // Here I am going to illustrate how to integrate // with DapperExtensions which saves us the T-SQL // - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey( + key: s_tenantId2, + connectionString: connStrBldr.ConnectionString, + options: ConnectionOptions.Validate)) { - using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey( - key: s_tenantId2, - connectionString: connStrBldr.ConnectionString, - options: ConnectionOptions.Validate)) + // Display all Blogs for tenant 2 + IEnumerable result = sqlconn.GetList(); + Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2); + foreach (var item in result) { - // Display all Blogs for tenant 2 - IEnumerable result = sqlconn.GetList(); - Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2); - foreach (var item in result) - { - Console.WriteLine(item.Name); - } + Console.WriteLine(item.Name); } - }); + } // Create and save a new Blog Console.Write("Enter a name for a new Blog: "); var name2 = Console.ReadLine(); - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey( + key: s_tenantId2, + connectionString: connStrBldr.ConnectionString, + options: ConnectionOptions.Validate)) { - using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey( - key: s_tenantId2, - connectionString: connStrBldr.ConnectionString, - options: ConnectionOptions.Validate)) - { - var blog = new Blog { Name = name2 }; - sqlconn.Insert(blog); - } - }); + var blog = new Blog { Name = name2 }; + sqlconn.Insert(blog); + } - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(s_tenantId2, connStrBldr.ConnectionString, ConnectionOptions.Validate)) { - using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(s_tenantId2, connStrBldr.ConnectionString, ConnectionOptions.Validate)) + // Display all Blogs for tenant 2 + IEnumerable result = sqlconn.GetList(); + Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2); + foreach (var item in result) { - // Display all Blogs for tenant 2 - IEnumerable result = sqlconn.GetList(); - Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2); - foreach (var item in result) - { - Console.WriteLine(item.Name); - } + Console.WriteLine(item.Name); } - }); + } Console.WriteLine("Press any key to exit..."); Console.ReadKey(); @@ -168,6 +153,7 @@ private static void CreateSchema(string shardName) using (SqlConnection conn = new SqlConnection(connStrBldr.ToString())) { + conn.RetryLogicProvider = SqlDatabaseUtils.SqlRetryProvider; conn.Open(); conn.Execute(@" IF (OBJECT_ID('[dbo].[Blog]', 'U') IS NULL) diff --git a/Samples/Dapper/Sharding.cs b/Samples/Dapper/Sharding.cs index a7625cf..f92b404 100644 --- a/Samples/Dapper/Sharding.cs +++ b/Samples/Dapper/Sharding.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement; namespace ElasticDapper diff --git a/Samples/Dapper/SqlDatabaseUtils.cs b/Samples/Dapper/SqlDatabaseUtils.cs index 66de772..e235ead 100644 --- a/Samples/Dapper/SqlDatabaseUtils.cs +++ b/Samples/Dapper/SqlDatabaseUtils.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling; +using Microsoft.Data.SqlClient; namespace ElasticDapper { @@ -11,12 +11,22 @@ namespace ElasticDapper /// internal static class SqlDatabaseUtils { + /// + /// Create a retry logic provider + /// + public static SqlRetryLogicBaseProvider SqlRetryProvider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(SqlRetryPolicy); + /// /// Gets the retry policy to use for connections to SQL Server. /// - public static RetryPolicy SqlRetryPolicy + private static SqlRetryLogicOption SqlRetryPolicy => new() { - get { return new RetryPolicy(10, TimeSpan.FromSeconds(5)); } - } + // Tries 5 times before throwing an exception + NumberOfTries = 5, + // Preferred gap time to delay before retry + DeltaTime = TimeSpan.FromSeconds(1), + // Maximum gap time for each delay time before retry + MaxTimeInterval = TimeSpan.FromSeconds(20) + }; } } diff --git a/Samples/EFCodeFirst/ElasticScaleContext.cs b/Samples/EFCodeFirst/ElasticScaleContext.cs index d42ab1e..9ce1039 100644 --- a/Samples/EFCodeFirst/ElasticScaleContext.cs +++ b/Samples/EFCodeFirst/ElasticScaleContext.cs @@ -3,7 +3,7 @@ using System.Data.Common; using System.Data.Entity; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement; namespace EFCodeFirstElasticScale diff --git a/Samples/EFCodeFirst/ElasticScaleDbConfiguration.cs b/Samples/EFCodeFirst/ElasticScaleDbConfiguration.cs index 3c6b3b8..364f009 100644 --- a/Samples/EFCodeFirst/ElasticScaleDbConfiguration.cs +++ b/Samples/EFCodeFirst/ElasticScaleDbConfiguration.cs @@ -17,7 +17,7 @@ public ElasticScaleDbConfiguration() // the SqlAzureExecutionStrategy which would lead to wrong retry behavior // since it would not use the OpenConnectionForKey call. // For more details, see http://msdn.microsoft.com/en-us/data/dn456835.aspx. - this.SetExecutionStrategy("System.Data.SqlClient", () => new DefaultExecutionStrategy()); + this.SetExecutionStrategy("Microsoft.Data.SqlClient", () => new DefaultExecutionStrategy()); // There are legitimate cases, typically for migrations during development // using Add-Migration and Update-Datase, where a connection to a diff --git a/Samples/EFCodeFirst/EntityFrameworkCodeFirst.csproj b/Samples/EFCodeFirst/EntityFrameworkCodeFirst.csproj index bd76408..203c518 100644 --- a/Samples/EFCodeFirst/EntityFrameworkCodeFirst.csproj +++ b/Samples/EFCodeFirst/EntityFrameworkCodeFirst.csproj @@ -5,10 +5,6 @@ - - - - @@ -17,4 +13,7 @@ + + + \ No newline at end of file diff --git a/Samples/EFCodeFirst/Program.cs b/Samples/EFCodeFirst/Program.cs index cec4e9e..3dc2721 100644 --- a/Samples/EFCodeFirst/Program.cs +++ b/Samples/EFCodeFirst/Program.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using System.Linq; //////////////////////////////////////////////////////////////////////////////////////// @@ -58,81 +58,66 @@ public static void Main() Console.Write("Enter a name for a new Blog: "); var name = Console.ReadLine(); - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId1, connStrBldr.ConnectionString)) { - using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId1, connStrBldr.ConnectionString)) - { - var blog = new Blog { Name = name }; - db.Blogs.Add(blog); - db.SaveChanges(); - } - }); + var blog = new Blog { Name = name }; + db.Blogs.Add(blog); + db.SaveChanges(); + } - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId1, connStrBldr.ConnectionString)) { - using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId1, connStrBldr.ConnectionString)) + // Display all Blogs for tenant 1 + var query = from b in db.Blogs + orderby b.Name + select b; + + Console.WriteLine("All blogs for tenant id {0}:", s_tenantId1); + foreach (var item in query) { - // Display all Blogs for tenant 1 - var query = from b in db.Blogs - orderby b.Name - select b; - - Console.WriteLine("All blogs for tenant id {0}:", s_tenantId1); - foreach (var item in query) - { - Console.WriteLine(item.Name); - } + Console.WriteLine(item.Name); } - }); + } // Do work for tenant 2 :-) - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString)) { - using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString)) + // Display all Blogs from the database + var query = from b in db.Blogs + orderby b.Name + select b; + + Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2); + foreach (var item in query) { - // Display all Blogs from the database - var query = from b in db.Blogs - orderby b.Name - select b; - - Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2); - foreach (var item in query) - { - Console.WriteLine(item.Name); - } + Console.WriteLine(item.Name); } - }); + } // Create and save a new Blog Console.Write("Enter a name for a new Blog: "); var name2 = Console.ReadLine(); - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString)) { - using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString)) - { - var blog = new Blog { Name = name2 }; - db.Blogs.Add(blog); - db.SaveChanges(); - } - }); + var blog = new Blog { Name = name2 }; + db.Blogs.Add(blog); + db.SaveChanges(); + } - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString)) { - using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString)) + // Display all Blogs from the database + var query = from b in db.Blogs + orderby b.Name + select b; + + Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2); + foreach (var item in query) { - // Display all Blogs from the database - var query = from b in db.Blogs - orderby b.Name - select b; - - Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2); - foreach (var item in query) - { - Console.WriteLine(item.Name); - } + Console.WriteLine(item.Name); } - }); + } Console.WriteLine("Press any key to exit..."); Console.ReadKey(); diff --git a/Samples/EFCodeFirst/Sharding.cs b/Samples/EFCodeFirst/Sharding.cs index 8ad1457..e9ead47 100644 --- a/Samples/EFCodeFirst/Sharding.cs +++ b/Samples/EFCodeFirst/Sharding.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using System.Linq; using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement; diff --git a/Samples/EFCodeFirst/SqlDatabaseUtils.cs b/Samples/EFCodeFirst/SqlDatabaseUtils.cs index 2e63840..96830f4 100644 --- a/Samples/EFCodeFirst/SqlDatabaseUtils.cs +++ b/Samples/EFCodeFirst/SqlDatabaseUtils.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using Microsoft.Data.SqlClient; using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling; namespace EFCodeFirstElasticScale @@ -11,12 +12,23 @@ namespace EFCodeFirstElasticScale /// internal static class SqlDatabaseUtils { + /// + /// Create a retry logic provider + /// + public static SqlRetryLogicBaseProvider SqlRetryProvider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(SqlRetryPolicy); + /// /// Gets the retry policy to use for connections to SQL Server. /// - public static RetryPolicy SqlRetryPolicy + private static SqlRetryLogicOption SqlRetryPolicy => new() { - get { return new RetryPolicy(10, TimeSpan.FromSeconds(5)); } - } + // Tries 5 times before throwing an exception + NumberOfTries = 5, + // Preferred gap time to delay before retry + DeltaTime = TimeSpan.FromSeconds(1), + // Maximum gap time for each delay time before retry + MaxTimeInterval = TimeSpan.FromSeconds(20) + }; + } } diff --git a/Samples/EFMultiTenant/ElasticScaleContext.cs b/Samples/EFMultiTenant/ElasticScaleContext.cs index b9d8ef6..99ac2c8 100644 --- a/Samples/EFMultiTenant/ElasticScaleContext.cs +++ b/Samples/EFMultiTenant/ElasticScaleContext.cs @@ -3,7 +3,7 @@ using System; using System.Data.Entity; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement; namespace EFMultiTenantElasticScale diff --git a/Samples/EFMultiTenant/ElasticScaleDbConfiguration.cs b/Samples/EFMultiTenant/ElasticScaleDbConfiguration.cs index 6945bac..aea6369 100644 --- a/Samples/EFMultiTenant/ElasticScaleDbConfiguration.cs +++ b/Samples/EFMultiTenant/ElasticScaleDbConfiguration.cs @@ -17,7 +17,7 @@ public ElasticScaleDbConfiguration() // the SqlAzureExecutionStrategy which would lead to wrong retry behavior // since it would not use the OpenConnectionForKey call. // For more details, see http://msdn.microsoft.com/en-us/data/dn456835.aspx. - this.SetExecutionStrategy("System.Data.SqlClient", () => new DefaultExecutionStrategy()); + this.SetExecutionStrategy("Microsoft.Data.SqlClient", () => new DefaultExecutionStrategy()); // There are legitimate cases, typically for migrations during development // using Add-Migration and Update-Datase, where a connection to a diff --git a/Samples/EFMultiTenant/EntityFrameworkMultiTenant.csproj b/Samples/EFMultiTenant/EntityFrameworkMultiTenant.csproj index 7a49864..51a43c3 100644 --- a/Samples/EFMultiTenant/EntityFrameworkMultiTenant.csproj +++ b/Samples/EFMultiTenant/EntityFrameworkMultiTenant.csproj @@ -5,10 +5,6 @@ - - - - @@ -20,4 +16,7 @@ + + + diff --git a/Samples/EFMultiTenant/Program.cs b/Samples/EFMultiTenant/Program.cs index 143f546..7832e74 100644 --- a/Samples/EFMultiTenant/Program.cs +++ b/Samples/EFMultiTenant/Program.cs @@ -3,7 +3,7 @@ using System; using System.Data.Entity.Infrastructure; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using System.Linq; //////////////////////////////////////////////////////////////////////////////////////// @@ -69,69 +69,62 @@ public static void Main() Console.Write("\nEnter a name for a new Blog for TenantId {0}: ", tenantId); var name = Console.ReadLine(); - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + using (var db = new ElasticScaleContext(sharding.ShardMap, tenantId, connStrBldr.ConnectionString)) { - using (var db = new ElasticScaleContext(sharding.ShardMap, tenantId, connStrBldr.ConnectionString)) + var blog = new Blog { Name = name, TenantId = tenantId }; // must specify TenantId unless using default constraints to auto-populate + db.Blogs.Add(blog); + db.SaveChanges(); + + // If Row-Level Security is enabled, tenants will only display their own blogs + // Otherwise, tenants will see blogs for all tenants on the shard db + var query = from b in db.Blogs + orderby b.Name + select b; + + Console.WriteLine("All blogs for TenantId {0}:", tenantId); + foreach (var item in query) { - var blog = new Blog { Name = name, TenantId = tenantId }; // must specify TenantId unless using default constraints to auto-populate - db.Blogs.Add(blog); - db.SaveChanges(); - - // If Row-Level Security is enabled, tenants will only display their own blogs - // Otherwise, tenants will see blogs for all tenants on the shard db - var query = from b in db.Blogs - orderby b.Name - select b; - - Console.WriteLine("All blogs for TenantId {0}:", tenantId); - foreach (var item in query) - { - Console.WriteLine(item.Name); - } + Console.WriteLine(item.Name); } - }); + } } // Example query via ADO.NET SqlClient // If Row-Level Security is enabled, only Tenant 4's blogs will be listed - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + // Note: We are using a wrapper function OpenDDRConnection that automatically set SESSION_CONTEXT with the specified TenantId. + // This is a best practice to ensure that SESSION_CONTEXT is always set before executing a query. + using (SqlConnection conn = ElasticScaleContext.OpenDDRConnection(sharding.ShardMap, s_tenantId4, connStrBldr.ConnectionString)) { - // Note: We are using a wrapper function OpenDDRConnection that automatically set SESSION_CONTEXT with the specified TenantId. - // This is a best practice to ensure that SESSION_CONTEXT is always set before executing a query. - using (SqlConnection conn = ElasticScaleContext.OpenDDRConnection(sharding.ShardMap, s_tenantId4, connStrBldr.ConnectionString)) - { - SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = @"SELECT * FROM Blogs"; + SqlCommand cmd = conn.CreateCommand(); + cmd.RetryLogicProvider = SqlDatabaseUtils.SqlRetryProvider; + cmd.CommandText = @"SELECT * FROM Blogs"; - Console.WriteLine("\n--\n\nAll blogs for TenantId {0} (using ADO.NET SqlClient):", s_tenantId4); - SqlDataReader reader = cmd.ExecuteReader(); - while (reader.Read()) - { - Console.WriteLine("{0}", reader["Name"]); - } + Console.WriteLine("\n--\n\nAll blogs for TenantId {0} (using ADO.NET SqlClient):", s_tenantId4); + SqlDataReader reader = cmd.ExecuteReader(); + while (reader.Read()) + { + Console.WriteLine("{0}", reader["Name"]); } - }); - + } + // Because of the RLS block predicate, attempting to insert a row for the wrong tenant will throw an error. Console.WriteLine("\n--\n\nTrying to create a new Blog for TenantId {0} while connected as TenantId {1}: ", s_tenantId2, s_tenantId3); - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + + using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId3, connStrBldr.ConnectionString)) { - using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId3, connStrBldr.ConnectionString)) + // Verify that block predicate prevents Tenant 3 from inserting rows for Tenant 2 + try { - // Verify that block predicate prevents Tenant 3 from inserting rows for Tenant 2 - try - { - var bad_blog = new Blog { Name = "BAD BLOG", TenantId = s_tenantId2 }; - db.Blogs.Add(bad_blog); - db.SaveChanges(); - Console.WriteLine("No error thrown - make sure your security policy has a block predicate on this table in each shard database."); - } - catch (DbUpdateException) - { - Console.WriteLine("Can't insert blog for incorrect tenant."); - } + var bad_blog = new Blog { Name = "BAD BLOG", TenantId = s_tenantId2 }; + db.Blogs.Add(bad_blog); + db.SaveChanges(); + Console.WriteLine("No error thrown - make sure your security policy has a block predicate on this table in each shard database."); } - }); + catch (DbUpdateException) + { + Console.WriteLine("Can't insert blog for incorrect tenant."); + } + } Console.WriteLine("\n--\n\nPress any key to exit..."); Console.ReadKey(); diff --git a/Samples/EFMultiTenant/Sharding.cs b/Samples/EFMultiTenant/Sharding.cs index 2a601dd..7668456 100644 --- a/Samples/EFMultiTenant/Sharding.cs +++ b/Samples/EFMultiTenant/Sharding.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using System.Linq; using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement; diff --git a/Samples/EFMultiTenant/SqlDatabaseUtils.cs b/Samples/EFMultiTenant/SqlDatabaseUtils.cs index 7a10b1b..03d777a 100644 --- a/Samples/EFMultiTenant/SqlDatabaseUtils.cs +++ b/Samples/EFMultiTenant/SqlDatabaseUtils.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using Microsoft.Data.SqlClient; using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling; namespace EFMultiTenantElasticScale @@ -11,12 +12,23 @@ namespace EFMultiTenantElasticScale /// internal static class SqlDatabaseUtils { + /// + /// Create a retry logic provider + /// + public static SqlRetryLogicBaseProvider SqlRetryProvider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(SqlRetryPolicy); + /// /// Gets the retry policy to use for connections to SQL Server. /// - public static RetryPolicy SqlRetryPolicy + private static SqlRetryLogicOption SqlRetryPolicy => new() { - get { return new RetryPolicy(10, TimeSpan.FromSeconds(5)); } - } + // Tries 5 times before throwing an exception + NumberOfTries = 5, + // Preferred gap time to delay before retry + DeltaTime = TimeSpan.FromSeconds(1), + // Maximum gap time for each delay time before retry + MaxTimeInterval = TimeSpan.FromSeconds(20) + }; + } } diff --git a/Samples/ElasticScaleStarterKit/Configuration.cs b/Samples/ElasticScaleStarterKit/Configuration.cs index 3d1fd33..c6f7578 100644 --- a/Samples/ElasticScaleStarterKit/Configuration.cs +++ b/Samples/ElasticScaleStarterKit/Configuration.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Configuration; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; namespace ElasticScaleStarterKit { @@ -81,13 +81,15 @@ public static string GetCredentialsConnectionString() string integratedSecurityString = ConfigurationManager.AppSettings["IntegratedSecurity"]; bool integratedSecurity = integratedSecurityString != null && bool.Parse(integratedSecurityString); + var entraSecurityString = ConfigurationManager.AppSettings["EntraSecurity"]; + var entraSecurity = entraSecurityString != null && bool.Parse(entraSecurityString); + SqlConnectionStringBuilder connStr = new SqlConnectionStringBuilder - { - // DDR and MSQ require credentials to be set - UserID = userId, - Password = password, + { IntegratedSecurity = integratedSecurity, + Authentication = entraSecurity ? SqlAuthenticationMethod.ActiveDirectoryInteractive : SqlAuthenticationMethod.NotSpecified, + // DataSource and InitialCatalog cannot be set for DDR and MSQ APIs, because these APIs will // determine the DataSource and InitialCatalog for you. // @@ -100,6 +102,14 @@ public static string GetCredentialsConnectionString() ApplicationName = "ESC_SKv1.0", ConnectTimeout = 30 }; + + if (!integratedSecurity && !entraSecurity) + { + // DDR and MSQ require credentials to be set + connStr.UserID = userId; + connStr.Password = password; + } + return connStr.ToString(); } } diff --git a/Samples/ElasticScaleStarterKit/DataDependentRoutingSample.cs b/Samples/ElasticScaleStarterKit/DataDependentRoutingSample.cs index 780b0f7..05bb1dc 100644 --- a/Samples/ElasticScaleStarterKit/DataDependentRoutingSample.cs +++ b/Samples/ElasticScaleStarterKit/DataDependentRoutingSample.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using System.Linq; using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement; @@ -64,30 +64,30 @@ private static void AddCustomer( // Open and execute the command with retry for transient faults. Note that if the command fails, the connection is closed, so // the entire block is wrapped in a retry. This means that only one command should be executed per block, since if we had multiple // commands then the first command may be executed multiple times if later commands fail. - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + + // Looks up the key in the shard map and opens a connection to the shard + using (SqlConnection conn = shardMap.OpenConnectionForKey(customerId, credentialsConnectionString)) { - // Looks up the key in the shard map and opens a connection to the shard - using (SqlConnection conn = shardMap.OpenConnectionForKey(customerId, credentialsConnectionString)) - { - // Create a simple command that will insert or update the customer information - SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = @" - IF EXISTS (SELECT 1 FROM Customers WHERE CustomerId = @customerId) - UPDATE Customers - SET Name = @name, RegionId = @regionId - WHERE CustomerId = @customerId - ELSE - INSERT INTO Customers (CustomerId, Name, RegionId) - VALUES (@customerId, @name, @regionId)"; - cmd.Parameters.AddWithValue("@customerId", customerId); - cmd.Parameters.AddWithValue("@name", name); - cmd.Parameters.AddWithValue("@regionId", regionId); - cmd.CommandTimeout = 60; - - // Execute the command - cmd.ExecuteNonQuery(); - } - }); + // Create a simple command that will insert or update the customer information + SqlCommand cmd = conn.CreateCommand(); + cmd.RetryLogicProvider = SqlDatabaseUtils.SqlRetryProvider; + + cmd.CommandText = @" + IF EXISTS (SELECT 1 FROM Customers WHERE CustomerId = @customerId) + UPDATE Customers + SET Name = @name, RegionId = @regionId + WHERE CustomerId = @customerId + ELSE + INSERT INTO Customers (CustomerId, Name, RegionId) + VALUES (@customerId, @name, @regionId)"; + cmd.Parameters.AddWithValue("@customerId", customerId); + cmd.Parameters.AddWithValue("@name", name); + cmd.Parameters.AddWithValue("@regionId", regionId); + cmd.CommandTimeout = 60; + + // Execute the command + cmd.ExecuteNonQuery(); + } } /// @@ -99,26 +99,24 @@ private static void AddOrder( int customerId, int productId) { - SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() => + // Looks up the key in the shard map and opens a connection to the shard + using (SqlConnection conn = shardMap.OpenConnectionForKey(customerId, credentialsConnectionString)) { - // Looks up the key in the shard map and opens a connection to the shard - using (SqlConnection conn = shardMap.OpenConnectionForKey(customerId, credentialsConnectionString)) - { - // Create a simple command that will insert a new order - SqlCommand cmd = conn.CreateCommand(); - - // Create a simple command - cmd.CommandText = @"INSERT INTO dbo.Orders (CustomerId, OrderDate, ProductId) - VALUES (@customerId, @orderDate, @productId)"; - cmd.Parameters.AddWithValue("@customerId", customerId); - cmd.Parameters.AddWithValue("@orderDate", DateTime.Now.Date); - cmd.Parameters.AddWithValue("@productId", productId); - cmd.CommandTimeout = 60; - - // Execute the command - cmd.ExecuteNonQuery(); - } - }); + // Create a simple command that will insert a new order + SqlCommand cmd = conn.CreateCommand(); + cmd.RetryLogicProvider = SqlDatabaseUtils.SqlRetryProvider; + + // Create a simple command + cmd.CommandText = @"INSERT INTO dbo.Orders (CustomerId, OrderDate, ProductId) + VALUES (@customerId, @orderDate, @productId)"; + cmd.Parameters.AddWithValue("@customerId", customerId); + cmd.Parameters.AddWithValue("@orderDate", DateTime.Now.Date); + cmd.Parameters.AddWithValue("@productId", productId); + cmd.CommandTimeout = 60; + + // Execute the command + cmd.ExecuteNonQuery(); + } ConsoleUtils.WriteInfo("Inserted order for customer ID: {0}", customerId); } diff --git a/Samples/ElasticScaleStarterKit/ElasticScaleStarterKit.csproj b/Samples/ElasticScaleStarterKit/ElasticScaleStarterKit.csproj index a523329..9abd73f 100644 --- a/Samples/ElasticScaleStarterKit/ElasticScaleStarterKit.csproj +++ b/Samples/ElasticScaleStarterKit/ElasticScaleStarterKit.csproj @@ -5,10 +5,8 @@ - - - - + + @@ -20,4 +18,7 @@ + + + \ No newline at end of file diff --git a/Samples/ElasticScaleStarterKit/SqlDatabaseUtils.cs b/Samples/ElasticScaleStarterKit/SqlDatabaseUtils.cs index 6049668..ef7313f 100644 --- a/Samples/ElasticScaleStarterKit/SqlDatabaseUtils.cs +++ b/Samples/ElasticScaleStarterKit/SqlDatabaseUtils.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using System.IO; using System.Text; using System.Threading; @@ -34,11 +34,10 @@ public static bool TryConnectToSqlDatabase() try { - using (ReliableSqlConnection conn = new ReliableSqlConnection( - connectionString, - SqlRetryPolicy, - SqlRetryPolicy)) + using (SqlConnection conn = new SqlConnection( + connectionString)) { + conn.RetryLogicProvider = SqlRetryProvider; conn.Open(); } @@ -55,18 +54,20 @@ public static bool TryConnectToSqlDatabase() public static bool DatabaseExists(string server, string db) { - using (ReliableSqlConnection conn = new ReliableSqlConnection( - Configuration.GetConnectionString(server, MasterDatabaseName), - SqlRetryPolicy, - SqlRetryPolicy)) + using (SqlConnection conn = new SqlConnection( + Configuration.GetConnectionString(server, MasterDatabaseName))) { + conn.RetryLogicProvider = SqlRetryProvider; conn.Open(); SqlCommand cmd = conn.CreateCommand(); + cmd.RetryLogicProvider = SqlRetryProvider; + cmd.CommandText = "select count(*) from sys.databases where name = @dbname"; cmd.Parameters.AddWithValue("@dbname", db); cmd.CommandTimeout = 60; - int count = conn.ExecuteCommand(cmd); + + int count = (int)cmd.ExecuteScalar(); bool exists = count > 0; return exists; @@ -75,18 +76,20 @@ public static bool DatabaseExists(string server, string db) public static bool DatabaseIsOnline(string server, string db) { - using (ReliableSqlConnection conn = new ReliableSqlConnection( - Configuration.GetConnectionString(server, MasterDatabaseName), - SqlRetryPolicy, - SqlRetryPolicy)) + using (SqlConnection conn = new SqlConnection( + Configuration.GetConnectionString(server, MasterDatabaseName))) { + conn.RetryLogicProvider = SqlRetryProvider; conn.Open(); SqlCommand cmd = conn.CreateCommand(); + cmd.RetryLogicProvider = SqlRetryProvider; + cmd.CommandText = "select count(*) from sys.databases where name = @dbname and state = 0"; // online cmd.Parameters.AddWithValue("@dbname", db); cmd.CommandTimeout = 60; - int count = conn.ExecuteCommand(cmd); + + int count = (int)cmd.ExecuteScalar(); bool exists = count > 0; return exists; @@ -96,35 +99,33 @@ public static bool DatabaseIsOnline(string server, string db) public static void CreateDatabase(string server, string db) { ConsoleUtils.WriteInfo("Creating database {0}", db); - using (ReliableSqlConnection conn = new ReliableSqlConnection( - Configuration.GetConnectionString(server, MasterDatabaseName), - SqlRetryPolicy, - SqlRetryPolicy)) + using (SqlConnection conn = new SqlConnection( + Configuration.GetConnectionString(server, MasterDatabaseName))) { + conn.RetryLogicProvider = SqlRetryProvider; conn.Open(); SqlCommand cmd = conn.CreateCommand(); // Determine if we are connecting to Azure SQL DB cmd.CommandText = "SELECT SERVERPROPERTY('EngineEdition')"; cmd.CommandTimeout = 60; - int engineEdition = conn.ExecuteCommand(cmd); + cmd.RetryLogicProvider = SqlRetryProvider; + + int engineEdition = (int)cmd.ExecuteScalar(); if (engineEdition == 5) { // Azure SQL DB - SqlRetryPolicy.ExecuteAction(() => - { - if (!DatabaseExists(server, db)) - { - // Begin creation (which is async for Standard/Premium editions) - cmd.CommandText = string.Format( - "CREATE DATABASE {0} (EDITION = '{1}')", - BracketEscapeName(db), - Configuration.DatabaseEdition); - cmd.CommandTimeout = 60; - cmd.ExecuteNonQuery(); - } - }); + if (!DatabaseExists(server, db)) + { + // Begin creation (which is async for Standard/Premium editions) + cmd.CommandText = string.Format( + "CREATE DATABASE {0} (EDITION = '{1}')", + BracketEscapeName(db), + Configuration.DatabaseEdition); + cmd.CommandTimeout = 180; + cmd.ExecuteNonQuery(); + } // Wait for the operation to complete while (!DatabaseIsOnline(server, db)) @@ -139,7 +140,7 @@ public static void CreateDatabase(string server, string db) { // Other edition of SQL DB cmd.CommandText = string.Format("CREATE DATABASE {0}", BracketEscapeName(db)); - conn.ExecuteCommand(cmd); + cmd.ExecuteNonQuery(); } } } @@ -147,18 +148,17 @@ public static void CreateDatabase(string server, string db) public static void DropDatabase(string server, string db) { ConsoleUtils.WriteInfo("Dropping database {0}", db); - using (ReliableSqlConnection conn = new ReliableSqlConnection( - Configuration.GetConnectionString(server, MasterDatabaseName), - SqlRetryPolicy, - SqlRetryPolicy)) + using (SqlConnection conn = new SqlConnection( + Configuration.GetConnectionString(server, MasterDatabaseName))) { + conn.RetryLogicProvider = SqlRetryProvider; conn.Open(); SqlCommand cmd = conn.CreateCommand(); // Determine if we are connecting to Azure SQL DB cmd.CommandText = "SELECT SERVERPROPERTY('EngineEdition')"; cmd.CommandTimeout = 60; - int engineEdition = conn.ExecuteCommand(cmd); + int engineEdition = (int)cmd.ExecuteScalar(); // Drop the database if (engineEdition == 5) @@ -182,13 +182,13 @@ public static void DropDatabase(string server, string db) public static void ExecuteSqlScript(string server, string db, string schemaFile) { ConsoleUtils.WriteInfo("Executing script {0}", schemaFile); - using (ReliableSqlConnection conn = new ReliableSqlConnection( - Configuration.GetConnectionString(server, db), - SqlRetryPolicy, - SqlRetryPolicy)) + using (SqlConnection conn = new SqlConnection( + Configuration.GetConnectionString(server, db))) { + conn.RetryLogicProvider = SqlRetryProvider; conn.Open(); SqlCommand cmd = conn.CreateCommand(); + cmd.RetryLogicProvider = SqlRetryProvider; // Read the commands from the sql script file IEnumerable commands = ReadSqlScript(schemaFile); @@ -197,7 +197,7 @@ public static void ExecuteSqlScript(string server, string db, string schemaFile) { cmd.CommandText = command; cmd.CommandTimeout = 60; - conn.ExecuteCommand(cmd); + cmd.ExecuteNonQuery(); } } } @@ -234,68 +234,20 @@ private static string BracketEscapeName(string sqlName) return '[' + sqlName.Replace("]", "]]") + ']'; } - /// - /// Gets the retry policy to use for connections to SQL Server. - /// - public static RetryPolicy SqlRetryPolicy - { - get - { - return new RetryPolicy(10, TimeSpan.FromSeconds(5)); - } - } + // Create a retry logic provider + public static SqlRetryLogicBaseProvider SqlRetryProvider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(SqlRetryPolicy); /// - /// Extended sql transient error detection strategy that performs additional transient error - /// checks besides the ones done by the enterprise library. + /// Gets the retry policy to use for connections to SQL Server. /// - private class ExtendedSqlDatabaseTransientErrorDetectionStrategy : ITransientErrorDetectionStrategy + private static SqlRetryLogicOption SqlRetryPolicy => new() { - /// - /// Enterprise transient error detection strategy. - /// - private SqlDatabaseTransientErrorDetectionStrategy _sqltransientErrorDetectionStrategy = new SqlDatabaseTransientErrorDetectionStrategy(); - - /// - /// Checks with enterprise library's default handler to see if the error is transient, additionally checks - /// for such errors using the code in the in function. - /// - /// Exception being checked. - /// true if exception is considered transient, false otherwise. - public bool IsTransient(Exception ex) - { - return _sqltransientErrorDetectionStrategy.IsTransient(ex) || IsTransientException(ex); - } - - /// - /// Detects transient errors not currently considered as transient by the enterprise library's strategy. - /// - /// Input exception. - /// true if exception is considered transient, false otherwise. - private static bool IsTransientException(Exception ex) - { - SqlException se = ex as SqlException; - - if (se != null && se.InnerException != null) - { - Win32Exception we = se.InnerException as Win32Exception; - - if (we != null) - { - switch (we.NativeErrorCode) - { - case 0x102: - // Transient wait expired error resulting in timeout - return true; - case 0x121: - // Transient semaphore wait expired error resulting in timeout - return true; - } - } - } - - return false; - } - } + // Tries 5 times before throwing an exception + NumberOfTries = 5, + // Preferred gap time to delay before retry + DeltaTime = TimeSpan.FromSeconds(1), + // Maximum gap time for each delay time before retry + MaxTimeInterval = TimeSpan.FromSeconds(20) + }; } } diff --git a/Samples/ShardSqlCmd/Program.cs b/Samples/ShardSqlCmd/Program.cs index 5ce8a42..53b7ad2 100644 --- a/Samples/ShardSqlCmd/Program.cs +++ b/Samples/ShardSqlCmd/Program.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using System.Diagnostics; using System.Linq; using System.Text; diff --git a/Samples/ShardSqlCmd/ShardSqlCmd.csproj b/Samples/ShardSqlCmd/ShardSqlCmd.csproj index 432852a..5f83b3b 100644 --- a/Samples/ShardSqlCmd/ShardSqlCmd.csproj +++ b/Samples/ShardSqlCmd/ShardSqlCmd.csproj @@ -6,9 +6,9 @@ - + - + diff --git a/Src/ElasticScale.Client/Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj b/Src/ElasticScale.Client/Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj index ac4c846..26ce352 100644 --- a/Src/ElasticScale.Client/Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj +++ b/Src/ElasticScale.Client/Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj @@ -9,7 +9,7 @@ Microsoft net6.0 Microsoft;Elastic;Scale;Azure;SQL;DB;Database;Shard;Sharding;Management;Query;azureofficial - Updated to net6.0 and migrated from System.Data.SqlClient to Microsoft.Data.SqlClient. + Updated to net6.0 and migrated from Microsoft.Data.SqlClient to Microsoft.Data.SqlClient. Icon.png https://github.com/Azure/elastic-db-tools MIT @@ -24,7 +24,7 @@ - + @@ -51,11 +51,4 @@ PerformanceCounters.Designer.cs - - - - 2.1.2 - - - diff --git a/Test/ElasticScale.ClientTestCommon/Microsoft.Azure.SqlDatabase.ElasticScale.ClientTestCommon.csproj b/Test/ElasticScale.ClientTestCommon/Microsoft.Azure.SqlDatabase.ElasticScale.ClientTestCommon.csproj index cfb54d1..b1b401c 100644 --- a/Test/ElasticScale.ClientTestCommon/Microsoft.Azure.SqlDatabase.ElasticScale.ClientTestCommon.csproj +++ b/Test/ElasticScale.ClientTestCommon/Microsoft.Azure.SqlDatabase.ElasticScale.ClientTestCommon.csproj @@ -6,7 +6,7 @@ - - + + \ No newline at end of file diff --git a/Test/ElasticScale.Query.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj b/Test/ElasticScale.Query.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj index 97b9f29..6ae32d3 100644 --- a/Test/ElasticScale.Query.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj +++ b/Test/ElasticScale.Query.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj @@ -7,10 +7,9 @@ - - - - + + + diff --git a/Test/ElasticScale.Query.UnitTests/MultiShardTestUtils.cs b/Test/ElasticScale.Query.UnitTests/MultiShardTestUtils.cs index e012536..e16cb1b 100644 --- a/Test/ElasticScale.Query.UnitTests/MultiShardTestUtils.cs +++ b/Test/ElasticScale.Query.UnitTests/MultiShardTestUtils.cs @@ -47,12 +47,12 @@ internal static class MultiShardTestUtils /// /// Connection string for local shard user. /// - internal static string ShardConnectionString = @"Integrated Security=SSPI;"; + internal static string ShardConnectionString = @"Integrated Security=SSPI;TrustServerCertificate=True;"; /// /// Connection string for global shard map manager operations. /// - internal static string ShardMapManagerConnectionString = @"Data Source=localhost;Initial Catalog=ShardMapManager;Integrated Security=SSPI;"; + internal static string ShardMapManagerConnectionString = @"Data Source=localhost;Initial Catalog=ShardMapManager;Integrated Security=SSPI;TrustServerCertificate=True;"; /// /// Name of the database where the ShardMapManager persists its data. @@ -214,6 +214,8 @@ private static string GetTestConnectionString(string database) builder.DataSource = s_serverLocation; builder.IntegratedSecurity = true; builder.InitialCatalog = database; + builder.TrustServerCertificate = true; + return builder.ConnectionString; } diff --git a/Test/ElasticScale.ShardManagement.UnitTests/Globals.cs b/Test/ElasticScale.ShardManagement.UnitTests/Globals.cs index c706ca2..21035ab 100644 --- a/Test/ElasticScale.ShardManagement.UnitTests/Globals.cs +++ b/Test/ElasticScale.ShardManagement.UnitTests/Globals.cs @@ -22,22 +22,22 @@ internal static class Globals /// /// Connection string for global shard map manager for Integrated Auth /// - private const string ShardMapManagerConnString = ShardMapManagerConnStringBase + "Integrated Security=SSPI;"; + private const string ShardMapManagerConnString = ShardMapManagerConnStringBase + "Integrated Security=SSPI;TrustServerCertificate=True;"; /// /// Connection string for global shard map manager for Sql Auth /// - private const string ShardMapManagerConnStringForSqlAuth = ShardMapManagerConnStringBase + "Integrated Security=False;"; + private const string ShardMapManagerConnStringForSqlAuth = ShardMapManagerConnStringBase + "Integrated Security=False;TrustServerCertificate=True;"; /// /// Connect string for local shard user. /// - private const string ShardUserConnString = @"Integrated Security=SSPI;"; + private const string ShardUserConnString = @"Integrated Security=SSPI;TrustServerCertificate=True;"; /// /// Connect string for local shard user. /// - private const string ShardUserConnStringForSqlAuth = @"User={0};Password={1}"; + private const string ShardUserConnStringForSqlAuth = @"User={0};Password={1};TrustServerCertificate=True;"; /// /// shardMapManager datasource name for unit tests. @@ -57,7 +57,7 @@ internal static class Globals /// /// Connection string for connecting to test server. /// - internal const string ShardMapManagerTestConnectionString = @"Data Source=" + Globals.ShardMapManagerTestsDatasourceName + ";Integrated Security=SSPI;"; + internal const string ShardMapManagerTestConnectionString = @"Data Source=" + Globals.ShardMapManagerTestsDatasourceName + ";Integrated Security=SSPI;TrustServerCertificate=True;"; /// /// Query to create database. diff --git a/Test/ElasticScale.ShardManagement.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.csproj b/Test/ElasticScale.ShardManagement.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.csproj index d755f90..dcde649 100644 --- a/Test/ElasticScale.ShardManagement.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.csproj +++ b/Test/ElasticScale.ShardManagement.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.csproj @@ -7,10 +7,9 @@ - - - - + + + diff --git a/Test/ElasticScale.ShardManagement.UnitTests/ScenarioTests.cs b/Test/ElasticScale.ShardManagement.UnitTests/ScenarioTests.cs index 26a1067..d24ebd1 100644 --- a/Test/ElasticScale.ShardManagement.UnitTests/ScenarioTests.cs +++ b/Test/ElasticScale.ShardManagement.UnitTests/ScenarioTests.cs @@ -308,14 +308,14 @@ public void BasicScenarioDefaultShardMaps() { // Also verify we can connect to the shard with Sql Auth, and Sql Auth using a secure credential using (shardForConnection.OpenConnectionAsync( - string.Empty, + "TrustServerCertificate=True;", Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName), ConnectionOptions.None).Result) { } using (shardForConnection.OpenConnectionAsync( - string.Empty, + "TrustServerCertificate=True;", Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName)).Result) { } @@ -1142,7 +1142,7 @@ public void BasicScenarioRangeShardMaps() // Cover the OpenConnectionForKey overloads using (SqlConnection conn = newMultiTenantShardMap.OpenConnectionForKey( 20, - string.Empty, + "TrustServerCertificate=True;", Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName))) { } @@ -1237,7 +1237,7 @@ public void BasicScenarioRangeShardMaps() // Cover the OpenConnectionForKeyAsync overloads using (SqlConnection conn = multiTenantShardMap.OpenConnectionForKeyAsync( 20, - string.Empty, + "TrustServerCertificate=True;", Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName), ConnectionOptions.None).Result) { @@ -1245,7 +1245,7 @@ public void BasicScenarioRangeShardMaps() using (SqlConnection conn = multiTenantShardMap.OpenConnectionForKeyAsync( 20, - string.Empty, + "TrustServerCertificate=True;", Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName)).Result) { } diff --git a/Test/ElasticScale.ShardManagement.UnitTests/ShardMapTests.cs b/Test/ElasticScale.ShardManagement.UnitTests/ShardMapTests.cs index a1ee56a..a2bf280 100644 --- a/Test/ElasticScale.ShardManagement.UnitTests/ShardMapTests.cs +++ b/Test/ElasticScale.ShardManagement.UnitTests/ShardMapTests.cs @@ -221,12 +221,12 @@ public void CreateShardDefault() } // Validate that we can connect to the shard using a secure Sql Auth Credential - using (sNew.OpenConnection(string.Empty, Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName))) + using (sNew.OpenConnection("TrustServerCertificate=True;", Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName))) { } using (sNew.OpenConnection( - string.Empty, + "TrustServerCertificate=True;", Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName), ConnectionOptions.Validate)) {