public void GlobalAddressResolverUpdateAsyncSynchronizationTest() { SynchronizationContext prevContext = SynchronizationContext.Current; try { TestSynchronizationContext syncContext = new TestSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(syncContext); syncContext.Post(_ => { UserAgentContainer container = new UserAgentContainer(); FakeMessageHandler messageHandler = new FakeMessageHandler(); AccountProperties databaseAccount = new AccountProperties(); Mock <IDocumentClientInternal> mockDocumentClient = new Mock <IDocumentClientInternal>(); mockDocumentClient.Setup(owner => owner.ServiceEndpoint).Returns(new Uri("https://blabla.com/")); mockDocumentClient.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny <Uri>(), It.IsAny <CancellationToken>())).ReturnsAsync(databaseAccount); GlobalEndpointManager globalEndpointManager = new GlobalEndpointManager(mockDocumentClient.Object, new ConnectionPolicy()); GlobalPartitionEndpointManager partitionKeyRangeLocationCache = new GlobalPartitionEndpointManagerCore(globalEndpointManager); ConnectionPolicy connectionPolicy = new ConnectionPolicy { RequestTimeout = TimeSpan.FromSeconds(10) }; GlobalAddressResolver globalAddressResolver = new GlobalAddressResolver( endpointManager: globalEndpointManager, partitionKeyRangeLocationCache: partitionKeyRangeLocationCache, protocol: Documents.Client.Protocol.Tcp, tokenProvider: this.mockTokenProvider.Object, collectionCache: null, routingMapProvider: null, serviceConfigReader: this.mockServiceConfigReader.Object, connectionPolicy: connectionPolicy, httpClient: MockCosmosUtil.CreateCosmosHttpClient(() => new HttpClient(messageHandler))); ConnectionStateListener connectionStateListener = new ConnectionStateListener(globalAddressResolver); connectionStateListener.OnConnectionEvent(ConnectionEvent.ReadEof, DateTime.Now, new Documents.Rntbd.ServerKey(new Uri("https://endpoint.azure.com:4040/"))); }, state: null); } finally { SynchronizationContext.SetSynchronizationContext(prevContext); } }
public void DocumentClient_BuildHttpClientFactory_WithFactory() { HttpClient staticHttpClient = new HttpClient(); Mock <Func <HttpClient> > mockFactory = new Mock <Func <HttpClient> >(); mockFactory.Setup(f => f()).Returns(staticHttpClient); ConnectionPolicy connectionPolicy = new ConnectionPolicy() { HttpClientFactory = mockFactory.Object }; HttpClient httpClient = DocumentClient.BuildHttpClient(connectionPolicy, ApiType.None, messageHandler: null); Assert.IsNotNull(httpClient); Assert.IsNotNull(httpClient); Mock.Get(mockFactory.Object) .Verify(f => f(), Times.Once); }
public async Task DocumentClient_BuildHttpClientFactory_WithHandler() { HttpMessageHandler messageHandler = new CustomMessageHandler(); ConnectionPolicy connectionPolicy = new ConnectionPolicy() { HttpClientFactory = () => new HttpClient(messageHandler) }; CosmosHttpClient httpClient = CosmosHttpClientCore.CreateWithConnectionPolicy( apiType: ApiType.None, eventSource: DocumentClientEventSource.Instance, connectionPolicy: connectionPolicy, httpMessageHandler: null, sendingRequestEventArgs: null, receivedResponseEventArgs: null); Assert.IsNotNull(httpClient); HttpResponseMessage response = await httpClient.GetAsync( uri : new Uri("https://localhost"), additionalHeaders : new DictionaryNameValueCollection(), resourceType : ResourceType.Document, diagnosticsContext : null, cancellationToken : default);
public async Task EndpointFailureMockTest() { Environment.SetEnvironmentVariable("MinimumIntervalForNonForceRefreshLocationInMS", "100"); try { // Setup dummpy read locations for the database account Collection <AccountRegion> readableLocations = new Collection <AccountRegion>(); AccountRegion writeLocation = new AccountRegion(); writeLocation.Name = "WriteLocation"; writeLocation.Endpoint = "https://writeendpoint.net/"; AccountRegion readLocation1 = new AccountRegion(); readLocation1.Name = "ReadLocation1"; readLocation1.Endpoint = "https://readendpoint1.net/"; AccountRegion readLocation2 = new AccountRegion(); readLocation2.Name = "ReadLocation2"; readLocation2.Endpoint = "https://readendpoint2.net/"; readableLocations.Add(writeLocation); readableLocations.Add(readLocation1); readableLocations.Add(readLocation2); AccountProperties databaseAccount = new AccountProperties(); databaseAccount.ReadLocationsInternal = readableLocations; //Setup mock owner "document client" Mock <IDocumentClientInternal> mockOwner = new Mock <IDocumentClientInternal>(); mockOwner.Setup(owner => owner.ServiceEndpoint).Returns(new Uri("https://defaultendpoint.net/")); int getAccountInfoCount = 0; mockOwner.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny <Uri>(), It.IsAny <CancellationToken>())) .Callback(() => getAccountInfoCount++) .ReturnsAsync(databaseAccount); //Create connection policy and populate preferred locations ConnectionPolicy connectionPolicy = new ConnectionPolicy(); connectionPolicy.PreferredLocations.Add("ReadLocation1"); connectionPolicy.PreferredLocations.Add("ReadLocation2"); using (GlobalEndpointManager globalEndpointManager = new GlobalEndpointManager(mockOwner.Object, connectionPolicy)) { globalEndpointManager.InitializeAccountPropertiesAndStartBackgroundRefresh(databaseAccount); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], new Uri(readLocation1.Endpoint)); //Mark each of the read locations as unavailable and validate that the read endpoint switches to the next preferred region / default endpoint. globalEndpointManager.MarkEndpointUnavailableForRead(globalEndpointManager.ReadEndpoints[0]); await globalEndpointManager.RefreshLocationAsync(); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], new Uri(readLocation2.Endpoint)); globalEndpointManager.MarkEndpointUnavailableForRead(globalEndpointManager.ReadEndpoints[0]); await globalEndpointManager.RefreshLocationAsync(); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], globalEndpointManager.WriteEndpoints[0]); getAccountInfoCount = 0; //Sleep a second for the unavailable endpoint entry to expire and background refresh timer to kick in await Task.Delay(TimeSpan.FromSeconds(3)); Assert.IsTrue(getAccountInfoCount > 0, "Callback is not working. There should be at least one call in this time frame."); await globalEndpointManager.RefreshLocationAsync(); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], new Uri(readLocation1.Endpoint)); } Assert.IsTrue(getAccountInfoCount > 0, "Callback is not working. There should be at least one call in this time frame."); getAccountInfoCount = 0; Thread.Sleep(TimeSpan.FromSeconds(3)); Assert.AreEqual(0, getAccountInfoCount, "There should be no more account calls after the GlobalEndpointManager is disposed"); } finally { Environment.SetEnvironmentVariable("MinimumIntervalForNonForceRefreshLocationInMS", null); } }
/// <summary> /// Initialize the instance of the RetryPolicy class /// </summary> public RetryPolicy(GlobalEndpointManager globalEndpointManager, ConnectionPolicy connectionPolicy) { this.enableEndpointDiscovery = connectionPolicy.EnableEndpointDiscovery; this.globalEndpointManager = globalEndpointManager; this.retryOptions = connectionPolicy.RetryOptions; }
internal static CosmosClientContext Create( CosmosClient cosmosClient, DocumentClient documentClient, CosmosClientOptions clientOptions, RequestInvokerHandler requestInvokerHandler = null) { if (cosmosClient == null) { throw new ArgumentNullException(nameof(cosmosClient)); } if (documentClient == null) { throw new ArgumentNullException(nameof(documentClient)); } clientOptions = ClientContextCore.CreateOrCloneClientOptions(clientOptions); ConnectionPolicy connectionPolicy = clientOptions.GetConnectionPolicy(cosmosClient.ClientId); ClientTelemetry telemetry = null; if (connectionPolicy.EnableClientTelemetry) { try { telemetry = ClientTelemetry.CreateAndStartBackgroundTelemetry( documentClient: documentClient, userAgent: connectionPolicy.UserAgentContainer.UserAgent, connectionMode: connectionPolicy.ConnectionMode, authorizationTokenProvider: cosmosClient.AuthorizationTokenProvider, diagnosticsHelper: DiagnosticsHandlerHelper.Instance, preferredRegions: clientOptions.ApplicationPreferredRegions); } catch (Exception ex) { DefaultTrace.TraceInformation($"Error While starting Telemetry Job : {ex.Message}. Hence disabling Client Telemetry"); connectionPolicy.EnableClientTelemetry = false; } } else { DefaultTrace.TraceInformation("Client Telemetry Disabled."); } if (requestInvokerHandler == null) { //Request pipeline ClientPipelineBuilder clientPipelineBuilder = new ClientPipelineBuilder( cosmosClient, clientOptions.ConsistencyLevel, clientOptions.CustomHandlers, telemetry: telemetry); requestInvokerHandler = clientPipelineBuilder.Build(); } CosmosSerializerCore serializerCore = CosmosSerializerCore.Create( clientOptions.Serializer, clientOptions.SerializerOptions); // This sets the serializer on client options which gives users access to it if a custom one is not configured. clientOptions.SetSerializerIfNotConfigured(serializerCore.GetCustomOrDefaultSerializer()); CosmosResponseFactoryInternal responseFactory = new CosmosResponseFactoryCore(serializerCore); return(new ClientContextCore( client: cosmosClient, clientOptions: clientOptions, serializerCore: serializerCore, cosmosResponseFactory: responseFactory, requestHandler: requestInvokerHandler, documentClient: documentClient, userAgent: documentClient.ConnectionPolicy.UserAgentContainer.UserAgent, batchExecutorCache: new BatchAsyncContainerExecutorCache(), telemetry: telemetry)); }
public void ReadLocationRemoveAndAddMockTest() { string originalConfigValue = Environment.GetEnvironmentVariable("MinimumIntervalForNonForceRefreshLocationInMS"); Environment.SetEnvironmentVariable("MinimumIntervalForNonForceRefreshLocationInMS", "1000"); // Setup dummpy read locations for the database account Collection <AccountRegion> readableLocations = new Collection <AccountRegion>(); AccountRegion writeLocation = new AccountRegion(); writeLocation.Name = "WriteLocation"; writeLocation.Endpoint = "https://writeendpoint.net/"; AccountRegion readLocation1 = new AccountRegion(); readLocation1.Name = "ReadLocation1"; readLocation1.Endpoint = "https://readendpoint1.net/"; AccountRegion readLocation2 = new AccountRegion(); readLocation2.Name = "ReadLocation2"; readLocation2.Endpoint = "https://readendpoint2.net/"; readableLocations.Add(writeLocation); readableLocations.Add(readLocation1); readableLocations.Add(readLocation2); AccountProperties databaseAccount = new AccountProperties(); databaseAccount.ReadLocationsInternal = readableLocations; //Setup mock owner "document client" Mock <IDocumentClientInternal> mockOwner = new Mock <IDocumentClientInternal>(); mockOwner.Setup(owner => owner.ServiceEndpoint).Returns(new Uri("https://defaultendpoint.net/")); mockOwner.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny <Uri>(), It.IsAny <CancellationToken>())).ReturnsAsync(databaseAccount); //Create connection policy and populate preferred locations ConnectionPolicy connectionPolicy = new ConnectionPolicy(); connectionPolicy.PreferredLocations.Add("ReadLocation1"); connectionPolicy.PreferredLocations.Add("ReadLocation2"); GlobalEndpointManager globalEndpointManager = new GlobalEndpointManager(mockOwner.Object, connectionPolicy); globalEndpointManager.InitializeAccountPropertiesAndStartBackgroundRefresh(databaseAccount); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], new Uri(readLocation1.Endpoint)); //Remove location 1 from read locations and validate that the read endpoint switches to the next preferred location readableLocations.Remove(readLocation1); databaseAccount.ReadLocationsInternal = readableLocations; globalEndpointManager.InitializeAccountPropertiesAndStartBackgroundRefresh(databaseAccount); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], new Uri(readLocation2.Endpoint)); //Add location 1 back to read locations and validate that location 1 becomes the read endpoint again. readableLocations.Add(readLocation1); databaseAccount.ReadLocationsInternal = readableLocations; //Sleep a bit for the refresh timer to kick in and rediscover location 1 Thread.Sleep(2000); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], new Uri(readLocation1.Endpoint)); Environment.SetEnvironmentVariable("MinimumIntervalForNonForceRefreshLocationInMS", "1000"); }
public async Task EndpointFailureMockTest() { // Setup dummpy read locations for the database account Collection <AccountRegion> readableLocations = new Collection <AccountRegion>(); AccountRegion writeLocation = new AccountRegion(); writeLocation.Name = "WriteLocation"; writeLocation.Endpoint = "https://writeendpoint.net/"; AccountRegion readLocation1 = new AccountRegion(); readLocation1.Name = "ReadLocation1"; readLocation1.Endpoint = "https://readendpoint1.net/"; AccountRegion readLocation2 = new AccountRegion(); readLocation2.Name = "ReadLocation2"; readLocation2.Endpoint = "https://readendpoint2.net/"; readableLocations.Add(writeLocation); readableLocations.Add(readLocation1); readableLocations.Add(readLocation2); AccountProperties databaseAccount = new AccountProperties(); databaseAccount.ReadLocationsInternal = readableLocations; //Setup mock owner "document client" Mock <IDocumentClientInternal> mockOwner = new Mock <IDocumentClientInternal>(); mockOwner.Setup(owner => owner.ServiceEndpoint).Returns(new Uri("https://defaultendpoint.net/")); mockOwner.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny <Uri>(), It.IsAny <CancellationToken>())).ReturnsAsync(databaseAccount); //Create connection policy and populate preferred locations ConnectionPolicy connectionPolicy = new ConnectionPolicy(); connectionPolicy.PreferredLocations.Add("ReadLocation1"); connectionPolicy.PreferredLocations.Add("ReadLocation2"); GlobalEndpointManager globalEndpointManager = new GlobalEndpointManager(mockOwner.Object, connectionPolicy); globalEndpointManager.InitializeAccountPropertiesAndStartBackgroundRefresh(databaseAccount); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], new Uri(readLocation1.Endpoint)); //Mark each of the read locations as unavailable and validate that the read endpoint switches to the next preferred region / default endpoint. globalEndpointManager.MarkEndpointUnavailableForRead(globalEndpointManager.ReadEndpoints[0]); globalEndpointManager.RefreshLocationAsync().Wait(); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], new Uri(readLocation2.Endpoint)); globalEndpointManager.MarkEndpointUnavailableForRead(globalEndpointManager.ReadEndpoints[0]); await globalEndpointManager.RefreshLocationAsync(); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], globalEndpointManager.WriteEndpoints[0]); //Sleep a second for the unavailable endpoint entry to expire and background refresh timer to kick in Thread.Sleep(3000); await globalEndpointManager.RefreshLocationAsync(); Assert.AreEqual(globalEndpointManager.ReadEndpoints[0], new Uri(readLocation1.Endpoint)); }