From fb90635c67a8f7dfad7bd6efe0dc04fb20bf6755 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Tue, 10 Jan 2023 11:54:43 -0800 Subject: [PATCH 1/5] Code changes to refactor implementations for opening connections to all replicas. Fixed test failures due to Direct package upgrade. --- Directory.Build.props | 2 +- .../src/Routing/GatewayAddressCache.cs | 46 +-- .../src/Routing/GlobalAddressResolver.cs | 24 +- .../src/Routing/IAddressCache.cs | 7 + .../CosmosHeaderTests.cs | 9 +- .../TransportWrapperTests.cs | 25 +- .../TraceWriterBaselineTests.TraceData.xml | 94 +----- .../ClientRetryPolicyTests.cs | 7 +- .../GatewayAddressCacheTests.cs | 268 +++++++++++++----- .../StoreReaderTest.cs | 2 +- ...entSideRequestStatisticsTraceDatumTests.cs | 21 +- .../Tracing/TraceTests.cs | 29 +- .../Tracing/TraceWriterBaselineTests.cs | 42 +-- 13 files changed, 266 insertions(+), 310 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 651e1f89e5..658186357b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ 3.31.2 3.31.2 preview - 3.29.4 + 3.30.0 2.0.0 2.0.0 preview diff --git a/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs b/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs index 210e5951fe..7c6355591e 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs @@ -50,6 +50,7 @@ internal class GatewayAddressCache : IAddressCache, IDisposable private Tuple masterPartitionAddressCache; private DateTime suboptimalMasterPartitionTimestamp; private bool disposedValue; + private IOpenConnectionsHandler openConnectionsHandler; public GatewayAddressCache( Uri serviceEndpoint, @@ -57,6 +58,7 @@ public GatewayAddressCache( ICosmosAuthorizationTokenProvider tokenProvider, IServiceConfigurationReader serviceConfigReader, CosmosHttpClient httpClient, + IOpenConnectionsHandler openConnectionsHandler, long suboptimalPartitionForceRefreshIntervalInSeconds = 600, bool enableTcpConnectionEndpointRediscovery = false) { @@ -80,6 +82,8 @@ public GatewayAddressCache( GatewayAddressCache.protocolFilterFormat, Constants.Properties.Protocol, GatewayAddressCache.ProtocolString(this.protocol)); + + this.openConnectionsHandler = openConnectionsHandler; } public Uri ServiceEndpoint => this.serviceEndpoint; @@ -88,7 +92,7 @@ public async Task OpenConnectionsAsync( string databaseName, ContainerProperties collection, IReadOnlyList partitionKeyRangeIdentities, - Func openConnectionHandler, + bool shouldOpenRntbdChannels, CancellationToken cancellationToken) { List>> tasks = new (); @@ -157,47 +161,21 @@ public async Task OpenConnectionsAsync( new PartitionKeyRangeIdentity(collection.ResourceId, addressInfo.Item1.PartitionKeyRangeId), addressInfo.Item2); - if (openConnectionHandler != null) + if (this.openConnectionsHandler != null && shouldOpenRntbdChannels) { - await this.OpenRntbdChannelsAsync( - addressInfo, - openConnectionHandler); + await this.openConnectionsHandler + .TryOpenRntbdChannelsAsync( + addresses: addressInfo.Item2.Get(Protocol.Tcp)?.ReplicaTransportAddressUris); } } } } } - /// - /// Invokes the transport client delegate to open the Rntbd connection - /// and establish Rntbd context negotiation to the backend replica nodes. - /// - /// An instance of containing the partition key id - /// and it's corresponding address information. - /// The transport client callback delegate to be invoked at a - /// later point of time. - private async Task OpenRntbdChannelsAsync( - Tuple addressInfo, - Func openConnectionHandlerAsync) + /// + public void SetOpenConnectionsHandler(IOpenConnectionsHandler openConnectionsHandler) { - foreach (AddressInformation address in addressInfo.Item2.AllAddresses) - { - DefaultTrace.TraceVerbose("Attempting to open Rntbd connection to backend uri: {0}. '{1}'", - address.PhysicalUri, - System.Diagnostics.Trace.CorrelationManager.ActivityId); - try - { - await openConnectionHandlerAsync( - new Uri(address.PhysicalUri)); - } - catch (Exception ex) - { - DefaultTrace.TraceWarning("Failed to open Rntbd connection to backend uri: {0} with exception: {1}. '{2}'", - address.PhysicalUri, - ex, - System.Diagnostics.Trace.CorrelationManager.ActivityId); - } - } + this.openConnectionsHandler = openConnectionsHandler; } public async Task TryGetAddressesAsync( diff --git a/Microsoft.Azure.Cosmos/src/Routing/GlobalAddressResolver.cs b/Microsoft.Azure.Cosmos/src/Routing/GlobalAddressResolver.cs index 4e31b0fb40..51a6c6d2f3 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/GlobalAddressResolver.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/GlobalAddressResolver.cs @@ -39,6 +39,7 @@ internal sealed class GlobalAddressResolver : IAddressResolverExtension, IDispos private readonly CosmosHttpClient httpClient; private readonly ConcurrentDictionary addressCacheByEndpoint; private readonly bool enableTcpConnectionEndpointRediscovery; + private IOpenConnectionsHandler openConnectionsHandler; public GlobalAddressResolver( GlobalEndpointManager endpointManager, @@ -108,7 +109,7 @@ public async Task OpenAsync( databaseName: databaseName, collection: collection, partitionKeyRangeIdentities: ranges, - openConnectionHandler: null, + shouldOpenRntbdChannels: false, cancellationToken: cancellationToken)); } @@ -116,16 +117,14 @@ public async Task OpenAsync( } /// - /// Invokes the gateway address cache and passes the deligate to be invoked from the same. + /// Invokes the gateway address cache to open the rntbd connections to the backend replicas. /// /// A string containing the name of the database. /// A string containing the container's link uri. - /// The transport client callback delegate to be invoked at a later point of time. /// An Instance of the . public async Task OpenConnectionsToAllReplicasAsync( string databaseName, string containerLinkUri, - Func openConnectionHandlerAsync, CancellationToken cancellationToken = default) { try @@ -180,7 +179,7 @@ await this.addressCacheByEndpoint[firstPreferredReadRegion] databaseName: databaseName, collection: collection, partitionKeyRangeIdentities: partitionKeyRangeIdentities, - openConnectionHandler: openConnectionHandlerAsync, + shouldOpenRntbdChannels: true, cancellationToken: cancellationToken); } @@ -197,6 +196,20 @@ await this.addressCacheByEndpoint[firstPreferredReadRegion] } } + /// + public void SetOpenConnectionsHandler(IOpenConnectionsHandler openConnectionsHandler) + { + this.openConnectionsHandler = openConnectionsHandler; + + // Sets the openConnectionsHandler for the existing address cache. + // For the new address caches added later, the openConnectionsHandler + // will be set through the constructor. + foreach (EndpointCache endpointCache in this.addressCacheByEndpoint.Values) + { + endpointCache.AddressCache.SetOpenConnectionsHandler(openConnectionsHandler); + } + } + public async Task ResolveAsync( DocumentServiceRequest request, bool forceRefresh, @@ -284,6 +297,7 @@ private EndpointCache GetOrAddEndpoint(Uri endpoint) this.tokenProvider, this.serviceConfigReader, this.httpClient, + this.openConnectionsHandler, enableTcpConnectionEndpointRediscovery: this.enableTcpConnectionEndpointRediscovery); string location = this.endpointManager.GetLocation(endpoint); diff --git a/Microsoft.Azure.Cosmos/src/Routing/IAddressCache.cs b/Microsoft.Azure.Cosmos/src/Routing/IAddressCache.cs index e8a6ade3ba..35d10fa622 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/IAddressCache.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/IAddressCache.cs @@ -29,5 +29,12 @@ Task TryGetAddressesAsync( ServiceIdentity serviceIdentity, bool forceRefreshPartitionAddresses, CancellationToken cancellationToken); + + /// + /// Sets the instance to a global readonly + /// field for invoking the open connection request at a later point of time. + /// + /// An instance of . + void SetOpenConnectionsHandler(IOpenConnectionsHandler openConnectionsHandler); } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosHeaderTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosHeaderTests.cs index 95501d0b91..4bc35b105c 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosHeaderTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosHeaderTests.cs @@ -6,6 +6,7 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests { using System; using System.Collections.Generic; + using System.Linq; using System.Net; using System.Reflection; using System.Threading; @@ -102,13 +103,13 @@ public override async Task SendAsync(RequestMessage request, Ca private void ValidateLazyHeadersAreNotCreated(CosmosMessageHeadersInternal internalHeaders) { RequestNameValueCollection storeRequestHeaders = (RequestNameValueCollection)internalHeaders.INameValueCollection; - FieldInfo lazyHeaders = typeof(Documents.Collections.RequestNameValueCollection).GetField("lazyNotCommonHeaders", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); - Lazy> lazyNotCommonHeaders = (Lazy>)lazyHeaders.GetValue(storeRequestHeaders); + FieldInfo fieldInfo = storeRequestHeaders.GetType().GetField("notCommonHeaders", BindingFlags.Instance | BindingFlags.NonPublic); + Dictionary notCommonHeaders = (Dictionary)fieldInfo.GetValue(storeRequestHeaders); // Use the if instead of Assert.IsFalse to avoid creating the dictionary in the error message - if (lazyNotCommonHeaders.IsValueCreated) + if (notCommonHeaders != null && notCommonHeaders.Any()) { - Assert.Fail($"The lazy dictionary should not be created. Please add the following headers to the {nameof(Documents.Collections.RequestNameValueCollection)}: {JsonConvert.SerializeObject(lazyNotCommonHeaders.Value)}"); + Assert.Fail($"The lazy dictionary should not be created. Please add the following headers to the {nameof(Documents.Collections.RequestNameValueCollection)}: {JsonConvert.SerializeObject(notCommonHeaders)}"); } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TransportWrapperTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TransportWrapperTests.cs index d90e23a397..720f37375c 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TransportWrapperTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TransportWrapperTests.cs @@ -144,33 +144,10 @@ private static void ThrowTransportExceptionOnItemOperation( userPayload: true, payloadSent: false); - DocumentClientException documentClientException = new DocumentClientException( - message: "Exception", - innerException: transportException, - statusCode: System.Net.HttpStatusCode.Gone); IClientSideRequestStatistics requestStatistics = request.RequestContext.ClientRequestStatistics; requestStatistics.RecordResponse( request, - new StoreResult( - storeResponse: null, - exception: documentClientException, - partitionKeyRangeId: "PkRange", - lsn: 42, - quorumAckedLsn: 4242, - requestCharge: 9000.42, - currentReplicaSetSize: 3, - currentWriteQuorum: 4, - isValid: true, - storePhysicalAddress: physicalAddress, - globalCommittedLSN: 2, - numberOfReadRegions: 1, - itemLSN: 5, - sessionToken: null, - usingLocalLSN: true, - activityId: Guid.NewGuid().ToString(), - backendRequestDurationInMs: "0", - retryAfterInMs: "42", - transportRequestStats: new TransportRequestStats()), + StoreResult.CreateForTesting(transportRequestStats: new TransportRequestStats()).Target, DateTime.MinValue, DateTime.MaxValue); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml index f38fc77bb8..96c67772e6 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml @@ -214,26 +214,7 @@ StoreResponseStatistics storeResponseStatistics = new StoreResponseStatistics( DateTime.MinValue, DateTime.MaxValue, - new Documents.StoreResult( - storeResponse: new StoreResponse(), - exception: null, - partitionKeyRangeId: 42.ToString(), - lsn: 1337, - quorumAckedLsn: 23, - requestCharge: 3.14, - currentReplicaSetSize: 4, - currentWriteQuorum: 3, - isValid: true, - storePhysicalAddress: new Uri("http://storephysicaladdress.com"), - globalCommittedLSN: 1234, - numberOfReadRegions: 13, - itemLSN: 15, - sessionToken: new SimpleSessionToken(42), - usingLocalLSN: true, - activityId: Guid.Empty.ToString(), - backendRequestDurationInMs: "4.2", - retryAfterInMs: "42", - transportRequestStats: TraceWriterBaselineTests.CreateTransportRequestStats()), + StoreResult.CreateForTesting(transportRequestStats: TraceWriterBaselineTests.CreateTransportRequestStats()).Target, ResourceType.Document, OperationType.Query, "42", @@ -357,7 +338,7 @@ "IsValid": true, "StorePhysicalAddress": "http://storephysicaladdress.com/", "RequestCharge": 3.14, - "RetryAfterInMs": "42", + "RetryAfterInMs": "9000", "BELatencyInMs": "4.2", "transportRequestTimeline": { "requestTimeline": [ @@ -439,26 +420,7 @@ StoreResponseStatistics storeResponseStatistics = new StoreResponseStatistics( requestStartTime: default, requestResponseTime: default, - new Documents.StoreResult( - storeResponse: new StoreResponse(), - exception: default, - partitionKeyRangeId: default, - lsn: default, - quorumAckedLsn: default, - requestCharge: default, - currentReplicaSetSize: default, - currentWriteQuorum: default, - isValid: default, - storePhysicalAddress: default, - globalCommittedLSN: default, - numberOfReadRegions: default, - itemLSN: default, - sessionToken: default, - usingLocalLSN: default, - activityId: default, - retryAfterInMs: default, - backendRequestDurationInMs: default, - transportRequestStats: TraceWriterBaselineTests.CreateTransportRequestStats()), + StoreResult.CreateForTesting(storeResponse: new StoreResponse()).Target, resourceType: default, operationType: default, requestSessionToken: default, @@ -567,55 +529,7 @@ "RequestCharge": 0, "RetryAfterInMs": null, "BELatencyInMs": null, - "transportRequestTimeline": { - "requestTimeline": [ - { - "event": "Created", - "startTimeUtc": "2021-12-31T23:59:59.059Z", - "durationInMs": 1 - }, - { - "event": "ChannelAcquisitionStarted", - "startTimeUtc": "2021-12-31T23:59:59.06Z", - "durationInMs": 0 - }, - { - "event": "Pipelined", - "startTimeUtc": "2021-12-31T23:59:59.06Z", - "durationInMs": 0 - }, - { - "event": "Transit Time", - "startTimeUtc": "2021-12-31T23:59:59.06Z", - "durationInMs": 0 - }, - { - "event": "Received", - "startTimeUtc": "2021-12-31T23:59:59.06Z", - "durationInMs": 0 - }, - { - "event": "Completed", - "startTimeUtc": "2021-12-31T23:59:59.06Z", - "durationInMs": 0 - } - ], - "serviceEndpointStats": { - "inflightRequests": 2, - "openConnections": 1 - }, - "connectionStats": { - "waitforConnectionInit": "True", - "callsPendingReceive": 1, - "lastSendAttempt": "2021-12-31T23:59:59.059Z", - "lastSend": "2021-12-31T23:59:59.059Z", - "lastReceive": "2021-12-31T23:59:59.059Z" - }, - "requestSizeInBytes": 2, - "requestBodySizeInBytes": 1, - "responseMetadataSizeInBytes": 1, - "responseBodySizeInBytes": 1 - }, + "transportRequestTimeline": null, "TransportException": null } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs index 7faeba2a35..a41f08afa1 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs @@ -521,7 +521,6 @@ public Task UpdateAsync(IReadOnlyList addressCacheTokens, Can public Task OpenConnectionsToAllReplicasAsync( string databaseName, string containerLinkUri, - Func openConnectionHandlerAsync, CancellationToken cancellationToken = default) { throw new NotImplementedException(); @@ -531,6 +530,12 @@ public Task UpdateAsync(Documents.Rntbd.ServerKey serverKey, CancellationToken c { throw new NotImplementedException(); } + + public void SetOpenConnectionsHandler( + IOpenConnectionsHandler openConnectionHandler) + { + throw new NotImplementedException(); + } } private class MockTransportClient : TransportClient diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs index 46dbbc609e..3954b4ae8f 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs @@ -81,6 +81,7 @@ public void TestGatewayAddressCacheAutoRefreshOnSuboptimalPartition() this.mockTokenProvider.Object, this.mockServiceConfigReader.Object, MockCosmosUtil.CreateCosmosHttpClient(() => httpClient), + openConnectionsHandler: null, suboptimalPartitionForceRefreshIntervalInSeconds: 2); int initialAddressesCount = cache.TryGetAddressesAsync( @@ -116,6 +117,7 @@ public async Task TestGatewayAddressCacheUpdateOnConnectionResetAsync() this.mockTokenProvider.Object, this.mockServiceConfigReader.Object, MockCosmosUtil.CreateCosmosHttpClient(() => httpClient), + openConnectionsHandler: null, suboptimalPartitionForceRefreshIntervalInSeconds: 2, enableTcpConnectionEndpointRediscovery: true); @@ -173,6 +175,7 @@ public async Task TestGatewayAddressCacheAvoidCacheRefresWhenAlreadyUpdatedAsync this.mockTokenProvider.Object, this.mockServiceConfigReader.Object, MockCosmosUtil.CreateCosmosHttpClient(() => httpClient), + openConnectionsHandler: null, suboptimalPartitionForceRefreshIntervalInSeconds: 2, enableTcpConnectionEndpointRediscovery: true); @@ -224,7 +227,6 @@ public async Task TestGatewayAddressCacheAvoidCacheRefresWhenAlreadyUpdatedAsync mockHttpHandler.VerifyAll(); } - [TestMethod] [Timeout(2000)] public void GlobalAddressResolverUpdateAsyncSynchronizationTest() @@ -287,6 +289,7 @@ public async Task GatewayAddressCacheInNetworkRequestTestAsync() this.mockTokenProvider.Object, this.mockServiceConfigReader.Object, MockCosmosUtil.CreateCosmosHttpClient(() => httpClient), + openConnectionsHandler: null, suboptimalPartitionForceRefreshIntervalInSeconds: 2, enableTcpConnectionEndpointRediscovery: true); @@ -323,15 +326,15 @@ public async Task GatewayAddressCacheInNetworkRequestTestAsync() /// /// Test to validate that when is called with a - /// valid open connection handler callback delegate, the delegate method is indeed invoked. + /// valid open connection handler, the handler method is indeed invoked. /// [TestMethod] [Owner("dkunda")] - public async Task OpenConnectionsAsync_WithValidOpenConnectionHandlerDelegate_ShouldInvokeDelegateMethod() + public async Task OpenConnectionsAsync_WithValidOpenConnectionHandler_ShouldInvokeHandlerMethod() { // Arrange. FakeMessageHandler messageHandler = new (); - FakeTransportClient transportClient = new (shouldFailTransport: false); + FakeOpenConnectionHandler fakeOpenConnectionHandler = new (failingIndexes: new HashSet()); ContainerProperties containerProperties = ContainerProperties.CreateWithResourceId("ccZ1ANCszwk="); containerProperties.Id = "TestId"; containerProperties.PartitionKeyPath = "/pk"; @@ -346,6 +349,7 @@ public async Task OpenConnectionsAsync_WithValidOpenConnectionHandlerDelegate_Sh this.mockTokenProvider.Object, this.mockServiceConfigReader.Object, MockCosmosUtil.CreateCosmosHttpClient(() => httpClient), + openConnectionsHandler: fakeOpenConnectionHandler, suboptimalPartitionForceRefreshIntervalInSeconds: 2); // Act. @@ -356,26 +360,30 @@ await cache.OpenConnectionsAsync( { this.testPartitionKeyRangeIdentity }, - openConnectionHandler: transportClient.OpenConnectionAsync, + shouldOpenRntbdChannels: true, cancellationToken: CancellationToken.None); // Assert. - Assert.AreEqual(0, transportClient.GetExceptionCount()); - Assert.AreEqual(3, transportClient.GetSuccessfulInvocationCount()); + GatewayAddressCacheTests.AssertOpenConnectionHandlerAttributes( + fakeOpenConnectionHandler: fakeOpenConnectionHandler, + expectedExceptionCount: 0, + expectedMethodInvocationCount: 1, + expectedReceivedAddressesCount: 3, + expectedSuccessCount: 3); } /// /// Test to validate that when is invoked with a - /// open connection handler callback delegate that throws an exception, the delegate method is indeed invoked + /// open connection handler that throws an exception, the handler method is indeed invoked /// and the exception is handled in such a way that the cosmos client initialization does not fail. /// [TestMethod] [Owner("dkunda")] - public async Task OpenConnectionsAsync_WhenConnectionHandlerDelegateThrowsException_ShouldNotFailInitialization() + public async Task OpenConnectionsAsync_WhenConnectionHandlerThrowsException_ShouldNotFailInitialization() { // Arrange. FakeMessageHandler messageHandler = new (); - FakeTransportClient transportClient = new (shouldFailTransport: true); + FakeOpenConnectionHandler fakeOpenConnectionHandler = new(failingIndexes: new HashSet() { 0, 1, 2}); ContainerProperties containerProperties = ContainerProperties.CreateWithResourceId("ccZ1ANCszwk="); containerProperties.Id = "TestId"; containerProperties.PartitionKeyPath = "/pk"; @@ -387,6 +395,7 @@ public async Task OpenConnectionsAsync_WhenConnectionHandlerDelegateThrowsExcept this.mockTokenProvider.Object, this.mockServiceConfigReader.Object, MockCosmosUtil.CreateCosmosHttpClient(() => httpClient), + openConnectionsHandler: fakeOpenConnectionHandler, suboptimalPartitionForceRefreshIntervalInSeconds: 2); // Act. @@ -397,26 +406,30 @@ await cache.OpenConnectionsAsync( { this.testPartitionKeyRangeIdentity }, - openConnectionHandler: transportClient.OpenConnectionAsync, + shouldOpenRntbdChannels: true, cancellationToken: CancellationToken.None); // Assert. - Assert.AreEqual(3, transportClient.GetExceptionCount()); - Assert.AreEqual(0, transportClient.GetSuccessfulInvocationCount()); + GatewayAddressCacheTests.AssertOpenConnectionHandlerAttributes( + fakeOpenConnectionHandler: fakeOpenConnectionHandler, + expectedExceptionCount: 3, + expectedMethodInvocationCount: 1, + expectedReceivedAddressesCount: 3, + expectedSuccessCount: 0); } /// /// Test to validate that when is invoked with a null - /// open connection handler callback delegate, the delegate is never invoked, thus no attempt to open connection + /// open connection handler, the handler method is never invoked, thus no attempt to open connections /// to the backend replica happens. /// [TestMethod] [Owner("dkunda")] - public async Task OpenConnectionsAsync_WithNullOpenConnectionHandlerDelegate_ShouldNotInvokeDelegateMethod() + public async Task OpenConnectionsAsync_WithNullOpenConnectionHandler_ShouldNotInvokeHandlerMethod() { // Arrange. FakeMessageHandler messageHandler = new (); - FakeTransportClient transportClient = new(shouldFailTransport: false); + FakeOpenConnectionHandler fakeOpenConnectionHandler = new (failingIndexes: new HashSet()); ContainerProperties containerProperties = ContainerProperties.CreateWithResourceId("ccZ1ANCszwk="); containerProperties.Id = "TestId"; containerProperties.PartitionKeyPath = "/pk"; @@ -431,6 +444,7 @@ public async Task OpenConnectionsAsync_WithNullOpenConnectionHandlerDelegate_Sho this.mockTokenProvider.Object, this.mockServiceConfigReader.Object, MockCosmosUtil.CreateCosmosHttpClient(() => httpClient), + openConnectionsHandler: null, suboptimalPartitionForceRefreshIntervalInSeconds: 2); // Act. @@ -441,25 +455,29 @@ await cache.OpenConnectionsAsync( { this.testPartitionKeyRangeIdentity }, - openConnectionHandler: null, + shouldOpenRntbdChannels: true, cancellationToken: CancellationToken.None); // Assert. - Assert.AreEqual(0, transportClient.GetExceptionCount()); - Assert.AreEqual(0, transportClient.GetSuccessfulInvocationCount()); + GatewayAddressCacheTests.AssertOpenConnectionHandlerAttributes( + fakeOpenConnectionHandler: fakeOpenConnectionHandler, + expectedExceptionCount: 0, + expectedMethodInvocationCount: 0, + expectedReceivedAddressesCount: 0, + expectedSuccessCount: 0); } /// /// Test to validate that when is called with a - /// valid open connection handler callback delegate, the delegate method is indeed invoked and an attempt is made to open + /// valid open connection handler, the handler method is indeed invoked and an attempt is made to open /// the connections to the backend replicas. /// [TestMethod] [Owner("dkunda")] - public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WithValidHandlerDelegate_ShouldOpenConnectionsToBackend() + public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WithValidHandler_ShouldOpenConnectionsToBackend() { // Arrange. - FakeTransportClient transportClient = new (shouldFailTransport: false); + FakeOpenConnectionHandler fakeOpenConnectionHandler = new (failingIndexes: new HashSet()); UserAgentContainer container = new (clientId: 0); FakeMessageHandler messageHandler = new (); AccountProperties databaseAccount = new (); @@ -509,29 +527,35 @@ public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WithVa connectionPolicy: connectionPolicy, httpClient: MockCosmosUtil.CreateCosmosHttpClient(() => new HttpClient(messageHandler))); + globalAddressResolver.SetOpenConnectionsHandler( + openConnectionsHandler: fakeOpenConnectionHandler); + // Act. await globalAddressResolver.OpenConnectionsToAllReplicasAsync( databaseName: "test-db", containerLinkUri: "https://test.uri.cosmos.com", - openConnectionHandlerAsync: transportClient.OpenConnectionAsync, CancellationToken.None); // Assert. - Assert.AreEqual(0, transportClient.GetExceptionCount()); - Assert.AreEqual(3, transportClient.GetSuccessfulInvocationCount()); + GatewayAddressCacheTests.AssertOpenConnectionHandlerAttributes( + fakeOpenConnectionHandler: fakeOpenConnectionHandler, + expectedExceptionCount: 0, + expectedMethodInvocationCount: 1, + expectedReceivedAddressesCount: 3, + expectedSuccessCount: 3); } /// /// Test to validate that when is called with a - /// open connection handler callback delegate that throws an exception, the delegate method is indeed invoked and the - /// exception is handled in such a way that the cosmos client initialization does not fail. + /// open connection handler that throws an exception, the handler method is indeed invoked and the exception is handled + /// in such a way that the cosmos client initialization does not fail. /// [TestMethod] [Owner("dkunda")] public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WhenHandlerDelegateThrowsException_ShouldNotFailInitialization() { // Arrange. - FakeTransportClient transportClient = new(shouldFailTransport: true); + FakeOpenConnectionHandler fakeOpenConnectionHandler = new (failingIndexes: new HashSet() { 0, 2}); UserAgentContainer container = new(clientId: 0); FakeMessageHandler messageHandler = new(); AccountProperties databaseAccount = new(); @@ -581,16 +605,22 @@ public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WhenHa connectionPolicy: connectionPolicy, httpClient: MockCosmosUtil.CreateCosmosHttpClient(() => new HttpClient(messageHandler))); + globalAddressResolver.SetOpenConnectionsHandler( + openConnectionsHandler: fakeOpenConnectionHandler); + // Act. await globalAddressResolver.OpenConnectionsToAllReplicasAsync( databaseName: "test-db", containerLinkUri: "https://test.uri.cosmos.com", - openConnectionHandlerAsync: transportClient.OpenConnectionAsync, CancellationToken.None); // Assert. - Assert.AreEqual(3, transportClient.GetExceptionCount()); - Assert.AreEqual(0, transportClient.GetSuccessfulInvocationCount()); + GatewayAddressCacheTests.AssertOpenConnectionHandlerAttributes( + fakeOpenConnectionHandler: fakeOpenConnectionHandler, + expectedExceptionCount: 2, + expectedMethodInvocationCount: 1, + expectedReceivedAddressesCount: 3, + expectedSuccessCount: 1); } /// @@ -603,7 +633,7 @@ await globalAddressResolver.OpenConnectionsToAllReplicasAsync( public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WhenInternalExceptionThrownApartFromTransportError_ShouldThrowException() { // Arrange. - FakeTransportClient transportClient = new(shouldFailTransport: false); + FakeOpenConnectionHandler fakeOpenConnectionHandler = new (failingIndexes: new HashSet()); UserAgentContainer container = new(clientId: 0); FakeMessageHandler messageHandler = new(); AccountProperties databaseAccount = new(); @@ -664,18 +694,24 @@ public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WhenIn connectionPolicy: connectionPolicy, httpClient: MockCosmosUtil.CreateCosmosHttpClient(() => new HttpClient(messageHandler))); + globalAddressResolver.SetOpenConnectionsHandler( + openConnectionsHandler: fakeOpenConnectionHandler); + // Act. Exception ex = await Assert.ThrowsExceptionAsync(() => globalAddressResolver.OpenConnectionsToAllReplicasAsync( databaseName: "test-db", containerLinkUri: "https://test.uri.cosmos.com", - openConnectionHandlerAsync: transportClient.OpenConnectionAsync, CancellationToken.None)); // Assert. Assert.IsNotNull(ex); Assert.AreEqual(exceptionMessage, ex.Message); - Assert.AreEqual(0, transportClient.GetExceptionCount()); - Assert.AreEqual(0, transportClient.GetSuccessfulInvocationCount()); + GatewayAddressCacheTests.AssertOpenConnectionHandlerAttributes( + fakeOpenConnectionHandler: fakeOpenConnectionHandler, + expectedExceptionCount: 0, + expectedMethodInvocationCount: 0, + expectedReceivedAddressesCount: 0, + expectedSuccessCount: 0); } /// @@ -688,7 +724,7 @@ public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WhenIn public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WhenNullCollectionReturned_ShouldThrowException() { // Arrange. - FakeTransportClient transportClient = new (shouldFailTransport: false); + FakeOpenConnectionHandler fakeOpenConnectionHandler = new (failingIndexes: new HashSet()); UserAgentContainer container = new (clientId: 0); FakeMessageHandler messageHandler = new (); AccountProperties databaseAccount = new (); @@ -734,33 +770,39 @@ public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WhenNu connectionPolicy: connectionPolicy, httpClient: MockCosmosUtil.CreateCosmosHttpClient(() => new HttpClient(messageHandler))); + globalAddressResolver.SetOpenConnectionsHandler( + openConnectionsHandler: fakeOpenConnectionHandler); + // Act. CosmosException ce = await Assert.ThrowsExceptionAsync(() => globalAddressResolver.OpenConnectionsToAllReplicasAsync( databaseName: "test-db", containerLinkUri: "https://test.uri.cosmos.com", - openConnectionHandlerAsync: transportClient.OpenConnectionAsync, CancellationToken.None)); // Assert. Assert.IsNotNull(ce); Assert.IsTrue(ce.Message.Contains("Could not resolve the collection")); - Assert.AreEqual(0, transportClient.GetExceptionCount()); - Assert.AreEqual(0, transportClient.GetSuccessfulInvocationCount()); + GatewayAddressCacheTests.AssertOpenConnectionHandlerAttributes( + fakeOpenConnectionHandler: fakeOpenConnectionHandler, + expectedExceptionCount: 0, + expectedMethodInvocationCount: 0, + expectedReceivedAddressesCount: 0, + expectedSuccessCount: 0); } /// /// Test to validate that when is called with a - /// valid open connection handler callback delegate and some of the address resolving fails with exception, - /// then the GatewayAddressCache should ignore the failed addresses and the delegate method is indeed invoked + /// valid open connection handler and some of the address resolving fails with exception, then the + /// GatewayAddressCache should ignore the failed addresses and the handler method is indeed invoked /// for all resolved addresses. /// [TestMethod] [Owner("dkunda")] - public async Task OpenConnectionsAsync_WhenSomeAddressResolvingFailsWithException_ShouldIgnoreExceptionsAndInvokeDelegateMethodForOtherAddresses() + public async Task OpenConnectionsAsync_WhenSomeAddressResolvingFailsWithException_ShouldIgnoreExceptionsAndInvokeHandlerMethodForOtherAddresses() { // Arrange. FakeMessageHandler messageHandler = new (); - FakeTransportClient transportClient = new (shouldFailTransport: false); + FakeOpenConnectionHandler fakeOpenConnectionHandler = new (failingIndexes: new HashSet()); ContainerProperties containerProperties = ContainerProperties.CreateWithResourceId("ccZ1ANCszwk="); containerProperties.Id = "TestId"; containerProperties.PartitionKeyPath = "/pk"; @@ -810,6 +852,7 @@ public async Task OpenConnectionsAsync_WhenSomeAddressResolvingFailsWithExceptio this.mockTokenProvider.Object, this.mockServiceConfigReader.Object, mockHttpClient.Object, + openConnectionsHandler: fakeOpenConnectionHandler, suboptimalPartitionForceRefreshIntervalInSeconds: 2); // Act. @@ -817,12 +860,38 @@ await cache.OpenConnectionsAsync( databaseName: "test-database", collection: containerProperties, partitionKeyRangeIdentities: partitionKeyRangeIdentities, - openConnectionHandler: transportClient.OpenConnectionAsync, + shouldOpenRntbdChannels: true, cancellationToken: CancellationToken.None); // Assert. - Assert.AreEqual(0, transportClient.GetExceptionCount()); - Assert.AreEqual(addresses.Count, transportClient.GetSuccessfulInvocationCount()); + GatewayAddressCacheTests.AssertOpenConnectionHandlerAttributes( + fakeOpenConnectionHandler: fakeOpenConnectionHandler, + expectedExceptionCount: 0, + expectedMethodInvocationCount: 1, + expectedReceivedAddressesCount: addresses.Count, + expectedSuccessCount: addresses.Count); + } + + /// + /// Helper method to assert on the class attributes + /// to match with that of the expected ones. + /// + /// An instance of the . + /// The expected exception count for the test. + /// The expected method invocation count for the test. + /// The expected received addresses count for the test. + /// The expected successful messages count for the test. + private static void AssertOpenConnectionHandlerAttributes( + FakeOpenConnectionHandler fakeOpenConnectionHandler, + int expectedExceptionCount, + int expectedMethodInvocationCount, + int expectedReceivedAddressesCount, + int expectedSuccessCount) + { + Assert.AreEqual(expectedExceptionCount, fakeOpenConnectionHandler.GetExceptionCount()); + Assert.AreEqual(expectedMethodInvocationCount, fakeOpenConnectionHandler.GetMethodInvocationCount()); + Assert.AreEqual(expectedReceivedAddressesCount, fakeOpenConnectionHandler.GetReceivedAddressesCount()); + Assert.AreEqual(expectedSuccessCount, fakeOpenConnectionHandler.GetSuccessfulInvocationCount()); } private class FakeMessageHandler : HttpMessageHandler @@ -911,44 +980,111 @@ public override void Post(SendOrPostCallback d, object state) } } - public class FakeTransportClient + public class FakeOpenConnectionHandler : IOpenConnectionsHandler { private int exceptionCounter = 0; + private int methodInvocationCounter = 0; private int successInvocationCounter = 0; - private readonly bool shouldFailTransport; + private int totalReceivedAddressesCounter = 0; + private readonly HashSet failingIndexes; + private readonly bool useAttemptBasedFailingIndexs; + private readonly ManualResetEvent manualResetEvent; + private readonly Dictionary> failIndexesByAttempts; + + public FakeOpenConnectionHandler( + HashSet failingIndexes, + ManualResetEvent manualResetEvent = null) + { + this.failingIndexes = failingIndexes; + this.manualResetEvent = manualResetEvent; + } + + public FakeOpenConnectionHandler( + Dictionary> failIndexesByAttempts, + ManualResetEvent manualResetEvent = null) + { + this.useAttemptBasedFailingIndexs = true; + this.failIndexesByAttempts = failIndexesByAttempts; + this.manualResetEvent = manualResetEvent; + } + + public int GetSuccessfulInvocationCount() + { + return this.successInvocationCounter; + } + + public int GetExceptionCount() + { + return this.exceptionCounter; + } - public FakeTransportClient(bool shouldFailTransport) + public int GetReceivedAddressesCount() { - this.shouldFailTransport = shouldFailTransport; + return this.totalReceivedAddressesCounter; } - public Task OpenConnectionAsync(Uri physicalAddress) + public int GetMethodInvocationCount() { - if (this.shouldFailTransport) + return this.methodInvocationCounter; + } + + Task IOpenConnectionsHandler.TryOpenRntbdChannelsAsync( + IReadOnlyList addresses) + { + this.totalReceivedAddressesCounter = addresses.Count; + for (int i = 0; i < addresses.Count; i++) { - this.exceptionCounter++; - throw new TransportException( - errorCode: TransportErrorCode.ConnectionBroken, - innerException: new Exception("Transport Error Occurred."), - activityId: Guid.NewGuid(), - requestUri: physicalAddress, - sourceDescription: "SourceDescription", - userPayload: true, - payloadSent: false); + if (this.useAttemptBasedFailingIndexs) + { + if (this.failIndexesByAttempts.ContainsKey(i) && this.failIndexesByAttempts[i].Contains(this.methodInvocationCounter)) + { + this.ExecuteFailureCondition( + addresses: addresses, + index: i); + } + else + { + this.ExecuteSuccessCondition( + addresses: addresses, + index: i); + } + } + else + { + if (this.failingIndexes.Contains(i)) + { + this.ExecuteFailureCondition( + addresses: addresses, + index: i); + } + else + { + this.ExecuteSuccessCondition( + addresses: addresses, + index: i); + } + } } - this.successInvocationCounter++; + this.methodInvocationCounter++; + this.manualResetEvent?.Set(); return Task.CompletedTask; } - public int GetSuccessfulInvocationCount() + private void ExecuteSuccessCondition( + IReadOnlyList addresses, + int index) { - return this.successInvocationCounter; + addresses[index].SetConnected(); + this.successInvocationCounter++; } - public int GetExceptionCount() + private void ExecuteFailureCondition( + IReadOnlyList addresses, + int index) { - return this.exceptionCounter; + addresses[index].SetUnhealthy(); + this.exceptionCounter++; } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/StoreReaderTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/StoreReaderTest.cs index 7251848ea7..b92ca3c804 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/StoreReaderTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/StoreReaderTest.cs @@ -541,7 +541,7 @@ public void StoreReaderBarrierTest() // reads always go to read quorum (2) replicas int replicaCountToRead = 2; - IList result = storeReader.ReadMultipleReplicaAsync( + IList> result = storeReader.ReadMultipleReplicaAsync( entity, false /*includePrimary*/, replicaCountToRead, diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/ClientSideRequestStatisticsTraceDatumTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/ClientSideRequestStatisticsTraceDatumTests.cs index aac19174c9..2ec6e9db62 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/ClientSideRequestStatisticsTraceDatumTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/ClientSideRequestStatisticsTraceDatumTests.cs @@ -21,26 +21,7 @@ public class ClientSideRequestStatisticsTraceDatumTests private static readonly HttpRequestMessage request = new HttpRequestMessage(); private static readonly Uri uri = new Uri("http://someUri1.com"); private static readonly DocumentServiceRequest requestDsr = DocumentServiceRequest.Create(OperationType.Read, resourceType: ResourceType.Document, authorizationTokenType: AuthorizationTokenType.PrimaryMasterKey); - private static readonly StoreResult storeResult = new Documents.StoreResult( - storeResponse: new StoreResponse(), - exception: null, - partitionKeyRangeId: 42.ToString(), - lsn: 1337, - quorumAckedLsn: 23, - requestCharge: 3.14, - currentReplicaSetSize: 4, - currentWriteQuorum: 3, - isValid: true, - storePhysicalAddress: new Uri("http://storephysicaladdress.com"), - globalCommittedLSN: 1234, - numberOfReadRegions: 13, - itemLSN: 15, - sessionToken: new SimpleSessionToken(42), - usingLocalLSN: true, - activityId: Guid.Empty.ToString(), - backendRequestDurationInMs: "4.2", - retryAfterInMs: "42", - transportRequestStats: TraceWriterBaselineTests.CreateTransportRequestStats()); + private static readonly StoreResult storeResult = StoreResult.CreateForTesting(storeResponse: new StoreResponse()).Target; /// /// This test is needed because different parts of the SDK use the same ClientSideRequestStatisticsTraceDatum across multiple diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceTests.cs index 3a883d2456..f747d35d22 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceTests.cs @@ -100,31 +100,12 @@ public void ValidateStoreResultSerialization() ClientSideRequestStatisticsTraceDatum datum = new ClientSideRequestStatisticsTraceDatum(DateTime.UtcNow, new TraceSummary()); trace.AddDatum(datumKey, datum); - StoreResult storeResult = new StoreResult( - storeResponse: new StoreResponse(), - exception: null, - partitionKeyRangeId: 42.ToString(), - lsn: 1337, - quorumAckedLsn: 23, - requestCharge: 3.14, - currentReplicaSetSize: 4, - currentWriteQuorum: 3, - isValid: true, - storePhysicalAddress: new Uri("http://storephysicaladdress.com"), - globalCommittedLSN: 1234, - numberOfReadRegions: 13, - itemLSN: 15, - sessionToken: new SimpleSessionToken(42), - usingLocalLSN: true, - activityId: Guid.Empty.ToString(), - backendRequestDurationInMs: "4.2", - retryAfterInMs: "42", - transportRequestStats: TraceWriterBaselineTests.CreateTransportRequestStats()); + ReferenceCountedDisposable storeResult = StoreResult.CreateForTesting(storeResponse: new StoreResponse()); StoreResponseStatistics storeResponseStatistics = new StoreResponseStatistics( DateTime.MinValue, DateTime.MaxValue, - storeResult, + storeResult.Target, ResourceType.Document, OperationType.Query, "42", @@ -139,11 +120,11 @@ public void ValidateStoreResultSerialization() List jsonPropertyNames = storeResultJObject.Properties().Select(p => p.Name).ToList(); storeResultProperties.Add("BELatencyInMs"); - storeResultProperties.Remove(nameof(storeResult.BackendRequestDurationInMs)); + storeResultProperties.Remove(nameof(storeResult.Target.BackendRequestDurationInMs)); storeResultProperties.Add("TransportException"); - storeResultProperties.Remove(nameof(storeResult.Exception)); + storeResultProperties.Remove(nameof(storeResult.Target.Exception)); storeResultProperties.Add("transportRequestTimeline"); - storeResultProperties.Remove(nameof(storeResult.TransportRequestStats)); + storeResultProperties.Remove(nameof(storeResult.Target.TransportRequestStats)); foreach (string key in jsonPropertyNames) { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs index eace2eb9df..67bafdbf56 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs @@ -363,26 +363,7 @@ public void TraceData() StoreResponseStatistics storeResponseStatistics = new StoreResponseStatistics( DateTime.MinValue, DateTime.MaxValue, - new Documents.StoreResult( - storeResponse: new StoreResponse(), - exception: null, - partitionKeyRangeId: 42.ToString(), - lsn: 1337, - quorumAckedLsn: 23, - requestCharge: 3.14, - currentReplicaSetSize: 4, - currentWriteQuorum: 3, - isValid: true, - storePhysicalAddress: new Uri("http://storephysicaladdress.com"), - globalCommittedLSN: 1234, - numberOfReadRegions: 13, - itemLSN: 15, - sessionToken: new SimpleSessionToken(42), - usingLocalLSN: true, - activityId: Guid.Empty.ToString(), - backendRequestDurationInMs: "4.2", - retryAfterInMs: "42", - transportRequestStats: TraceWriterBaselineTests.CreateTransportRequestStats()), + StoreResult.CreateForTesting(transportRequestStats: TraceWriterBaselineTests.CreateTransportRequestStats()).Target, ResourceType.Document, OperationType.Query, "42", @@ -416,26 +397,7 @@ public void TraceData() StoreResponseStatistics storeResponseStatistics = new StoreResponseStatistics( requestStartTime: default, requestResponseTime: default, - new Documents.StoreResult( - storeResponse: new StoreResponse(), - exception: default, - partitionKeyRangeId: default, - lsn: default, - quorumAckedLsn: default, - requestCharge: default, - currentReplicaSetSize: default, - currentWriteQuorum: default, - isValid: default, - storePhysicalAddress: default, - globalCommittedLSN: default, - numberOfReadRegions: default, - itemLSN: default, - sessionToken: default, - usingLocalLSN: default, - activityId: default, - retryAfterInMs: default, - backendRequestDurationInMs: default, - transportRequestStats: TraceWriterBaselineTests.CreateTransportRequestStats()), + StoreResult.CreateForTesting(storeResponse: new StoreResponse()).Target, resourceType: default, operationType: default, requestSessionToken: default, From 2f0c28bb791ba19e53c72a73e9c8d27f2710dccf Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Tue, 10 Jan 2023 16:31:10 -0800 Subject: [PATCH 2/5] Code changes to add poland central region as a part of Regions.cs --- Microsoft.Azure.Cosmos/src/Regions.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Microsoft.Azure.Cosmos/src/Regions.cs b/Microsoft.Azure.Cosmos/src/Regions.cs index f08bbf4c91..853bc48267 100644 --- a/Microsoft.Azure.Cosmos/src/Regions.cs +++ b/Microsoft.Azure.Cosmos/src/Regions.cs @@ -344,5 +344,10 @@ public static class Regions /// Name of the Azure China East 3 region in the Azure Cosmos DB service. /// public const string ChinaEast3 = "China East 3"; + + /// + /// Name of the Azure Poland Central region in the Azure Cosmos DB service. + /// + public const string PolandCentral = "Poland Central"; } } From 76fe77f773f4948c952171839c27b7ed865dfabc Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Wed, 11 Jan 2023 10:26:41 -0800 Subject: [PATCH 3/5] Code changes to update contract to reflect new regions. --- .../Contracts/DotNetPreviewSDKAPI.json | 10 +++++----- .../Contracts/DotNetSDKAPI.json | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json index add1fce30e..4e2a06aeaf 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json @@ -165,11 +165,6 @@ "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.ChangeFeedMode AllVersionsAndDeletes;CanRead:True;CanWrite:False;Microsoft.Azure.Cosmos.ChangeFeedMode get_AllVersionsAndDeletes();IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, - "Microsoft.Azure.Cosmos.ChangeFeedMode LatestVersion": { - "Type": "Property", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.ChangeFeedMode LatestVersion;CanRead:True;CanWrite:False;Microsoft.Azure.Cosmos.ChangeFeedMode get_LatestVersion();IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, "Microsoft.Azure.Cosmos.ChangeFeedMode get_AllVersionsAndDeletes()": { "Type": "Method", "Attributes": [], @@ -179,6 +174,11 @@ "Type": "Method", "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.ChangeFeedMode get_LatestVersion();IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.ChangeFeedMode LatestVersion": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.ChangeFeedMode LatestVersion;CanRead:True;CanWrite:False;Microsoft.Azure.Cosmos.ChangeFeedMode get_LatestVersion();IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" } }, "NestedTypes": {} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json index 4e18b8084b..70e4a5d780 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json @@ -6570,6 +6570,11 @@ "Attributes": [], "MethodInfo": "System.String NorwayWest;IsInitOnly:False;IsStatic:True;" }, + "System.String PolandCentral": { + "Type": "Field", + "Attributes": [], + "MethodInfo": "System.String PolandCentral;IsInitOnly:False;IsStatic:True;" + }, "System.String QatarCentral": { "Type": "Field", "Attributes": [], From c78eb2febae8fa31d537f3b580b336531b801b92 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Wed, 11 Jan 2023 11:19:48 -0800 Subject: [PATCH 4/5] Revert "Code changes to update contract to reflect new regions." This reverts commit f171b3c1c9889043556ddf96bcd33ccd79565ad9. --- .../Contracts/DotNetPreviewSDKAPI.json | 10 +++++----- .../Contracts/DotNetSDKAPI.json | 5 ----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json index 4e2a06aeaf..add1fce30e 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json @@ -165,6 +165,11 @@ "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.ChangeFeedMode AllVersionsAndDeletes;CanRead:True;CanWrite:False;Microsoft.Azure.Cosmos.ChangeFeedMode get_AllVersionsAndDeletes();IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Microsoft.Azure.Cosmos.ChangeFeedMode LatestVersion": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.ChangeFeedMode LatestVersion;CanRead:True;CanWrite:False;Microsoft.Azure.Cosmos.ChangeFeedMode get_LatestVersion();IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Microsoft.Azure.Cosmos.ChangeFeedMode get_AllVersionsAndDeletes()": { "Type": "Method", "Attributes": [], @@ -174,11 +179,6 @@ "Type": "Method", "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.ChangeFeedMode get_LatestVersion();IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Microsoft.Azure.Cosmos.ChangeFeedMode LatestVersion": { - "Type": "Property", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.ChangeFeedMode LatestVersion;CanRead:True;CanWrite:False;Microsoft.Azure.Cosmos.ChangeFeedMode get_LatestVersion();IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" } }, "NestedTypes": {} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json index 70e4a5d780..4e18b8084b 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json @@ -6570,11 +6570,6 @@ "Attributes": [], "MethodInfo": "System.String NorwayWest;IsInitOnly:False;IsStatic:True;" }, - "System.String PolandCentral": { - "Type": "Field", - "Attributes": [], - "MethodInfo": "System.String PolandCentral;IsInitOnly:False;IsStatic:True;" - }, "System.String QatarCentral": { "Type": "Field", "Attributes": [], From e716a10d95453fd9398473653c1280f13f3ff99e Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Wed, 11 Jan 2023 11:20:10 -0800 Subject: [PATCH 5/5] Revert "Code changes to add poland central region as a part of Regions.cs" This reverts commit 1aafbf18f6d80e9a92baa301b6b23cf065e4b155. --- Microsoft.Azure.Cosmos/src/Regions.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Regions.cs b/Microsoft.Azure.Cosmos/src/Regions.cs index 853bc48267..f08bbf4c91 100644 --- a/Microsoft.Azure.Cosmos/src/Regions.cs +++ b/Microsoft.Azure.Cosmos/src/Regions.cs @@ -344,10 +344,5 @@ public static class Regions /// Name of the Azure China East 3 region in the Azure Cosmos DB service. /// public const string ChinaEast3 = "China East 3"; - - /// - /// Name of the Azure Poland Central region in the Azure Cosmos DB service. - /// - public const string PolandCentral = "Poland Central"; } }