public async Task <CosmosAccountSettings> InitializeReaderAsync() { CosmosAccountSettings databaseAccount = await GlobalEndpointManager.GetDatabaseAccountFromAnyLocationsAsync( this.serviceEndpoint, this.connectionPolicy.PreferredLocations, this.GetDatabaseAccountAsync); return(databaseAccount); }
public async Task InitializeAsync() { if (this.AccountSettings == null) { this.AccountSettings = await accountSettingsTaskFunc(); } }
public void ReadLocationRemoveAndAddMockTest() { // Setup dummpy read locations for the database account Collection <CosmosAccountLocation> readableLocations = new Collection <CosmosAccountLocation>(); CosmosAccountLocation writeLocation = new CosmosAccountLocation(); writeLocation.Name = "WriteLocation"; writeLocation.DatabaseAccountEndpoint = "https://writeendpoint.net/"; CosmosAccountLocation readLocation1 = new CosmosAccountLocation(); readLocation1.Name = "ReadLocation1"; readLocation1.DatabaseAccountEndpoint = "https://readendpoint1.net/"; CosmosAccountLocation readLocation2 = new CosmosAccountLocation(); readLocation2.Name = "ReadLocation2"; readLocation2.DatabaseAccountEndpoint = "https://readendpoint2.net/"; readableLocations.Add(writeLocation); readableLocations.Add(readLocation1); readableLocations.Add(readLocation2); CosmosAccountSettings databaseAccount = new CosmosAccountSettings(); 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.RefreshLocationAsync(databaseAccount).Wait(); Assert.IsTrue(globalEndpointManager.ReadEndpoints[0] == new Uri(readLocation1.DatabaseAccountEndpoint)); //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.RefreshLocationAsync(databaseAccount).Wait(); Assert.IsTrue(globalEndpointManager.ReadEndpoints[0] == new Uri(readLocation2.DatabaseAccountEndpoint)); //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.IsTrue(globalEndpointManager.ReadEndpoints[0] == new Uri(readLocation1.DatabaseAccountEndpoint)); }
public void EndpointFailureMockTest() { // Setup dummpy read locations for the database account Collection <CosmosAccountLocation> readableLocations = new Collection <CosmosAccountLocation>(); CosmosAccountLocation writeLocation = new CosmosAccountLocation(); writeLocation.Name = "WriteLocation"; writeLocation.DatabaseAccountEndpoint = "https://writeendpoint.net/"; CosmosAccountLocation readLocation1 = new CosmosAccountLocation(); readLocation1.Name = "ReadLocation1"; readLocation1.DatabaseAccountEndpoint = "https://readendpoint1.net/"; CosmosAccountLocation readLocation2 = new CosmosAccountLocation(); readLocation2.Name = "ReadLocation2"; readLocation2.DatabaseAccountEndpoint = "https://readendpoint2.net/"; readableLocations.Add(writeLocation); readableLocations.Add(readLocation1); readableLocations.Add(readLocation2); CosmosAccountSettings databaseAccount = new CosmosAccountSettings(); 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.RefreshLocationAsync(databaseAccount).Wait(); Assert.IsTrue(globalEndpointManager.ReadEndpoints[0] == new Uri(readLocation1.DatabaseAccountEndpoint)); //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(null).Wait(); Assert.IsTrue(globalEndpointManager.ReadEndpoints[0] == new Uri(readLocation2.DatabaseAccountEndpoint)); globalEndpointManager.MarkEndpointUnavailableForRead(globalEndpointManager.ReadEndpoints[0]); globalEndpointManager.RefreshLocationAsync(null).Wait(); Assert.IsTrue(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(1000); globalEndpointManager.RefreshLocationAsync(null).Wait(); Assert.IsTrue(globalEndpointManager.ReadEndpoints[0] == new Uri(readLocation1.DatabaseAccountEndpoint)); }
private async Task <CosmosAccountSettings> GetDatabaseAccountAsync(Uri serviceEndpoint) { HttpClient httpClient = this.messageHandler == null ? new HttpClient() : new HttpClient(this.messageHandler); httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.Version, HttpConstants.Versions.CurrentVersion); // Send client version. httpClient.AddUserAgentHeader(this.connectionPolicy.UserAgentContainer); httpClient.AddApiTypeHeader(this.apiType); string authorizationToken = string.Empty; if (this.hasAuthKeyResourceToken) { authorizationToken = HttpUtility.UrlEncode(this.authKeyResourceToken); } else { // Retrieve the document service properties. string xDate = DateTime.UtcNow.ToString("r", CultureInfo.InvariantCulture); httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.XDate, xDate); INameValueCollection headersCollection = new StringKeyValueCollection(); headersCollection.Add(HttpConstants.HttpHeaders.XDate, xDate); authorizationToken = AuthorizationHelper.GenerateKeyAuthorizationSignature( HttpConstants.HttpMethods.Get, serviceEndpoint, headersCollection, this.authKeyHashFunction); } httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.Authorization, authorizationToken); using (HttpResponseMessage responseMessage = await httpClient.GetHttpAsync( serviceEndpoint)) { using (DocumentServiceResponse documentServiceResponse = await ClientExtensions.ParseResponseAsync(responseMessage)) { CosmosAccountSettings databaseAccount = documentServiceResponse.GetInternalResource <CosmosAccountSettings>(CosmosAccountSettings.CreateNewInstance); return(databaseAccount); } } }
public virtual async Task <CosmosAccountSettings> GetDatabaseAccountAsync(HttpRequestMessage requestMessage, CancellationToken cancellationToken = default(CancellationToken)) { CosmosAccountSettings databaseAccount = null; // Get the ServiceDocumentResource from the gateway. using (HttpResponseMessage responseMessage = await this.gatewayStoreClient.SendHttpAsync(requestMessage, cancellationToken)) { using (DocumentServiceResponse documentServiceResponse = await ClientExtensions.ParseResponseAsync(responseMessage)) { databaseAccount = CosmosResource.FromStream <CosmosAccountSettings>(documentServiceResponse); } long longValue; IEnumerable <string> headerValues; if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.MaxMediaStorageUsageInMB, out headerValues) && (headerValues.Count() != 0)) { if (long.TryParse(headerValues.First(), out longValue)) { databaseAccount.MaxMediaStorageUsageInMB = longValue; } } if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.CurrentMediaStorageUsageInMB, out headerValues) && (headerValues.Count() != 0)) { if (long.TryParse(headerValues.First(), out longValue)) { databaseAccount.MediaStorageUsageInMB = longValue; } } if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountConsumedDocumentStorageInMB, out headerValues) && (headerValues.Count() != 0)) { if (long.TryParse(headerValues.First(), out longValue)) { databaseAccount.ConsumedDocumentStorageInMB = longValue; } } if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountProvisionedDocumentStorageInMB, out headerValues) && (headerValues.Count() != 0)) { if (long.TryParse(headerValues.First(), out longValue)) { databaseAccount.ProvisionedDocumentStorageInMB = longValue; } } if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountReservedDocumentStorageInMB, out headerValues) && (headerValues.Count() != 0)) { if (long.TryParse(headerValues.First(), out longValue)) { databaseAccount.ReservedDocumentStorageInMB = longValue; } } } return(databaseAccount); }