diff --git a/Microsoft.Azure.Cosmos/src/ConnectionPolicy.cs b/Microsoft.Azure.Cosmos/src/ConnectionPolicy.cs
index cd582f0c18..f77d95b856 100644
--- a/Microsoft.Azure.Cosmos/src/ConnectionPolicy.cs
+++ b/Microsoft.Azure.Cosmos/src/ConnectionPolicy.cs
@@ -50,7 +50,7 @@ public ConnectionPolicy()
this.RetryOptions = new RetryOptions();
this.EnableReadRequestsFallback = null;
this.ServerCertificateCustomValidationCallback = null;
-
+ this.AvailabilityStrategy = null;
this.CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions();
}
@@ -512,6 +512,34 @@ public bool? EnableAdvancedReplicaSelectionForTcp
set;
}
+ ///
+ /// Availability Strategy to be used for periods of high latency
+ ///
+ /// ///
+ /// An example on how to set an availability strategy custom serializer.
+ ///
+ /// { "East US", "Central US", "West US" } )
+ /// .WithAvailabilityStrategy(
+ /// AvailabilityStrategy.CrossRegionHedgingStrategy(
+ /// threshold: TimeSpan.FromMilliseconds(500),
+ /// thresholdStep: TimeSpan.FromMilliseconds(100)
+ /// ))
+ /// .Build();
+ /// ]]>
+ ///
+ ///
+ ///
+ /// The availability strategy in the example is a Cross Region Hedging Strategy.
+ /// These strategies take two values, a threshold and a threshold step.When a request that is sent
+ /// out takes longer than the threshold time, the SDK will hedge to the second region in the application preferred regions list.
+ /// If a response from either the primary request or the first hedged request is not received
+ /// after the threshold step time, the SDK will hedge to the third region and so on.
+ ///
+ public AvailabilityStrategy AvailabilityStrategy { get; set; }
+
///
/// (Direct/TCP) This is an advanced setting that controls the number of TCP connections that will be opened eagerly to each Cosmos DB back-end.
///
@@ -545,6 +573,15 @@ internal SessionRetryOptions SessionRetryOptions
set;
}
+ ///
+ /// A string containing the application name.
+ ///
+ internal string ApplicationName
+ {
+ get;
+ set;
+ }
+
///
/// GlobalEndpointManager will subscribe to this event if user updates the preferredLocations list in the Azure Cosmos DB service.
///
diff --git a/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs b/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs
index ac785c8068..3f60995b4a 100644
--- a/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs
+++ b/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs
@@ -54,13 +54,7 @@ public class CosmosClientOptions
private const string ConnectionStringAccountKey = "AccountKey";
private const string ConnectionStringDisableServerCertificateValidation = "DisableServerCertificateValidation";
- private const ApiType DefaultApiType = ApiType.None;
-
- ///
- /// Default thresholds for PPAF request hedging.
- ///
- private const int DefaultHedgingThresholdInMilliseconds = 1000;
- private const int DefaultHedgingThresholdStepInMilliseconds = 500;
+ private const ApiType DefaultApiType = ApiType.None;
///
/// Default request timeout
@@ -771,15 +765,6 @@ bool EnableRemoteRegionPreferredForSessionRetry
set => this.SessionRetryOptions.RemoteRegionPreferred = value;
}
- ///
- /// Gets or sets a value indicating whether partition-level failover is enabled. When this feature is enabled,
- /// the SDK by default applies a cross-region hedging strategy with a default threshold of 1 seconds.
- /// If an availability strategy is provided explicitly, then it will be honored, and the default policy wouldn't be applied. Note that
- /// the default availability strategy can be opted out by setting as the availability strategy in
- /// cosmos client options.
- ///
- internal bool EnablePartitionLevelFailover { get; set; } = ConfigurationManager.IsPartitionLevelFailoverEnabled(defaultValue: false);
-
///
/// Enable partition level circuit breaker (aka PPCB). For compute gateway use case, by default per partition automatic failover will be disabled, so does the PPCB.
/// If compute gateway chooses to enable PPAF, then the .NET SDK will enable PPCB by default, which will improve the read availability and latency. This would mean
@@ -1028,10 +1013,10 @@ internal virtual ConnectionPolicy GetConnectionPolicy(int clientId)
{
this.ValidateDirectTCPSettings();
this.ValidateLimitToEndpointSettings();
- this.InitializePartitionLevelFailoverWithDefaultHedging();
ConnectionPolicy connectionPolicy = new ConnectionPolicy()
- {
+ {
+ ApplicationName = this.ApplicationName,
MaxConnectionLimit = this.GatewayModeMaxConnectionLimit,
RequestTimeout = this.RequestTimeout,
ConnectionMode = this.ConnectionMode,
@@ -1044,14 +1029,14 @@ internal virtual ConnectionPolicy GetConnectionPolicy(int clientId)
MaxRequestsPerTcpConnection = this.MaxRequestsPerTcpConnection,
MaxTcpConnectionsPerEndpoint = this.MaxTcpConnectionsPerEndpoint,
EnableEndpointDiscovery = !this.LimitToEndpoint,
- EnablePartitionLevelFailover = this.EnablePartitionLevelFailover,
- EnablePartitionLevelCircuitBreaker = this.EnablePartitionLevelFailover || this.EnablePartitionLevelCircuitBreaker,
+ EnablePartitionLevelCircuitBreaker = this.EnablePartitionLevelCircuitBreaker,
PortReuseMode = this.portReuseMode,
EnableTcpConnectionEndpointRediscovery = this.EnableTcpConnectionEndpointRediscovery,
EnableAdvancedReplicaSelectionForTcp = this.EnableAdvancedReplicaSelectionForTcp,
HttpClientFactory = this.httpClientFactory,
ServerCertificateCustomValidationCallback = this.ServerCertificateCustomValidationCallback,
- CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions()
+ CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions(),
+ AvailabilityStrategy = this.AvailabilityStrategy,
};
if (this.CosmosClientTelemetryOptions != null)
@@ -1262,47 +1247,9 @@ internal UserAgentContainer CreateUserAgentContainerWithFeatures(int clientId)
return new UserAgentContainer(
clientId: clientId,
features: featureString,
- regionConfiguration: regionConfiguration,
- suffix: this.GetUserAgentSuffix());
- }
-
- internal void InitializePartitionLevelFailoverWithDefaultHedging()
- {
- if (this.EnablePartitionLevelFailover
- && this.AvailabilityStrategy == null)
- {
- // The default threshold is the minimum value of 1 second and a fraction (currently it's half) of
- // the request timeout value provided by the end customer.
- double defaultThresholdInMillis = Math.Min(CosmosClientOptions.DefaultHedgingThresholdInMilliseconds, this.RequestTimeout.TotalMilliseconds / 2);
-
- this.AvailabilityStrategy = AvailabilityStrategy.CrossRegionHedgingStrategy(
- threshold: TimeSpan.FromMilliseconds(defaultThresholdInMillis),
- thresholdStep: TimeSpan.FromMilliseconds(CosmosClientOptions.DefaultHedgingThresholdStepInMilliseconds));
- }
+ regionConfiguration: regionConfiguration,
+ suffix: this.ApplicationName);
}
-
- internal string GetUserAgentSuffix()
- {
- int featureFlag = 0;
- if (this.EnablePartitionLevelFailover)
- {
- featureFlag += (int)UserAgentFeatureFlags.PerPartitionAutomaticFailover;
- }
-
- if (this.EnablePartitionLevelFailover || this.EnablePartitionLevelCircuitBreaker)
- {
- featureFlag += (int)UserAgentFeatureFlags.PerPartitionCircuitBreaker;
- }
-
- if (featureFlag == 0)
- {
- return this.ApplicationName;
- }
-
- return string.IsNullOrEmpty(this.ApplicationName) ?
- $"F{featureFlag:X}" :
- $"F{featureFlag:X}|{this.ApplicationName}";
- }
///
/// This generates a key that added to the user agent to make it
diff --git a/Microsoft.Azure.Cosmos/src/DocumentClient.cs b/Microsoft.Azure.Cosmos/src/DocumentClient.cs
index e51bcf35e9..22a9b55c5a 100644
--- a/Microsoft.Azure.Cosmos/src/DocumentClient.cs
+++ b/Microsoft.Azure.Cosmos/src/DocumentClient.cs
@@ -112,6 +112,12 @@ internal partial class DocumentClient : IDisposable, IAuthorizationTokenProvider
private const int DefaultRntbdSendHangDetectionTimeSeconds = 10;
private const bool DefaultEnableCpuMonitor = true;
private const string DefaultInitTaskKey = "InitTaskKey";
+
+ ///
+ /// Default thresholds for PPAF request hedging.
+ ///
+ private const int DefaultHedgingThresholdInMilliseconds = 1000;
+ private const int DefaultHedgingThresholdStepInMilliseconds = 500;
private static readonly char[] resourceIdOrFullNameSeparators = new char[] { '/' };
private static readonly char[] resourceIdSeparators = new char[] { '/', '\\', '?', '#' };
@@ -425,8 +431,8 @@ internal DocumentClient(Uri serviceEndpoint,
transportClientHandlerFactory,
storeClientFactory)
{
- }
-
+ }
+
///
/// Initializes a new instance of the class using the
/// specified service endpoint, an authorization key (or resource token) and a connection policy
@@ -508,7 +514,7 @@ internal DocumentClient(Uri serviceEndpoint,
enableAsyncCacheExceptionNoSharing: this.enableAsyncCacheExceptionNoSharing);
this.chaosInterceptorFactory = chaosInterceptorFactory;
this.chaosInterceptor = chaosInterceptorFactory?.CreateInterceptor(this);
- this.isThinClientEnabled = ConfigurationManager.IsThinClientEnabled(defaultValue: false);
+ this.isThinClientEnabled = ConfigurationManager.IsThinClientEnabled(defaultValue: false);
this.Initialize(
serviceEndpoint: serviceEndpoint,
@@ -954,15 +960,8 @@ internal virtual void Initialize(Uri serviceEndpoint,
ServicePointAccessor servicePoint = ServicePointAccessor.FindServicePoint(this.ServiceEndpoint);
servicePoint.ConnectionLimit = this.ConnectionPolicy.MaxConnectionLimit;
}
-#endif
-
- this.GlobalEndpointManager = new GlobalEndpointManager(this, this.ConnectionPolicy, this.enableAsyncCacheExceptionNoSharing);
- this.PartitionKeyRangeLocation = this.ConnectionPolicy.EnablePartitionLevelFailover || this.ConnectionPolicy.EnablePartitionLevelCircuitBreaker
- ? new GlobalPartitionEndpointManagerCore(
- this.GlobalEndpointManager,
- this.ConnectionPolicy.EnablePartitionLevelFailover,
- this.ConnectionPolicy.EnablePartitionLevelCircuitBreaker)
- : GlobalPartitionEndpointManagerNoOp.Instance;
+#endif
+ this.GlobalEndpointManager = new GlobalEndpointManager(this, this.ConnectionPolicy, this.enableAsyncCacheExceptionNoSharing);
this.httpClient = CosmosHttpClientCore.CreateWithConnectionPolicy(
this.ApiType,
@@ -1003,13 +1002,6 @@ internal virtual void Initialize(Uri serviceEndpoint,
this.sessionContainer = new SessionContainer(this.ServiceEndpoint.Host);
}
- this.retryPolicy = new RetryPolicy(
- globalEndpointManager: this.GlobalEndpointManager,
- connectionPolicy: this.ConnectionPolicy,
- partitionKeyRangeLocationCache: this.PartitionKeyRangeLocation);
-
- this.ResetSessionTokenRetryPolicy = this.retryPolicy;
-
this.desiredConsistencyLevel = desiredConsistencyLevel;
// Setup the proxy to be used based on connection mode.
// For gateway: GatewayProxy.
@@ -1062,7 +1054,34 @@ private async Task GetInitializationTaskAsync(IStoreClientFactory storeCli
if (this.desiredConsistencyLevel.HasValue)
{
this.EnsureValidOverwrite(this.desiredConsistencyLevel.Value);
- }
+ }
+
+ bool isPPafEnabled = ConfigurationManager.IsPartitionLevelFailoverEnabled(defaultValue: false);
+ if (this.accountServiceConfiguration != null && this.accountServiceConfiguration.AccountProperties.EnablePartitionLevelFailover.HasValue)
+ {
+ isPPafEnabled = this.accountServiceConfiguration.AccountProperties.EnablePartitionLevelFailover.Value;
+ }
+
+ this.ConnectionPolicy.EnablePartitionLevelFailover = isPPafEnabled;
+ this.ConnectionPolicy.EnablePartitionLevelCircuitBreaker |= this.ConnectionPolicy.EnablePartitionLevelFailover;
+ this.ConnectionPolicy.UserAgentContainer.AppendFeatures(this.GetUserAgentFeatures());
+ this.InitializePartitionLevelFailoverWithDefaultHedging();
+
+ this.PartitionKeyRangeLocation =
+ this.ConnectionPolicy.EnablePartitionLevelFailover
+ || this.ConnectionPolicy.EnablePartitionLevelCircuitBreaker
+ ? new GlobalPartitionEndpointManagerCore(
+ this.GlobalEndpointManager,
+ this.ConnectionPolicy.EnablePartitionLevelFailover,
+ this.ConnectionPolicy.EnablePartitionLevelCircuitBreaker)
+ : GlobalPartitionEndpointManagerNoOp.Instance;
+
+ this.retryPolicy = new RetryPolicy(
+ globalEndpointManager: this.GlobalEndpointManager,
+ connectionPolicy: this.ConnectionPolicy,
+ partitionKeyRangeLocationCache: this.PartitionKeyRangeLocation);
+
+ this.ResetSessionTokenRetryPolicy = this.retryPolicy;
GatewayStoreModel gatewayStoreModel = new GatewayStoreModel(
this.GlobalEndpointManager,
@@ -6820,12 +6839,44 @@ private async Task InitializeGatewayConfigurationReaderAsync()
this.accountServiceConfiguration = new CosmosAccountServiceConfiguration(accountReader.InitializeReaderAsync);
- await this.accountServiceConfiguration.InitializeAsync();
- AccountProperties accountProperties = this.accountServiceConfiguration.AccountProperties;
+ await this.accountServiceConfiguration.InitializeAsync();
+ AccountProperties accountProperties = this.accountServiceConfiguration.AccountProperties;
this.UseMultipleWriteLocations = this.ConnectionPolicy.UseMultipleWriteLocations && accountProperties.EnableMultipleWriteLocations;
-
this.GlobalEndpointManager.InitializeAccountPropertiesAndStartBackgroundRefresh(accountProperties);
}
+
+ internal string GetUserAgentFeatures()
+ {
+ int featureFlag = 0;
+ if (this.ConnectionPolicy.EnablePartitionLevelFailover)
+ {
+ featureFlag += (int)UserAgentFeatureFlags.PerPartitionAutomaticFailover;
+ }
+
+ if (this.ConnectionPolicy.EnablePartitionLevelFailover || this.ConnectionPolicy.EnablePartitionLevelCircuitBreaker)
+ {
+ featureFlag += (int)UserAgentFeatureFlags.PerPartitionCircuitBreaker;
+ }
+
+ return featureFlag == 0 ? string.Empty : $"F{featureFlag:X}";
+ }
+
+ internal void InitializePartitionLevelFailoverWithDefaultHedging()
+ {
+ if (this.ConnectionPolicy.EnablePartitionLevelFailover
+ && this.ConnectionPolicy.AvailabilityStrategy == null)
+ {
+ // The default threshold is the minimum value of 1 second and a fraction (currently it's half) of
+ // the request timeout value provided by the end customer.
+ double defaultThresholdInMillis = Math.Min(
+ DocumentClient.DefaultHedgingThresholdInMilliseconds,
+ this.ConnectionPolicy.RequestTimeout.TotalMilliseconds / 2);
+
+ this.ConnectionPolicy.AvailabilityStrategy = AvailabilityStrategy.CrossRegionHedgingStrategy(
+ threshold: TimeSpan.FromMilliseconds(defaultThresholdInMillis),
+ thresholdStep: TimeSpan.FromMilliseconds(DocumentClient.DefaultHedgingThresholdStepInMilliseconds));
+ }
+ }
internal void CaptureSessionToken(DocumentServiceRequest request, DocumentServiceResponse response)
{
diff --git a/Microsoft.Azure.Cosmos/src/Fluent/CosmosClientBuilder.cs b/Microsoft.Azure.Cosmos/src/Fluent/CosmosClientBuilder.cs
index f91ce44a0e..5e7ce3d116 100644
--- a/Microsoft.Azure.Cosmos/src/Fluent/CosmosClientBuilder.cs
+++ b/Microsoft.Azure.Cosmos/src/Fluent/CosmosClientBuilder.cs
@@ -754,15 +754,6 @@ internal CosmosClientBuilder WithCpuMonitorDisabled()
return this;
}
- ///
- /// Enabled partition level failover in the SDK
- ///
- internal CosmosClientBuilder WithPartitionLevelFailoverEnabled()
- {
- this.clientOptions.EnablePartitionLevelFailover = true;
- return this;
- }
-
///
/// Enables SDK to inject fault. Used for testing applications.
///
diff --git a/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs b/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs
index 01d37d3378..7499ac178e 100644
--- a/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs
+++ b/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs
@@ -127,7 +127,7 @@ public override async Task SendAsync(
public AvailabilityStrategyInternal AvailabilityStrategy(RequestMessage request)
{
AvailabilityStrategy strategy = request.RequestOptions?.AvailabilityStrategy
- ?? this.client.ClientOptions.AvailabilityStrategy;
+ ?? this.client.DocumentClient.ConnectionPolicy.AvailabilityStrategy;
if (strategy == null)
{
diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/AccountProperties.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/AccountProperties.cs
index cfc42707fb..9157964b9e 100644
--- a/Microsoft.Azure.Cosmos/src/Resource/Settings/AccountProperties.cs
+++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/AccountProperties.cs
@@ -244,6 +244,12 @@ internal long ProvisionedDocumentStorageInMB
[JsonProperty(PropertyName = Constants.Properties.EnableMultipleWriteLocations)]
internal bool EnableMultipleWriteLocations { get; set; }
+ ///
+ /// Gets the featured enabled value for Per Partition Automatic Failover
+ ///
+ [JsonProperty(PropertyName = Constants.Properties.EnablePerPartitionFailoverBehavior)]
+ internal bool? EnablePartitionLevelFailover { get; set; }
+
private IDictionary QueryStringToDictConverter()
{
if (!string.IsNullOrEmpty(this.QueryEngineConfigurationString))
diff --git a/Microsoft.Azure.Cosmos/src/Routing/GlobalEndpointManager.cs b/Microsoft.Azure.Cosmos/src/Routing/GlobalEndpointManager.cs
index 3762ced7ea..b9ce687c32 100644
--- a/Microsoft.Azure.Cosmos/src/Routing/GlobalEndpointManager.cs
+++ b/Microsoft.Azure.Cosmos/src/Routing/GlobalEndpointManager.cs
@@ -597,6 +597,14 @@ public virtual void InitializeAccountPropertiesAndStartBackgroundRefresh(Account
{
return;
}
+
+ bool isPPafEnabled = ConfigurationManager.IsPartitionLevelFailoverEnabled(defaultValue: false);
+ if (databaseAccount.EnablePartitionLevelFailover.HasValue)
+ {
+ isPPafEnabled = databaseAccount.EnablePartitionLevelFailover.Value;
+ }
+
+ this.connectionPolicy.EnablePartitionLevelFailover = isPPafEnabled;
GlobalEndpointManager.ParseThinClientLocationsFromAdditionalProperties(databaseAccount);
this.locationCache.OnDatabaseAccountRead(databaseAccount);
diff --git a/Microsoft.Azure.Cosmos/src/UserAgentContainer.cs b/Microsoft.Azure.Cosmos/src/UserAgentContainer.cs
index d91aa8b3fb..ae9e3d4457 100644
--- a/Microsoft.Azure.Cosmos/src/UserAgentContainer.cs
+++ b/Microsoft.Azure.Cosmos/src/UserAgentContainer.cs
@@ -29,6 +29,17 @@ public UserAgentContainer(
this.Suffix = suffix ?? string.Empty;
}
+ public void AppendFeatures(
+ string features)
+ {
+ if (!string.IsNullOrEmpty(features))
+ {
+ this.Suffix = string.IsNullOrEmpty(this.Suffix)
+ ? features
+ : $"{features}|{this.Suffix}";
+ }
+ }
+
internal override string BaseUserAgent => this.cosmosBaseUserAgent ?? string.Empty;
protected virtual void GetEnvironmentInformation(
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemIntegrationTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemIntegrationTests.cs
index 45551f0bef..5ee7266408 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemIntegrationTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemIntegrationTests.cs
@@ -1312,7 +1312,7 @@ public async Task ReadItemAsync_WithPPAFEnabledAndSingleMasterAccountWithRespons
traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out object hedgeContext);
- if (cosmosClientOptions.EnablePartitionLevelFailover)
+ if (enablePartitionLevelFailover)
{
Assert.IsNotNull(hedgeContext);
List hedgedRegions = ((IEnumerable)hedgeContext).ToList();
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CustomSerializationTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CustomSerializationTests.cs
index 3334c201d1..96f8d3b0ce 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CustomSerializationTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CustomSerializationTests.cs
@@ -14,6 +14,7 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
+ using Microsoft.Azure.Cosmos.Tracing;
using Microsoft.Azure.Cosmos.Utils;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
@@ -244,6 +245,7 @@ public async Task TestStoredProcJsonSerializerSettings()
}";
DocumentClient client = new DocumentClient(this.hostUri, this.masterKey, serializerSettings);
+ await client.EnsureValidClientAsync(NoOpTrace.Singleton);
StoredProcedure sproc = await client.CreateStoredProcedureAsync(this.collectionUri, storedProcedureDef);
@@ -326,6 +328,8 @@ public void TestStoredProcedure()
connectionPolicy,
defaultConsistencyLevel);
+ client.EnsureValidClientAsync(NoOpTrace.Singleton).Wait();
+
// Create a simple stored procedure
string scriptId = "bulkImportScript";
StoredProcedure sproc = new StoredProcedure
@@ -533,6 +537,9 @@ private void SetupDateTimeScenario(JsonSerializerSettings serializerSettings, st
serializerSettings,
connectionPolicy,
defaultConsistencyLevel);
+
+ client.EnsureValidClientAsync(NoOpTrace.Singleton).Wait();
+
originalDocument = new Document();
originalDocument.SetPropertyValue(jsonPropertyName, "2017-05-18T17:17:32.7514920Z");
originalDocument.SetPropertyValue(PartitionKeyProperty, "value");
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/DocumentClientUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/DocumentClientUnitTests.cs
index 227f308baf..43fe495852 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/DocumentClientUnitTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/DocumentClientUnitTests.cs
@@ -13,6 +13,7 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
using Microsoft.Azure.Cosmos.Internal;
using Microsoft.Azure.Cosmos.Linq;
using Microsoft.Azure.Cosmos.Query.Core.QueryPlan;
+ using Microsoft.Azure.Cosmos.Tracing;
using Microsoft.Azure.Cosmos.Utils;
using Microsoft.Azure.Documents;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -58,6 +59,7 @@ public async Task RetryExceedingMaxTimeLimit()
(HttpMessageHandler)null,
connectionPolicy);
+ await client.EnsureValidClientAsync(NoOpTrace.Singleton);
await client.GetDatabaseAccountAsync();
int expectedExecutionTimes = 11;
@@ -144,6 +146,7 @@ public async Task OpenConnectionsToAllReplicasAsync_WhenStoreModelThrowsInternal
(HttpMessageHandler)null,
connectionPolicy);
+ await client.EnsureValidClientAsync(NoOpTrace.Singleton);
await client.GetDatabaseAccountAsync();
client.StoreModel = mockStoreModel.Object;
client.GatewayStoreModel = mockStoreModel.Object;
@@ -200,6 +203,7 @@ private void TestRetryOnThrottled(int? numberOfRetries)
(HttpMessageHandler)null,
connectionPolicy);
+ client.EnsureValidClientAsync(NoOpTrace.Singleton).Wait();
client.GetDatabaseAccountAsync().Wait();
int expectedExecutionTimes = numberOfRetries + 1 ?? 10;
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/HeadersValidationTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/HeadersValidationTests.cs
index 9120e7179a..047c5b0332 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/HeadersValidationTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/HeadersValidationTests.cs
@@ -745,15 +745,14 @@ public async Task ValidateVersionHeader()
HttpConstants.Versions.CurrentVersion = "2015-01-01";
client.Dispose();
client = TestCommon.CreateClient(true);
- try
- {
- doc = (await client.CreateDocumentAsync(coll.SelfLink, new Document())).Resource;
- Assert.Fail("Should have faild because of version error");
- }
- catch (CosmosException dce)
- {
- Assert.AreEqual(dce.StatusCode, HttpStatusCode.BadRequest);
- }
+ Assert.Fail("Should have faild because of version error");
+ }
+ catch (AggregateException ae)
+ {
+ Assert.IsTrue(ae.InnerException is CosmosException);
+
+ CosmosException ce = (CosmosException) ae.InnerException;
+ Assert.AreEqual(ce.StatusCode, HttpStatusCode.BadRequest);
}
finally
{
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TestCommon.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TestCommon.cs
index e66f723121..6cc922b35d 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TestCommon.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TestCommon.cs
@@ -246,6 +246,7 @@ internal static DocumentClient CreateClient(bool useGateway, Protocol protocol =
apiType,
recievedResponseEventHandler);
+ client.EnsureValidClientAsync(NoOpTrace.Singleton).Wait();
return client;
}
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs
index 246f6914f8..04a1181921 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs
@@ -87,7 +87,7 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
Assert.IsNull(clientOptions.HttpClientFactory);
Assert.AreNotEqual(consistencyLevel, clientOptions.ConsistencyLevel);
Assert.AreNotEqual(priorityLevel, clientOptions.PriorityLevel);
- Assert.IsFalse(clientOptions.EnablePartitionLevelFailover);
+ Assert.IsFalse(clientOptions.EnablePartitionLevelCircuitBreaker);
Assert.IsFalse(clientOptions.EnableAdvancedReplicaSelectionForTcp.HasValue);
Assert.AreNotEqual(throughputBucket, clientOptions.ThroughputBucket);
@@ -149,7 +149,7 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
Assert.IsTrue(clientOptions.AllowBulkExecution);
Assert.AreEqual(consistencyLevel, clientOptions.ConsistencyLevel);
Assert.AreEqual(priorityLevel, clientOptions.PriorityLevel);
- Assert.IsFalse(clientOptions.EnablePartitionLevelFailover);
+ Assert.IsFalse(clientOptions.EnablePartitionLevelCircuitBreaker);
Assert.IsTrue(clientOptions.EnableAdvancedReplicaSelectionForTcp.HasValue && clientOptions.EnableAdvancedReplicaSelectionForTcp.Value);
Assert.AreEqual(throughputBucket, clientOptions.ThroughputBucket);
@@ -231,17 +231,11 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
///
[TestMethod]
[Owner("dkunda")]
- [DataRow(true, DisplayName = "Validate that when environment variable is used to enable PPAF, the outcome of the test should be same.")]
- [DataRow(false, DisplayName = "Validate that when CosmosClientOptions is used to enable PPAF, the outcome of the test should be same.")]
- public void CosmosClientOptions_WhenPartitionLevelFailoverEnabledAndPreferredRegionsNotSet_ShouldInitializeCosmosClientSuccessfully(
- bool useEnvironmentVariable)
+ public void CosmosClientOptions_WhenPartitionLevelFailoverEnabledAndPreferredRegionsNotSet_ShouldInitializeCosmosClientSuccessfully()
{
try
{
- if (useEnvironmentVariable)
- {
- Environment.SetEnvironmentVariable(ConfigurationManager.PartitionLevelFailoverEnabled, "True");
- }
+ Environment.SetEnvironmentVariable(ConfigurationManager.PartitionLevelFailoverEnabled, "True");
string endpoint = AccountEndpoint;
string key = MockCosmosUtil.RandomInvalidCorrectlyFormatedAuthKey;
@@ -277,12 +271,6 @@ public void CosmosClientOptions_WhenPartitionLevelFailoverEnabledAndPreferredReg
.WithPriorityLevel(priorityLevel)
.WithThroughputBucket(throughputBucket);
- if (!useEnvironmentVariable)
- {
- cosmosClientBuilder
- .WithPartitionLevelFailoverEnabled();
- }
-
CosmosClient cosmosClient = cosmosClientBuilder.Build();
Assert.IsNotNull(cosmosClient,
@@ -300,16 +288,11 @@ public void CosmosClientOptions_WhenPartitionLevelFailoverEnabledAndPreferredReg
///
[TestMethod]
[Owner("dkunda")]
- [DataRow(true, DisplayName = "Validate that when enevironment variable is used to enable PPAF, the outcome of the test should be same.")]
- [DataRow(false, DisplayName = "Validate that when CosmosClientOptions is used to enable PPAF, the outcome of the test should be same.")]
- public void CosmosClientOptions_WhenPartitionLevelFailoverEnabledAndPreferredRegionsSet_ShouldInitializeSuccessfully(bool useEnvironmentVariable)
+ public void CosmosClientOptions_WhenPartitionLevelFailoverEnabledAndPreferredRegionsSet_ShouldInitializeSuccessfully()
{
try
{
- if (useEnvironmentVariable)
- {
- Environment.SetEnvironmentVariable(ConfigurationManager.PartitionLevelFailoverEnabled, "True");
- }
+ Environment.SetEnvironmentVariable(ConfigurationManager.PartitionLevelFailoverEnabled, "True");
string endpoint = AccountEndpoint;
string key = MockCosmosUtil.RandomInvalidCorrectlyFormatedAuthKey;
@@ -342,7 +325,6 @@ public void CosmosClientOptions_WhenPartitionLevelFailoverEnabledAndPreferredReg
.WithSerializerOptions(cosmosSerializerOptions)
.WithConsistencyLevel(consistencyLevel)
.WithPriorityLevel(priorityLevel)
- .WithPartitionLevelFailoverEnabled()
.WithThroughputBucket(throughputBucket)
.WithApplicationPreferredRegions(
new List()
@@ -373,7 +355,6 @@ public void CosmosClientOptions_WhenPartitionLevelFailoverEnabledAndPreferredReg
Assert.AreEqual(cosmosSerializerOptions.Indented, clientOptions.SerializerOptions.Indented);
Assert.IsFalse(clientOptions.AllowBulkExecution);
Assert.AreEqual(consistencyLevel, clientOptions.ConsistencyLevel);
- Assert.IsTrue(clientOptions.EnablePartitionLevelFailover);
Assert.IsNotNull(clientOptions.ApplicationPreferredRegions);
Assert.IsNotNull(clientOptions.AccountInitializationCustomEndpoints);
}
@@ -513,69 +494,75 @@ public void UserAgentContainsEnvironmentInformation()
[TestMethod]
[Owner("ntripician")]
- [DataRow(true, new string[] { nameof(UserAgentFeatureFlags.PerPartitionCircuitBreaker) }, "F2", DisplayName = "With PPCB and ApplicationName")]
- [DataRow(true, new string[] { nameof(UserAgentFeatureFlags.PerPartitionCircuitBreaker), nameof(UserAgentFeatureFlags.PerPartitionAutomaticFailover) }, "F3", DisplayName = "With PPAF and ApplicationName")]
- [DataRow(false, new string[] { nameof(UserAgentFeatureFlags.PerPartitionCircuitBreaker) }, "F2", DisplayName = "With PPCB and Without ApplicationName")]
- [DataRow(false, new string[] { }, "", DisplayName = "Without Any Features and ApplicationName")]
+ [DataRow(true, false, true, "F2", DisplayName = "With PPCB and ApplicationName")]
+ [DataRow(true, true, true, "F3", DisplayName = "With PPAF and ApplicationName")]
+ [DataRow(false, false, true, "F2", DisplayName = "With PPCB and Without ApplicationName")]
+ [DataRow(false, false, false, "", DisplayName = "Without Any Features and ApplicationName")]
public void UserAgentContainsPPAFInformation(
bool appName,
- string[] featureList,
+ bool ppaf,
+ bool ppcb,
string expectedHexStringPostFix)
{
EnvironmentInformation environmentInformation = new EnvironmentInformation();
string expectedValue = "cosmos-netstandard-sdk/" + environmentInformation.ClientVersion;
- CosmosClientOptions cosmosClientOptions = new CosmosClientOptions();
string userAgentSuffix = "testSuffix";
+
+ string endpoint = AccountEndpoint;
+ string key = MockCosmosUtil.RandomInvalidCorrectlyFormatedAuthKey;
+
+ CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder(
+ accountEndpoint: endpoint,
+ authKeyOrResourceToken: key);
+
if (appName)
{
- cosmosClientOptions.ApplicationName = userAgentSuffix;
+ cosmosClientBuilder.WithApplicationName(userAgentSuffix);
}
- foreach(string feature in featureList)
+ ConnectionPolicy policy = new ConnectionPolicy()
{
- if (feature.Equals(nameof(UserAgentFeatureFlags.PerPartitionCircuitBreaker)))
- {
- cosmosClientOptions.EnablePartitionLevelCircuitBreaker = true;
- }
- else if (feature.Equals(nameof(UserAgentFeatureFlags.PerPartitionAutomaticFailover)))
- {
- cosmosClientOptions.EnablePartitionLevelFailover = true;
- }
- }
+ EnablePartitionLevelCircuitBreaker = ppcb,
+ EnablePartitionLevelFailover = ppaf
+ };
+
+ CosmosClient cosmosClient = cosmosClientBuilder.Build(new MockDocumentClient(policy));
- cosmosClientOptions.ApplicationRegion = Regions.WestUS;
+ CosmosClientOptions cosmosClientOptions = cosmosClient.ClientOptions;
+
if (appName)
{
Assert.AreEqual(userAgentSuffix, cosmosClientOptions.ApplicationName);
+ cosmosClient.DocumentClient.ConnectionPolicy.UserAgentContainer.AppendFeatures(cosmosClientOptions.ApplicationName);
}
else
{
Assert.IsNull(cosmosClientOptions.ApplicationName);
}
- Cosmos.UserAgentContainer userAgentContainer = cosmosClientOptions.CreateUserAgentContainerWithFeatures(clientId: 0);
- Console.WriteLine(userAgentContainer.UserAgent);
+ cosmosClient.DocumentClient.ConnectionPolicy.UserAgentContainer.AppendFeatures(cosmosClient.DocumentClient.GetUserAgentFeatures());
+
+ string userAgent = cosmosClient.DocumentClient.ConnectionPolicy.UserAgentContainer.UserAgent;
+ Console.WriteLine(userAgent);
if (appName)
{
- Assert.IsTrue(userAgentContainer.UserAgent.EndsWith(userAgentSuffix));
+ Assert.IsTrue(userAgent.EndsWith(userAgentSuffix));
}
else
{
- Assert.IsTrue(userAgentContainer.UserAgent.EndsWith(expectedHexStringPostFix));
+ Assert.IsTrue(userAgent.EndsWith(expectedHexStringPostFix));
}
-
- Assert.IsTrue(userAgentContainer.UserAgent.StartsWith(expectedValue));
- ConnectionPolicy connectionPolicy = cosmosClientOptions.GetConnectionPolicy(clientId: 0);
- Assert.IsTrue(connectionPolicy.UserAgentContainer.UserAgent.StartsWith(expectedValue));
- Assert.IsTrue(connectionPolicy.UserAgentContainer.UserAgent.Contains(expectedHexStringPostFix));
+ Assert.IsTrue(userAgent.StartsWith(expectedValue));
+ Assert.IsTrue(userAgent.Contains(expectedHexStringPostFix));
+
if (appName)
{
- Assert.IsTrue(connectionPolicy.UserAgentContainer.UserAgent.EndsWith(userAgentSuffix));
+ Assert.IsTrue(userAgent.EndsWith(userAgentSuffix));
}
else
{
- Assert.IsTrue(connectionPolicy.UserAgentContainer.UserAgent.EndsWith(expectedHexStringPostFix));
+ Assert.IsTrue(userAgent.EndsWith(expectedHexStringPostFix));
}
}
@@ -1202,62 +1189,6 @@ public void TestServerCertificatesValidationWithDisableSSLFlagTrue(string connSt
#nullable disable
}
- [TestMethod]
- public void PPAFClientApplicationRegionCreationTest()
- {
- CosmosClientOptions cosmosClientOptions = new CosmosClientOptions
- {
- ApplicationRegion = Regions.WestUS2,
- EnablePartitionLevelFailover = true
- };
-
- CosmosClient cosmosClient = new CosmosClient(ConnectionString, cosmosClientOptions);
- Assert.AreEqual(Regions.WestUS2, cosmosClient.ClientOptions.ApplicationRegion);
- Assert.IsTrue(cosmosClient.ClientOptions.EnablePartitionLevelFailover);
- }
-
- [TestMethod]
- public void PPAFClientApplicationPreferredRegionCreationTest()
- {
- CosmosClientOptions cosmosClientOptions = new CosmosClientOptions
- {
- ApplicationPreferredRegions = new List { Regions.WestUS2, Regions.EastUS2 },
- EnablePartitionLevelFailover = true
- };
-
- CosmosClient cosmosClient = new CosmosClient(ConnectionString, cosmosClientOptions);
- Assert.AreEqual(Regions.WestUS2, cosmosClient.ClientOptions.ApplicationPreferredRegions[0]);
- Assert.AreEqual(Regions.EastUS2, cosmosClient.ClientOptions.ApplicationPreferredRegions[1]);
- Assert.IsTrue(cosmosClient.ClientOptions.EnablePartitionLevelFailover);
- }
-
- [TestMethod]
- [ExpectedException(typeof(ArgumentException))]
- public void PPAFClientAppRegionAndAppPreferredRegionTest()
- {
- CosmosClientOptions cosmosClientOptions = new CosmosClientOptions
- {
- EnablePartitionLevelFailover = true,
- ApplicationPreferredRegions = new List { Regions.WestUS2, Regions.EastUS2 },
- ApplicationRegion = Regions.AustraliaCentral
- };
-
- _ = new CosmosClient(ConnectionString, cosmosClientOptions);
- }
-
- [TestMethod]
- public void PPAFClientNoRegionsTest()
- {
- CosmosClientOptions cosmosClientOptions = new CosmosClientOptions
- {
- EnablePartitionLevelFailover = true
- };
-
- CosmosClient cosmosClient = new(ConnectionString, cosmosClientOptions);
-
- Assert.IsNotNull(cosmosClient);
- }
-
private class TestWebProxy : IWebProxy
{
public ICredentials Credentials { get; set; }
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs
index e664746a04..1ebff95eec 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs
@@ -55,7 +55,7 @@ public void ValidatePropertySerialization()
string id = "testId";
this.TestProperty(
id,
- $@"{{""id"":""{id}"",""writableLocations"":[],""readableLocations"":[],""userConsistencyPolicy"":null,""addresses"":null,""userReplicationPolicy"":null,""systemReplicationPolicy"":null,""readPolicy"":null,""queryEngineConfiguration"":null,""enableMultipleWriteLocations"":false}}");
+ $@"{{""id"":""{id}"",""writableLocations"":[],""readableLocations"":[],""userConsistencyPolicy"":null,""addresses"":null,""userReplicationPolicy"":null,""systemReplicationPolicy"":null,""readPolicy"":null,""queryEngineConfiguration"":null,""enableMultipleWriteLocations"":false,""enablePerPartitionFailoverBehavior"":null}}");
this.TestProperty(
id,
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosSerializerCoreTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosSerializerCoreTests.cs
index 9c748eb790..7b18b25518 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosSerializerCoreTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosSerializerCoreTests.cs
@@ -143,7 +143,7 @@ public void ValidateCustomSerializerNotUsedForInternalTypes()
this.TestProperty(
serializerCore,
id,
- $@"{{""id"":""{id}"",""writableLocations"":[],""readableLocations"":[],""userConsistencyPolicy"":null,""addresses"":null,""userReplicationPolicy"":null,""systemReplicationPolicy"":null,""readPolicy"":null,""queryEngineConfiguration"":null,""enableMultipleWriteLocations"":false}}");
+ $@"{{""id"":""{id}"",""writableLocations"":[],""readableLocations"":[],""userConsistencyPolicy"":null,""addresses"":null,""userReplicationPolicy"":null,""systemReplicationPolicy"":null,""readPolicy"":null,""queryEngineConfiguration"":null,""enableMultipleWriteLocations"":false,""enablePerPartitionFailoverBehavior"":null}}");
this.TestProperty(
serializerCore,
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/GlobalPartitionEndpointManagerTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/GlobalPartitionEndpointManagerTests.cs
index 114428297b..433250e811 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/GlobalPartitionEndpointManagerTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/GlobalPartitionEndpointManagerTests.cs
@@ -24,6 +24,7 @@ public class GlobalPartitionEndpointManagerTests
public async Task TestWriteForbiddenScenarioAsync()
{
GlobalPartitionEndpointManagerTests.SetupAccountAndCacheOperations(
+ shouldEnablePPAF: true,
out string secondaryRegionNameForUri,
out string globalEndpoint,
out string secondaryRegionEndpiont,
@@ -57,13 +58,12 @@ public async Task TestWriteForbiddenScenarioAsync()
CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
{
- EnablePartitionLevelFailover = true,
ConsistencyLevel = Cosmos.ConsistencyLevel.Strong,
ApplicationPreferredRegions = new List()
- {
- Regions.EastUS,
- Regions.WestUS
- },
+ {
+ Regions.EastUS,
+ Regions.WestUS
+ },
HttpClientFactory = () => new HttpClient(new HttpHandlerHelper(mockHttpHandler.Object)),
TransportClientHandlerFactory = (original) => mockTransport.Object,
};
@@ -115,6 +115,7 @@ public async Task TestWriteForbiddenScenarioAsync()
public async Task CreateItemAsync_WithPreferredRegionsAndServiceUnavailableForFirstPreferredRegion_ShouldRetryAndSucceedToTheNextPreferredRegion()
{
GlobalPartitionEndpointManagerTests.SetupAccountAndCacheOperations(
+ shouldEnablePPAF: true,
out string secondaryRegionNameForUri,
out string globalEndpoint,
out string secondaryRegionEndpiont,
@@ -148,21 +149,20 @@ public async Task CreateItemAsync_WithPreferredRegionsAndServiceUnavailableForFi
CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
{
- EnablePartitionLevelFailover = true,
ConsistencyLevel = Cosmos.ConsistencyLevel.Strong,
ApplicationPreferredRegions = new List()
- {
- Regions.EastUS,
- Regions.WestUS
- },
+ {
+ Regions.EastUS,
+ Regions.WestUS
+ },
HttpClientFactory = () => new HttpClient(new HttpHandlerHelper(mockHttpHandler.Object)),
TransportClientHandlerFactory = (original) => mockTransport.Object,
};
using CosmosClient customClient = new CosmosClient(
- globalEndpoint,
- Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())),
- cosmosClientOptions);
+ globalEndpoint,
+ Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())),
+ cosmosClientOptions);
Container container = customClient.GetContainer(databaseName, containerName);
@@ -212,6 +212,7 @@ public void CreateItemAsync_WithNoPreferredRegionsAndServiceUnavailable_ShouldNo
TimeSpan explictAvailabilityStrategyThresholdStep = TimeSpan.FromMilliseconds(500);
GlobalPartitionEndpointManagerTests.SetupAccountAndCacheOperations(
+ shouldEnablePPAF: true,
out string secondaryRegionNameForUri,
out string globalEndpoint,
out string secondaryRegionEndpiont,
@@ -247,7 +248,6 @@ public void CreateItemAsync_WithNoPreferredRegionsAndServiceUnavailable_ShouldNo
CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
{
- EnablePartitionLevelFailover = true,
ConsistencyLevel = Cosmos.ConsistencyLevel.Strong,
HttpClientFactory = () => new HttpClient(new HttpHandlerHelper(mockHttpHandler.Object)),
TransportClientHandlerFactory = (original) => mockTransport.Object,
@@ -268,10 +268,10 @@ public void CreateItemAsync_WithNoPreferredRegionsAndServiceUnavailable_ShouldNo
Assert.IsNotNull(cosmosClient,
message: "ApplicationPreferredRegions or ApplicationRegion is no longer mandatory fields, hence the client initialization should succeed.");
- Assert.IsNotNull(cosmosClient.ClientOptions.AvailabilityStrategy);
+ Assert.IsNotNull(cosmosClient.DocumentClient.ConnectionPolicy.AvailabilityStrategy);
+
+ CrossRegionHedgingAvailabilityStrategy crossRegionHedgingStrategy = (CrossRegionHedgingAvailabilityStrategy)cosmosClient.DocumentClient.ConnectionPolicy.AvailabilityStrategy;
- CrossRegionHedgingAvailabilityStrategy crossRegionHedgingStrategy = (CrossRegionHedgingAvailabilityStrategy)cosmosClient.ClientOptions.AvailabilityStrategy;
-
Assert.IsNotNull(crossRegionHedgingStrategy);
if (isExplictAvailabilityStrategyProvided)
@@ -293,6 +293,7 @@ public void CreateItemAsync_WithNoPreferredRegionsAndServiceUnavailable_ShouldNo
public async Task TestRequestTimeoutExceptionScenarioAsync()
{
GlobalPartitionEndpointManagerTests.SetupAccountAndCacheOperations(
+ shouldEnablePPAF: true,
out string secondaryRegionNameForUri,
out string globalEndpoint,
out string secondaryRegionEndpiont,
@@ -326,13 +327,12 @@ public async Task TestRequestTimeoutExceptionScenarioAsync()
CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
{
- EnablePartitionLevelFailover = true,
ConsistencyLevel = Cosmos.ConsistencyLevel.Strong,
ApplicationPreferredRegions = new List()
- {
- Regions.EastUS,
- Regions.WestUS
- },
+ {
+ Regions.EastUS,
+ Regions.WestUS
+ },
HttpClientFactory = () => new HttpClient(new HttpHandlerHelper(mockHttpHandler.Object)),
TransportClientHandlerFactory = (original) => mockTransport.Object,
};
@@ -386,6 +386,7 @@ public async Task TestRequestTimeoutExceptionScenarioAsync()
}
private static void SetupAccountAndCacheOperations(
+ bool shouldEnablePPAF,
out string secondaryRegionNameForUri,
out string globalEndpoint,
out string secondaryRegionEndpiont,
@@ -439,7 +440,8 @@ private static void SetupAccountAndCacheOperations(
endpoint: globalEndpointUri.ToString(),
accountName: accountName,
writeRegions: writeRegion,
- readRegions: readRegions);
+ readRegions: readRegions,
+ shouldEnablePPAF: shouldEnablePPAF);
MockSetupsHelper.SetupContainerProperties(
mockHttpHandler: mockHttpHandler,
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/MockSetupsHelper.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/MockSetupsHelper.cs
index 160ed58548..4356df6d50 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/MockSetupsHelper.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/MockSetupsHelper.cs
@@ -29,12 +29,14 @@ public static void SetupStrongAccountProperties(
string accountName,
string endpoint,
IList writeRegions,
- IList readRegions)
+ IList readRegions,
+ bool shouldEnablePPAF)
{
HttpResponseMessage httpResponseMessage = MockSetupsHelper.CreateStrongAccount(
accountName,
writeRegions,
- readRegions);
+ readRegions,
+ shouldEnablePPAF);
Uri endpointUri = new Uri(endpoint);
mockHttpClientHandler.Setup(x => x.SendAsync(
@@ -106,7 +108,8 @@ public static Uri SetupSingleRegionAccount(
public static HttpResponseMessage CreateStrongAccount(
string accountName,
IList writeRegions,
- IList readRegions)
+ IList readRegions,
+ bool shouldEnablePPAF = false)
{
AccountProperties accountProperties = new AccountProperties()
{
@@ -114,6 +117,7 @@ public static HttpResponseMessage CreateStrongAccount(
WriteLocationsInternal = new Collection(writeRegions),
ReadLocationsInternal = new Collection(readRegions),
EnableMultipleWriteLocations = writeRegions.Count > 1,
+ EnablePartitionLevelFailover = shouldEnablePPAF,
Consistency = new AccountConsistency()
{
DefaultConsistencyLevel = Cosmos.ConsistencyLevel.Strong
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/RegionFailoverTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/RegionFailoverTests.cs
index dfd5a0c23a..f8bddc530c 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/RegionFailoverTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeFailoverTests/RegionFailoverTests.cs
@@ -103,11 +103,11 @@ public async Task TestHttpRequestExceptionScenarioAsync()
count++;
if (count < 2)
{
- return Task.FromResult(MockSetupsHelper.CreateStrongAccount(accountName, writeRegion, readRegions));
+ return Task.FromResult(MockSetupsHelper.CreateStrongAccount(accountName, writeRegion, readRegions, shouldEnablePPAF: true));
}
else
{
- return Task.FromResult(MockSetupsHelper.CreateStrongAccount(accountName, writeRegionFailedOver, readRegionsFailedOver));
+ return Task.FromResult(MockSetupsHelper.CreateStrongAccount(accountName, writeRegionFailedOver, readRegionsFailedOver, shouldEnablePPAF: true));
}
});
@@ -156,7 +156,6 @@ public async Task TestHttpRequestExceptionScenarioAsync()
CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
{
- EnablePartitionLevelFailover = true,
ConsistencyLevel = Cosmos.ConsistencyLevel.Strong,
ApplicationPreferredRegions = new List()
{