private async Task ValidateUserAgentStringAsync( CosmosClientOptions cosmosClientOptions, string userAgentContentToValidate, string databaseName, string containerName) { HttpClientHandlerHelper httpClientHandlerHelper = new HttpClientHandlerHelper() { RequestCallBack = (request, cancellationToken) => { string userAgent = request.Headers.UserAgent.ToString(); Assert.IsTrue(userAgent.Contains(userAgentContentToValidate)); return(null); } }; cosmosClientOptions.HttpClientFactory = () => new HttpClient(httpClientHandlerHelper); using (CosmosClient client = TestCommon.CreateCosmosClient(cosmosClientOptions)) { Cosmos.Database db = await client.CreateDatabaseIfNotExistsAsync(databaseName); await db.CreateContainerIfNotExistsAsync(containerName, "/pk"); } }
public async Task CreateAndInitializeWithCosmosClientBuilderTest() { int httpCallsMade = 0; HttpClientHandlerHelper httpClientHandlerHelper = new HttpClientHandlerHelper { RequestCallBack = (request, cancellationToken) => { httpCallsMade++; return(null); } }; (string endpoint, string authKey) = TestCommon.GetAccountInfo(); List <(string, string)> containers = new List <(string, string)> { ("ClientCreateAndInitializeDatabase", "ClientCreateAndInitializeContainer") }; CosmosClientBuilder builder = new CosmosClientBuilder(endpoint, authKey).WithHttpClientFactory(() => new HttpClient(httpClientHandlerHelper)); CosmosClient cosmosClient = await builder.BuildAndInitializeAsync(containers); Assert.IsNotNull(cosmosClient); int httpCallsMadeAfterCreation = httpCallsMade; ContainerInternal container = (ContainerInternal)cosmosClient.GetContainer("ClientCreateAndInitializeDatabase", "ClientCreateAndInitializeContainer"); ItemResponse <ToDoActivity> readResponse = await container.ReadItemAsync <ToDoActivity>("1", new Cosmos.PartitionKey("Status1")); Assert.AreEqual(httpCallsMade, httpCallsMadeAfterCreation); cosmosClient.Dispose(); }
public async Task GatewaySameSessionTokenTest() { string createSessionToken = null; GatewaySessionTokenTests.HttpClientHandlerHelper httpClientHandler = new HttpClientHandlerHelper { ResponseCallBack = (result) => { HttpResponseMessage response = result.Result; if (response.StatusCode != HttpStatusCode.Created) { return(response); } response.Headers.TryGetValues("x-ms-session-token", out IEnumerable <string> sessionTokens); foreach (string singleToken in sessionTokens) { createSessionToken = singleToken; break; } return(response); } }; using (CosmosClient client = TestCommon.CreateCosmosClient(builder => builder .WithConnectionModeGateway() .WithConsistencyLevel(Cosmos.ConsistencyLevel.Session) .WithHttpClientFactory(() => new HttpClient(httpClientHandler)))) { Container container = client.GetContainer(this.database.Id, this.Container.Id); ToDoActivity item = ToDoActivity.CreateRandomToDoActivity("Status1001", "1001"); ItemResponse <ToDoActivity> itemResponse = await container.CreateItemAsync(item); // Read back the created Item and check if the session token is identical. string docLink = "dbs/" + this.database.Id + "/colls/" + this.Container.Id + "/docs/1001"; Documents.Collections.INameValueCollection headers = new StoreRequestNameValueCollection(); headers.Set(HttpConstants.HttpHeaders.PartitionKey, "[\"Status1001\"]"); DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, docLink, AuthorizationTokenType.PrimaryMasterKey, headers); await GatewayStoreModel.ApplySessionTokenAsync(request, Cosmos.ConsistencyLevel.Session, client.DocumentClient.sessionContainer, await client.DocumentClient.GetPartitionKeyRangeCacheAsync(NoOpTrace.Singleton), await client.DocumentClient.GetCollectionCacheAsync(NoOpTrace.Singleton)); string readSessionToken = request.Headers[HttpConstants.HttpHeaders.SessionToken]; Assert.AreEqual(readSessionToken, createSessionToken); } }
public void TestInitialize() { this.actualInfo = new List <ClientTelemetryProperties>(); Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetrySchedulingInSeconds, "1"); Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEndpoint, telemetryEndpointUrl); HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper { RequestCallBack = (request, cancellation) => { if (request.RequestUri.AbsoluteUri.Equals(ClientTelemetryOptions.GetClientTelemetryEndpoint().AbsoluteUri)) { HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); string jsonObject = request.Content.ReadAsStringAsync().GetAwaiter().GetResult(); lock (this.actualInfo) { this.actualInfo.Add(JsonConvert.DeserializeObject <ClientTelemetryProperties>(jsonObject)); } return(Task.FromResult(result)); } else if (request.RequestUri.AbsoluteUri.Equals(ClientTelemetryOptions.GetVmMetadataUrl().AbsoluteUri)) { HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); object jsonObject = JsonConvert.DeserializeObject("{\"compute\":{\"azEnvironment\":\"AzurePublicCloud\",\"customData\":\"\",\"isHostCompatibilityLayerVm\":\"false\",\"licenseType\":\"\",\"location\":\"eastus\",\"name\":\"sourabh-testing\",\"offer\":\"UbuntuServer\",\"osProfile\":{\"adminUsername\":\"azureuser\",\"computerName\":\"sourabh-testing\"},\"osType\":\"Linux\",\"placementGroupId\":\"\",\"plan\":{\"name\":\"\",\"product\":\"\",\"publisher\":\"\"},\"platformFaultDomain\":\"0\",\"platformUpdateDomain\":\"0\",\"provider\":\"Microsoft.Compute\",\"publicKeys\":[{\"keyData\":\"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5uCeOAm3ehmhI+2PbMoMl17Eo\r\nqfHKCycSaBJsv9qxlmBOuFheSJc1XknJleXUSsuTO016/d1PyWpevnqOZNRksWoa\r\nJvQ23sDTxcK+X2OP3QlCUeX4cMjPXqlL8z1UYzU4Bx3fFvf8fs67G3N72sxWBw5P\r\nZyuXyhBm0NCe/2NYMKgEDT4ma8XszO0ikbhoPKbMbgHAQk/ktWQHNcqYOPQKEWqp\r\nEK1R0rjS2nmtovfScP/ZGXcvOpJ1/NDBo4dh1K+OxOGM/4PSH/F448J5Zy4eAyEk\r\nscys+IpeIOTOlRUy/703SNIX0LEWlnYqbyL9c1ypcYLQqF76fKkDfzzFI/OWVlGw\r\nhj/S9uP8iMsR+fhGIbn6MAa7O4DWPWLuedSp7KDYyjY09gqNJsfuaAJN4LiC6bPy\r\nhknm0PVLK3ux7EUOt+cZrHCdIFWbdOtxiPNIl1tkv9kV5aE5Aj2gJm4MeB9uXYhS\r\nOuksboBc0wyUGrl9+XZJ1+NlZOf7IjVi86CieK8= generated-by-azure\r\n\",\"path\":\"/home/azureuser/.ssh/authorized_keys\"}],\"publisher\":\"Canonical\",\"resourceGroupName\":\"sourabh-telemetry-sdk\",\"resourceId\":\"/subscriptions/8fba6d4f-7c37-4d13-9063-fd58ad2b86e2/resourceGroups/sourabh-telemetry-sdk/providers/Microsoft.Compute/virtualMachines/sourabh-testing\",\"securityProfile\":{\"secureBootEnabled\":\"false\",\"virtualTpmEnabled\":\"false\"},\"sku\":\"18.04-LTS\",\"storageProfile\":{\"dataDisks\":[],\"imageReference\":{\"id\":\"\",\"offer\":\"UbuntuServer\",\"publisher\":\"Canonical\",\"sku\":\"18.04-LTS\",\"version\":\"latest\"},\"osDisk\":{\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\",\"diffDiskSettings\":{\"option\":\"\"},\"diskSizeGB\":\"30\",\"encryptionSettings\":{\"enabled\":\"false\"},\"image\":{\"uri\":\"\"},\"managedDisk\":{\"id\":\"/subscriptions/8fba6d4f-7c37-4d13-9063-fd58ad2b86e2/resourceGroups/sourabh-telemetry-sdk/providers/Microsoft.Compute/disks/sourabh-testing_OsDisk_1_9a54abfc5ba149c6a106bd9e5b558c2a\",\"storageAccountType\":\"Premium_LRS\"},\"name\":\"sourabh-testing_OsDisk_1_9a54abfc5ba149c6a106bd9e5b558c2a\",\"osType\":\"Linux\",\"vhd\":{\"uri\":\"\"},\"writeAcceleratorEnabled\":\"false\"}},\"subscriptionId\":\"8fba6d4f-7c37-4d13-9063-fd58ad2b86e2\",\"tags\":\"azsecpack:nonprod;platformsettings.host_environment.service.platform_optedin_for_rootcerts:true\",\"tagsList\":[{\"name\":\"azsecpack\",\"value\":\"nonprod\"},{\"name\":\"platformsettings.host_environment.service.platform_optedin_for_rootcerts\",\"value\":\"true\"}],\"version\":\"18.04.202103250\",\"vmId\":\"d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd\",\"vmScaleSetName\":\"\",\"vmSize\":\"Standard_D2s_v3\",\"zone\":\"1\"},\"network\":{\"interface\":[{\"ipv4\":{\"ipAddress\":[{\"privateIpAddress\":\"10.0.7.5\",\"publicIpAddress\":\"\"}],\"subnet\":[{\"address\":\"10.0.7.0\",\"prefix\":\"24\"}]},\"ipv6\":{\"ipAddress\":[]},\"macAddress\":\"000D3A8F8BA0\"}]}}"); string payload = JsonConvert.SerializeObject(jsonObject); result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); return(Task.FromResult(result)); } return(null); } }; List <string> preferredRegionList = new List <string> { "region1", "region2" }; this.cosmosClientBuilder = TestCommon.GetDefaultConfiguration() .WithApplicationPreferredRegions(preferredRegionList) .WithTelemetryEnabled() .WithHttpClientFactory(() => new HttpClient(httpHandler)); }
private async Task <Container> CreateContainer(bool isLocalQuorumConsistency) { HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper { ResponseIntercepter = async(response) => { string responseString = await response.Content.ReadAsStringAsync(); if (responseString.Contains("databaseAccountEndpoint")) { AccountProperties accountProperties = JsonConvert.DeserializeObject <AccountProperties>(responseString); accountProperties.Consistency.DefaultConsistencyLevel = Cosmos.ConsistencyLevel.Eventual; response.Content = new StringContent(JsonConvert.SerializeObject(accountProperties), Encoding.UTF8, "application/json"); } return(response); } }; RequestHandlerHelper handlerHelper = new RequestHandlerHelper { UpdateRequestMessage = (request) => { if (request.OperationType == Documents.OperationType.Read) { Assert.AreEqual(Cosmos.ConsistencyLevel.Strong.ToString(), request.Headers[Documents.HttpConstants.HttpHeaders.ConsistencyLevel]); } } }; this.cosmosClient = TestCommon.CreateCosmosClient(x => { CosmosClientBuilder builder = x.AddCustomHandlers(handlerHelper) .WithHttpClientFactory(() => new HttpClient(httpHandler)); if (isLocalQuorumConsistency) { builder.AllowUpgradeConsistencyToLocalQuorum(); } }); Database database = await this.cosmosClient.CreateDatabaseAsync(Guid.NewGuid().ToString(), cancellationToken : new CancellationTokenSource().Token); return(await database.CreateContainerAsync(id : Guid.NewGuid().ToString(), partitionKeyPath : "/pk")); }
public async Task QueryPlanRetryTimeoutTestAsync() { HttpClientHandlerHelper httpClientHandler = new HttpClientHandlerHelper(); using (CosmosClient client = TestCommon.CreateCosmosClient(builder => builder .WithConnectionModeGateway() .WithHttpClientFactory(() => new HttpClient(httpClientHandler)))) { Cosmos.Database database = await client.CreateDatabaseAsync(Guid.NewGuid().ToString()); ContainerInternal container = (ContainerInternal)await database.CreateContainerAsync(Guid.NewGuid().ToString(), "/pk"); Container gatewayQueryPlanContainer = new ContainerInlineCore( client.ClientContext, (DatabaseInternal)database, container.Id, new DisableServiceInterop(client.ClientContext, container)); bool isQueryRequestFound = false; httpClientHandler.RequestCallBack = (request, cancellationToken) => { if (request.Headers.TryGetValues(HttpConstants.HttpHeaders.IsQueryPlanRequest, out IEnumerable <string> isQueryPlan) && isQueryPlan.FirstOrDefault() == bool.TrueString) { Assert.IsFalse(isQueryRequestFound, "Should only call get query plan once."); Assert.AreNotEqual(cancellationToken, default); isQueryRequestFound = true; } }; using FeedIterator <JObject> iterator = gatewayQueryPlanContainer.GetItemQueryIterator <JObject>("select * From T order by T.status"); FeedResponse <JObject> response = await iterator.ReadNextAsync(); Assert.IsTrue(isQueryRequestFound, "Query plan call back was not called."); string diagnostics = response.Diagnostics.ToString(); JObject parsedDiagnostics = JObject.Parse(diagnostics); JToken contextList = parsedDiagnostics["Context"]; Assert.IsNotNull(contextList.First(x => x["Id"]?.ToString() == "CreateQueryPipeline")); Assert.IsNotNull(contextList.First(x => x["Id"]?.ToString() == "Microsoft.Azure.Cosmos.GatewayStoreModel")); Assert.IsNotNull(contextList.First(x => x["Id"]?.ToString() == "SendHttpHelperAsync:" + nameof(HttpTimeoutPolicyControlPlaneRetriableHotPath))); await database.DeleteStreamAsync(); } }
public void TestInitialize() { this.actualInfo = new List <ClientTelemetryProperties>(); HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper { RequestCallBack = (request, cancellation) => { if (request.RequestUri.AbsoluteUri.Equals(ClientTelemetryOptions.GetClientTelemetryEndpoint().AbsoluteUri)) { HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); string jsonObject = request.Content.ReadAsStringAsync().GetAwaiter().GetResult(); lock (this.actualInfo) { this.actualInfo.Add(JsonConvert.DeserializeObject <ClientTelemetryProperties>(jsonObject)); } return(Task.FromResult(result)); } else if (request.RequestUri.AbsoluteUri.Equals(ClientTelemetryOptions.GetVmMetadataUrl().AbsoluteUri)) { HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); string payload = JsonConvert.SerializeObject(ClientTelemetryTests.jsonObject); result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); return(Task.FromResult(result)); } return(null); } }; this.preferredRegionList = new List <string> { "region1", "region2" }; this.cosmosClientBuilder = TestCommon.GetDefaultConfiguration() .WithApplicationPreferredRegions(this.preferredRegionList) .WithHttpClientFactory(() => new HttpClient(httpHandler)); }
public async Task ValidateExceptionOnInitTask() { int httpCallCount = 0; HttpClientHandlerHelper httpClientHandlerHelper = new HttpClientHandlerHelper() { RequestCallBack = (request, cancellToken) => { Interlocked.Increment(ref httpCallCount); return(null); } }; using CosmosClient cosmosClient = new CosmosClient( accountEndpoint: "https://localhost:8081", authKeyOrResourceToken: Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())), clientOptions: new CosmosClientOptions() { HttpClientFactory = () => new HttpClient(httpClientHandlerHelper), }); CosmosException cosmosException1 = null; try { await cosmosClient.GetContainer("db", "c").ReadItemAsync <JObject>("Random", new Cosmos.PartitionKey("DoesNotExist")); } catch (CosmosException ex) { cosmosException1 = ex; Assert.IsTrue(httpCallCount > 0); } httpCallCount = 0; try { await cosmosClient.GetContainer("db", "c").ReadItemAsync <JObject>("Random2", new Cosmos.PartitionKey("DoesNotExist2")); } catch (CosmosException ex) { Assert.IsFalse(object.ReferenceEquals(ex, cosmosException1)); Assert.IsTrue(httpCallCount > 0); } }
public async Task TestHeadersPassedinByClient() { int httpCallCount = 0; IEnumerable <string> sdkSupportedCapabilities = null; HttpClientHandlerHelper httpClientHandlerHelper = new HttpClientHandlerHelper() { RequestCallBack = (request, cancellToken) => { Interlocked.Increment(ref httpCallCount); request.Headers.TryGetValues(HttpConstants.HttpHeaders.SDKSupportedCapabilities, out sdkSupportedCapabilities); return(null); } }; using CosmosClient cosmosClient = new CosmosClient( accountEndpoint: "https://localhost:8081", authKeyOrResourceToken: Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())), clientOptions: new CosmosClientOptions() { HttpClientFactory = () => new HttpClient(httpClientHandlerHelper), }); CosmosException cosmosException1 = null; try { await cosmosClient.GetContainer("db", "c").ReadItemAsync <JObject>("Random", new Cosmos.PartitionKey("DoesNotExist")); } catch (CosmosException ex) { cosmosException1 = ex; Assert.IsTrue(httpCallCount > 0); } Assert.IsNotNull(sdkSupportedCapabilities); Assert.AreEqual(1, sdkSupportedCapabilities.Count()); string sdkSupportedCapability = sdkSupportedCapabilities.Single(); ulong capability = ulong.Parse(sdkSupportedCapability); Assert.AreEqual((ulong)SDKSupportedCapabilities.PartitionMerge, capability & (ulong)SDKSupportedCapabilities.PartitionMerge, $" received header value as {sdkSupportedCapability}"); }
public async Task CreateItemWithSubStatusCodeTest(ConnectionMode mode) { HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper(); HttpClient httpClient = new HttpClient(httpHandler); httpHandler.RequestCallBack = (request, cancellation) => { if (request.RequestUri.AbsoluteUri.Equals(ClientTelemetryOptions.GetClientTelemetryEndpoint().AbsoluteUri)) { HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); string jsonObject = request.Content.ReadAsStringAsync().GetAwaiter().GetResult(); lock (this.actualInfo) { this.actualInfo.Add(JsonConvert.DeserializeObject <ClientTelemetryProperties>(jsonObject)); } return(Task.FromResult(result)); } else if (request.RequestUri.AbsoluteUri.Equals(ClientTelemetryOptions.GetVmMetadataUrl().AbsoluteUri)) { HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); string payload = JsonConvert.SerializeObject(ClientTelemetryTests.jsonObject); result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); return(Task.FromResult(result)); } else if (request.Method == HttpMethod.Get && request.RequestUri.AbsolutePath == "//addresses/") { HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.Forbidden); // Add a substatus code that is not part of the enum. // This ensures that if the backend adds a enum the status code is not lost. result.Headers.Add(WFConstants.BackendHeaders.SubStatus, 999999.ToString(CultureInfo.InvariantCulture)); string payload = JsonConvert.SerializeObject(new Error() { Message = "test message" }); result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); return(Task.FromResult(result)); } return(null); }; // Replacing originally initialized cosmos Builder with this one with new handler this.cosmosClientBuilder = this.cosmosClientBuilder .WithHttpClientFactory(() => new HttpClient(httpHandler)); Container container = await this.CreateClientAndContainer(mode); try { ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue"); ItemResponse <ToDoActivity> createResponse = await container.CreateItemAsync <ToDoActivity>(testItem); Assert.Fail("Request should throw exception."); } catch (CosmosException ce) when(ce.StatusCode == HttpStatusCode.Forbidden) { Assert.AreEqual(999999, ce.SubStatusCode); } IDictionary <string, long> expectedRecordCountInOperation = new Dictionary <string, long> { { Documents.OperationType.Create.ToString(), 1 } }; await this.WaitAndAssert(expectedOperationCount : 2, expectedOperationRecordCountMap : expectedRecordCountInOperation, expectedSubstatuscode : "999999"); }
public async Task InitTaskThreadSafe() { int httpCallCount = 0; int metadataCallCount = 0; bool delayCallBack = true; var isInitializedField = typeof(VmMetadataApiHandler).GetField("isInitialized", BindingFlags.Static | BindingFlags.NonPublic); isInitializedField.SetValue(null, false); var azMetadataField = typeof(VmMetadataApiHandler).GetField("azMetadata", BindingFlags.Static | BindingFlags.NonPublic); azMetadataField.SetValue(null, null); HttpClientHandlerHelper httpClientHandlerHelper = new HttpClientHandlerHelper() { RequestCallBack = async(request, cancellToken) => { if (request.RequestUri.AbsoluteUri == VmMetadataApiHandler.vmMetadataEndpointUrl.AbsoluteUri) { Interlocked.Increment(ref metadataCallCount); } else { Interlocked.Increment(ref httpCallCount); } while (delayCallBack) { await Task.Delay(TimeSpan.FromMilliseconds(100)); } return(null); } }; using CosmosClient cosmosClient = new CosmosClient( accountEndpoint: "https://localhost:8081", authKeyOrResourceToken: Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())), clientOptions: new CosmosClientOptions() { HttpClientFactory = () => new HttpClient(httpClientHandlerHelper), }); List <Task> tasks = new List <Task>(); Container container = cosmosClient.GetContainer("db", "c"); for (int loop = 0; loop < 3; loop++) { for (int i = 0; i < 10; i++) { tasks.Add(this.ReadNotFound(container)); } ValueStopwatch sw = ValueStopwatch.StartNew(); while (this.TaskStartedCount < 10 && sw.Elapsed.TotalSeconds < 2) { await Task.Delay(TimeSpan.FromMilliseconds(50)); } Assert.AreEqual(10, this.TaskStartedCount, "Tasks did not start"); delayCallBack = false; await Task.WhenAll(tasks); Assert.AreEqual(1, metadataCallCount, "Only one call for VM Metadata call with be made"); Assert.AreEqual(1, httpCallCount, "Only the first task should do the http call. All other should wait on the first task"); // Reset counters and retry the client to verify a new http call is done for new requests tasks.Clear(); delayCallBack = true; this.TaskStartedCount = 0; httpCallCount = 0; } }