From fb2fda3a0e9817ae7793da519e666a46c9a0681c Mon Sep 17 00:00:00 2001 From: Damir Imangulov Date: Wed, 13 Mar 2019 12:33:34 +0200 Subject: [PATCH 1/6] CosmosDb provider support for a current region option CosmosDb provider doesn't support a configuration option for a current region Fix #15007 --- .../CosmosDbContextOptionsExtensions.cs | 31 +++++++++++++++++++ .../Internal/CosmosDbOptionExtension.cs | 18 +++++++++++ .../Storage/Internal/CosmosClientWrapper.cs | 25 +++++++++++---- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/EFCore.Cosmos/Extensions/CosmosDbContextOptionsExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosDbContextOptionsExtensions.cs index a601e17278c..58d353d0efc 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosDbContextOptionsExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosDbContextOptionsExtensions.cs @@ -52,5 +52,36 @@ public static DbContextOptionsBuilder UseCosmos( return optionsBuilder; } + + public static DbContextOptionsBuilder UseCosmos( + [NotNull] this DbContextOptionsBuilder optionsBuilder, + [NotNull] string serviceEndPoint, + [NotNull] string authKeyOrResourceToken, + [NotNull] string databaseName, + [NotNull] string regionName, + [CanBeNull] Action cosmosOptionsAction = null) + { + Check.NotNull(optionsBuilder, nameof(optionsBuilder)); + Check.NotNull(serviceEndPoint, nameof(serviceEndPoint)); + Check.NotEmpty(authKeyOrResourceToken, nameof(authKeyOrResourceToken)); + Check.NotEmpty(databaseName, nameof(databaseName)); + Check.NotEmpty(regionName, nameof(regionName)); + + var extension = optionsBuilder.Options.FindExtension() + ?? new CosmosDbOptionsExtension(); + + extension = extension + .WithServiceEndPoint(serviceEndPoint) + .WithAuthKeyOrResourceToken(authKeyOrResourceToken) + .WithDatabaseName(databaseName) + .WithCurrentRegion(regionName) + ; + + ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); + + cosmosOptionsAction?.Invoke(new CosmosDbContextOptionsBuilder(optionsBuilder)); + + return optionsBuilder; + } } } diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs index 20640621fcd..748f73cc92c 100644 --- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs +++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs @@ -18,6 +18,7 @@ public class CosmosDbOptionsExtension : IDbContextOptionsExtension private string _databaseName; private Func _executionStrategyFactory; private string _logFragment; + private string _currentRegion; public CosmosDbOptionsExtension() { @@ -29,6 +30,7 @@ protected CosmosDbOptionsExtension(CosmosDbOptionsExtension copyFrom) _authKeyOrResourceToken = copyFrom._authKeyOrResourceToken; _databaseName = copyFrom._databaseName; _executionStrategyFactory = copyFrom._executionStrategyFactory; + _currentRegion = copyFrom._currentRegion; } public virtual string ServiceEndPoint => _serviceEndPoint; @@ -64,6 +66,17 @@ public virtual CosmosDbOptionsExtension WithDatabaseName(string database) return clone; } + public virtual string CurrentRegion => _currentRegion; + + public virtual CosmosDbOptionsExtension WithCurrentRegion(string currentRegion) + { + var clone = Clone(); + + clone._currentRegion = currentRegion; + + return clone; + } + /// /// A factory for creating the default , or null if none has been /// configured. @@ -121,6 +134,11 @@ public string LogFragment builder.Append("Database=").Append(_databaseName).Append(' '); + if (_currentRegion != null) + { + builder.Append("CurrentRegion=").Append(_currentRegion).Append(' '); + } + _logFragment = builder.ToString(); } diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs index 75a93680867..a993b0ddf4a 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs @@ -33,6 +33,7 @@ public class CosmosClientWrapper : IDisposable private static readonly string _userAgent = " Microsoft.EntityFrameworkCore.Cosmos/" + ProductInfo.GetVersion(); public static readonly JsonSerializer Serializer = new JsonSerializer(); + private readonly string _currentRegion; static CosmosClientWrapper() { @@ -50,18 +51,30 @@ public CosmosClientWrapper( _databaseId = options.DatabaseName; _endPoint = options.ServiceEndPoint; _authKey = options.AuthKeyOrResourceToken; + _currentRegion = options.CurrentRegion; _executionStrategyFactory = executionStrategyFactory; _commandLogger = commandLogger; } private CosmosClient Client => _client - ?? (_client = new CosmosClient( - new CosmosConfiguration(_endPoint, _authKey) - { - UserAgentSuffix = _userAgent, - ConnectionMode = ConnectionMode.Direct - })); + ?? (_client = BuildCosmosClient()); + + private CosmosClient BuildCosmosClient() + { + var configuration = new CosmosConfiguration(_endPoint, _authKey) + { + UserAgentSuffix = _userAgent, + ConnectionMode = ConnectionMode.Direct, + }; + + if (_currentRegion != null) + { + configuration.UseCurrentRegion(_currentRegion); + } + + return new CosmosClient(configuration); + } public bool CreateDatabaseIfNotExists() => _executionStrategyFactory.Create().Execute( From c4bc97d9f0525a174d065657ac798a042fd2d01b Mon Sep 17 00:00:00 2001 From: Damir Imangulov Date: Tue, 19 Mar 2019 08:53:55 +0200 Subject: [PATCH 2/6] Revert "CosmosDb provider support for a current region option" This reverts commit fb2fda3a0e9817ae7793da519e666a46c9a0681c. --- .../CosmosDbContextOptionsExtensions.cs | 31 ------------------- .../Internal/CosmosDbOptionExtension.cs | 18 ----------- .../Storage/Internal/CosmosClientWrapper.cs | 25 ++++----------- 3 files changed, 6 insertions(+), 68 deletions(-) diff --git a/src/EFCore.Cosmos/Extensions/CosmosDbContextOptionsExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosDbContextOptionsExtensions.cs index 58d353d0efc..a601e17278c 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosDbContextOptionsExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosDbContextOptionsExtensions.cs @@ -52,36 +52,5 @@ public static DbContextOptionsBuilder UseCosmos( return optionsBuilder; } - - public static DbContextOptionsBuilder UseCosmos( - [NotNull] this DbContextOptionsBuilder optionsBuilder, - [NotNull] string serviceEndPoint, - [NotNull] string authKeyOrResourceToken, - [NotNull] string databaseName, - [NotNull] string regionName, - [CanBeNull] Action cosmosOptionsAction = null) - { - Check.NotNull(optionsBuilder, nameof(optionsBuilder)); - Check.NotNull(serviceEndPoint, nameof(serviceEndPoint)); - Check.NotEmpty(authKeyOrResourceToken, nameof(authKeyOrResourceToken)); - Check.NotEmpty(databaseName, nameof(databaseName)); - Check.NotEmpty(regionName, nameof(regionName)); - - var extension = optionsBuilder.Options.FindExtension() - ?? new CosmosDbOptionsExtension(); - - extension = extension - .WithServiceEndPoint(serviceEndPoint) - .WithAuthKeyOrResourceToken(authKeyOrResourceToken) - .WithDatabaseName(databaseName) - .WithCurrentRegion(regionName) - ; - - ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); - - cosmosOptionsAction?.Invoke(new CosmosDbContextOptionsBuilder(optionsBuilder)); - - return optionsBuilder; - } } } diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs index 748f73cc92c..20640621fcd 100644 --- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs +++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs @@ -18,7 +18,6 @@ public class CosmosDbOptionsExtension : IDbContextOptionsExtension private string _databaseName; private Func _executionStrategyFactory; private string _logFragment; - private string _currentRegion; public CosmosDbOptionsExtension() { @@ -30,7 +29,6 @@ protected CosmosDbOptionsExtension(CosmosDbOptionsExtension copyFrom) _authKeyOrResourceToken = copyFrom._authKeyOrResourceToken; _databaseName = copyFrom._databaseName; _executionStrategyFactory = copyFrom._executionStrategyFactory; - _currentRegion = copyFrom._currentRegion; } public virtual string ServiceEndPoint => _serviceEndPoint; @@ -66,17 +64,6 @@ public virtual CosmosDbOptionsExtension WithDatabaseName(string database) return clone; } - public virtual string CurrentRegion => _currentRegion; - - public virtual CosmosDbOptionsExtension WithCurrentRegion(string currentRegion) - { - var clone = Clone(); - - clone._currentRegion = currentRegion; - - return clone; - } - /// /// A factory for creating the default , or null if none has been /// configured. @@ -134,11 +121,6 @@ public string LogFragment builder.Append("Database=").Append(_databaseName).Append(' '); - if (_currentRegion != null) - { - builder.Append("CurrentRegion=").Append(_currentRegion).Append(' '); - } - _logFragment = builder.ToString(); } diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs index a993b0ddf4a..75a93680867 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs @@ -33,7 +33,6 @@ public class CosmosClientWrapper : IDisposable private static readonly string _userAgent = " Microsoft.EntityFrameworkCore.Cosmos/" + ProductInfo.GetVersion(); public static readonly JsonSerializer Serializer = new JsonSerializer(); - private readonly string _currentRegion; static CosmosClientWrapper() { @@ -51,30 +50,18 @@ public CosmosClientWrapper( _databaseId = options.DatabaseName; _endPoint = options.ServiceEndPoint; _authKey = options.AuthKeyOrResourceToken; - _currentRegion = options.CurrentRegion; _executionStrategyFactory = executionStrategyFactory; _commandLogger = commandLogger; } private CosmosClient Client => _client - ?? (_client = BuildCosmosClient()); - - private CosmosClient BuildCosmosClient() - { - var configuration = new CosmosConfiguration(_endPoint, _authKey) - { - UserAgentSuffix = _userAgent, - ConnectionMode = ConnectionMode.Direct, - }; - - if (_currentRegion != null) - { - configuration.UseCurrentRegion(_currentRegion); - } - - return new CosmosClient(configuration); - } + ?? (_client = new CosmosClient( + new CosmosConfiguration(_endPoint, _authKey) + { + UserAgentSuffix = _userAgent, + ConnectionMode = ConnectionMode.Direct + })); public bool CreateDatabaseIfNotExists() => _executionStrategyFactory.Create().Execute( From 5b63201a10d15195e13cad21c9ee701ea40027e6 Mon Sep 17 00:00:00 2001 From: Damir Imangulov Date: Tue, 19 Mar 2019 10:07:26 +0200 Subject: [PATCH 3/6] CosmosDb provider support for a current region option CosmosDb provider doesn't support a configuration option for a current region Fix #15007 --- .../CosmosDbContextOptionsBuilder.cs | 7 ++++++ .../Internal/CosmosDbOptionExtension.cs | 12 ++++++++++ .../Storage/Internal/CosmosClientWrapper.cs | 24 +++++++++++++++---- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs b/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs index 3257598d265..8d939da2f26 100644 --- a/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs +++ b/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs @@ -30,6 +30,13 @@ public virtual CosmosDbContextOptionsBuilder ExecutionStrategy( [NotNull] Func getExecutionStrategy) => WithOption(e => e.WithExecutionStrategyFactory(Check.NotNull(getExecutionStrategy, nameof(getExecutionStrategy)))); + /// + /// Configures the context to use the provided Region. + /// + /// CosmosDB region name + public virtual CosmosDbContextOptionsBuilder Region(string region) + => WithOption(e => e.WithRegion(Check.NotNull(region, nameof(region)))); + /// /// Sets an option by cloning the extension used to store the settings. This ensures the builder /// does not modify options that are already in use elsewhere. diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs index 20640621fcd..e9351b1f6a8 100644 --- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs +++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs @@ -18,6 +18,7 @@ public class CosmosDbOptionsExtension : IDbContextOptionsExtension private string _databaseName; private Func _executionStrategyFactory; private string _logFragment; + private string _region; public CosmosDbOptionsExtension() { @@ -64,6 +65,17 @@ public virtual CosmosDbOptionsExtension WithDatabaseName(string database) return clone; } + public virtual string Region => _region; + + public virtual CosmosDbOptionsExtension WithRegion(string region) + { + var clone = Clone(); + + clone._region = region; + + return clone; + } + /// /// A factory for creating the default , or null if none has been /// configured. diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs index 75a93680867..a473feb763b 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs @@ -33,6 +33,7 @@ public class CosmosClientWrapper : IDisposable private static readonly string _userAgent = " Microsoft.EntityFrameworkCore.Cosmos/" + ProductInfo.GetVersion(); public static readonly JsonSerializer Serializer = new JsonSerializer(); + private string _region; static CosmosClientWrapper() { @@ -50,6 +51,7 @@ public CosmosClientWrapper( _databaseId = options.DatabaseName; _endPoint = options.ServiceEndPoint; _authKey = options.AuthKeyOrResourceToken; + _region = options.Region; _executionStrategyFactory = executionStrategyFactory; _commandLogger = commandLogger; } @@ -57,11 +59,23 @@ public CosmosClientWrapper( private CosmosClient Client => _client ?? (_client = new CosmosClient( - new CosmosConfiguration(_endPoint, _authKey) - { - UserAgentSuffix = _userAgent, - ConnectionMode = ConnectionMode.Direct - })); + BuildCosmosConfiguration())); + + private CosmosConfiguration BuildCosmosConfiguration() + { + var configuration = new CosmosConfiguration(_endPoint, _authKey) + { + UserAgentSuffix = _userAgent, + ConnectionMode = ConnectionMode.Direct + }; + + if (_region != null) + { + configuration = configuration.UseCurrentRegion(_region); + } + + return configuration; + } public bool CreateDatabaseIfNotExists() => _executionStrategyFactory.Create().Execute( From c56281132996671b4744c6a4250b3e36f3e8b1f4 Mon Sep 17 00:00:00 2001 From: Damir Imangulov Date: Wed, 20 Mar 2019 09:55:07 +0200 Subject: [PATCH 4/6] Temporary commit to test the changes on windows (cosmosdb emulator doesn't work on MacOS) --- .../Internal/CosmosDbOptionExtension.cs | 1 + .../CosmosEndToEndTest.cs | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs index e9351b1f6a8..9af1d6fd2b3 100644 --- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs +++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs @@ -30,6 +30,7 @@ protected CosmosDbOptionsExtension(CosmosDbOptionsExtension copyFrom) _authKeyOrResourceToken = copyFrom._authKeyOrResourceToken; _databaseName = copyFrom._databaseName; _executionStrategyFactory = copyFrom._executionStrategyFactory; + _region = copyFrom._region; } public virtual string ServiceEndPoint => _serviceEndPoint; diff --git a/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs b/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs index 3ed536ac5e3..885ebed75ca 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs @@ -4,6 +4,8 @@ using System; using System.Linq; using System.Threading.Tasks; +using Microsoft.Azure.Cosmos; +using Microsoft.EntityFrameworkCore.Cosmos.Infrastructure.Internal; using Microsoft.EntityFrameworkCore.Cosmos.TestUtilities; using Microsoft.EntityFrameworkCore.TestUtilities; using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; @@ -362,6 +364,40 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) } } + [ConditionalFact] + public void Can_create_options_with_specified_region() + { + var regionName = CosmosRegions.EastAsia; + var options = new DbContextOptionsBuilder().UseCosmos( + "serviceEndPoint", + "authKeyOrResourceToken", + "databaseName", + o => { o.Region(regionName); }); + + var extension = options + .Options.FindExtension(); + + Assert.Equal(regionName, extension.Region); + } + + [ConditionalFact] + public void Should_throw_if_specified_region_is_wrong() + { + var regionName = "FakeRegion"; + + Action a = () => + { + var options = new DbContextOptionsBuilder().UseCosmos( + "serviceEndPoint", + "authKeyOrResourceToken", + "databaseName", + o => { o.Region(regionName); }); + }; + + var ex = Assert.Throws(a); + Assert.Equal("Current location is not a valid Azure region.", ex.Message); + } + [ConditionalFact] public async Task Can_add_update_delete_end_to_end_with_conflicting_id() { From d44f1eb87ffee297a5ff1cd9202b0e85c3a9c3f8 Mon Sep 17 00:00:00 2001 From: Damir Imangulov Date: Wed, 20 Mar 2019 10:07:25 +0200 Subject: [PATCH 5/6] Temporary commit to test the changes on windows (cosmosdb emulator doesn't work on MacOS) --- .../CosmosEndToEndTest.cs | 20 ++++++++++++++----- .../TestUtilities/CosmosTestStore.cs | 20 ++++++++++++------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs b/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs index 885ebed75ca..26b50a6346e 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs @@ -387,11 +387,21 @@ public void Should_throw_if_specified_region_is_wrong() Action a = () => { - var options = new DbContextOptionsBuilder().UseCosmos( - "serviceEndPoint", - "authKeyOrResourceToken", - "databaseName", - o => { o.Region(regionName); }); + using (var testDatabase = CosmosTestStore.CreateInitialized(DatabaseName, o => o.Region(regionName))) + { + var options = Fixture.CreateOptions(testDatabase); + + var customer = new Customer {Id = 42, Name = "Theon"}; + + using (var context = new CustomerContext(options)) + { + context.Database.EnsureCreated(); + + context.Add(customer); + + context.SaveChanges(); + } + } }; var ex = Assert.Throws(a); diff --git a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs index 98d27593963..f6c3b412ead 100644 --- a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs +++ b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs @@ -5,6 +5,8 @@ using System.IO; using System.Reflection; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.Cosmos.Infrastructure; +using Microsoft.EntityFrameworkCore.Cosmos.Infrastructure.Internal; using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -18,23 +20,23 @@ public class CosmosTestStore : TestStore private readonly TestStoreContext _storeContext; private readonly string _dataFilePath; - public static CosmosTestStore Create(string name) => new CosmosTestStore(name, shared: false); + public static CosmosTestStore Create(string name, Action extensionConfiguration = null) => new CosmosTestStore(name, shared: false, extensionConfiguration: extensionConfiguration); - public static CosmosTestStore CreateInitialized(string name) - => (CosmosTestStore)Create(name).Initialize(null, (Func)null, null); + public static CosmosTestStore CreateInitialized(string name, Action extensionConfiguration = null) + => (CosmosTestStore)Create(name, extensionConfiguration).Initialize(null, (Func)null, null); public static CosmosTestStore GetOrCreate(string name) => new CosmosTestStore(name); public static CosmosTestStore GetOrCreate(string name, string dataFilePath) => new CosmosTestStore(name, dataFilePath: dataFilePath); - private CosmosTestStore(string name, bool shared = true, string dataFilePath = null) + private CosmosTestStore(string name, bool shared = true, string dataFilePath = null, Action extensionConfiguration = null) : base(name, shared) { ConnectionUri = TestEnvironment.DefaultConnection; AuthToken = TestEnvironment.AuthToken; - _storeContext = new TestStoreContext(this); + _storeContext = new TestStoreContext(this, extensionConfiguration); if (dataFilePath != null) { @@ -148,15 +150,19 @@ public override void Dispose() private class TestStoreContext : DbContext { private readonly CosmosTestStore _testStore; + private readonly Action _extensionConfiguration; - public TestStoreContext(CosmosTestStore testStore) + public TestStoreContext(CosmosTestStore testStore, + Action extensionConfiguration) { _testStore = testStore; + _extensionConfiguration = extensionConfiguration; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseCosmos(_testStore.ConnectionUri, _testStore.AuthToken, _testStore.Name); + var extensionConfiguration = _extensionConfiguration ?? (_ => { }); + optionsBuilder.UseCosmos(_testStore.ConnectionUri, _testStore.AuthToken, _testStore.Name, extensionConfiguration); } } } From 91f668c56d18bff180bfdd55b2b2f2b127b04ea3 Mon Sep 17 00:00:00 2001 From: Damir Imangulov Date: Wed, 20 Mar 2019 10:29:31 +0200 Subject: [PATCH 6/6] CosmosDb provider support for a current region option Unit and end-to-end tests for the CosmosDbOptionsExtension.WithRegion configuration method Fix aspnet#15007 --- .../CosmosEndToEndTest.cs | 26 ++++++----- .../CosmosDbContextOptionsExtensionsTests.cs | 44 +++++++++++++++++++ 2 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 test/EFCore.Cosmos.Tests/Configuration/CosmosDbContextOptionsExtensionsTests.cs diff --git a/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs b/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs index 26b50a6346e..dab95f13e43 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CosmosEndToEndTest.cs @@ -365,19 +365,25 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) } [ConditionalFact] - public void Can_create_options_with_specified_region() + public void Should_not_throw_if_specified_region_is_right() { - var regionName = CosmosRegions.EastAsia; - var options = new DbContextOptionsBuilder().UseCosmos( - "serviceEndPoint", - "authKeyOrResourceToken", - "databaseName", - o => { o.Region(regionName); }); + var regionName = CosmosRegions.AustraliaCentral; - var extension = options - .Options.FindExtension(); + using (var testDatabase = CosmosTestStore.CreateInitialized(DatabaseName, o => o.Region(regionName))) + { + var options = Fixture.CreateOptions(testDatabase); + + var customer = new Customer { Id = 42, Name = "Theon" }; - Assert.Equal(regionName, extension.Region); + using (var context = new CustomerContext(options)) + { + context.Database.EnsureCreated(); + + context.Add(customer); + + context.SaveChanges(); + } + } } [ConditionalFact] diff --git a/test/EFCore.Cosmos.Tests/Configuration/CosmosDbContextOptionsExtensionsTests.cs b/test/EFCore.Cosmos.Tests/Configuration/CosmosDbContextOptionsExtensionsTests.cs new file mode 100644 index 00000000000..13e8c0cc894 --- /dev/null +++ b/test/EFCore.Cosmos.Tests/Configuration/CosmosDbContextOptionsExtensionsTests.cs @@ -0,0 +1,44 @@ +using Microsoft.Azure.Cosmos; +using Microsoft.EntityFrameworkCore.Cosmos.Infrastructure.Internal; +using Xunit; + +namespace Microsoft.EntityFrameworkCore.Cosmos.Configuration +{ + public class CosmosDbContextOptionsExtensionsTests + { + [Fact] + public void Can_create_options_with_specified_region() + { + var regionName = CosmosRegions.EastAsia; + var options = new DbContextOptionsBuilder().UseCosmos( + "serviceEndPoint", + "authKeyOrResourceToken", + "databaseName", + o => { o.Region(regionName); }); + + var extension = options + .Options.FindExtension(); + + Assert.Equal(regionName, extension.Region); + } + + /// + /// The region will be checked by the cosmosdb sdk, because the region list is not constant + /// + [Fact] + public void Can_create_options_with_wrong_region() + { + var regionName = "FakeRegion"; + var options = new DbContextOptionsBuilder().UseCosmos( + "serviceEndPoint", + "authKeyOrResourceToken", + "databaseName", + o => { o.Region(regionName); }); + + var extension = options + .Options.FindExtension(); + + Assert.Equal(regionName, extension.Region); + } + } +}