// </ReadItemAsync> // <QueryItems> private static async Task QueryItems() { //****************************************************************************************************************** // 1.4 - Query for items by a property other than Id // // NOTE: Operations like AsEnumerable(), ToList(), ToArray() will make as many trips to the database // as required to fetch the entire result-set. Even if you set MaxItemCount to a smaller number. // MaxItemCount just controls how many results to fetch each trip. //****************************************************************************************************************** Console.WriteLine("\n1.4 - Querying for a item using its AccountNumber property"); QueryDefinition query = new QueryDefinition( "select * from sales s where s.AccountNumber = @AccountInput ") .WithParameter("@AccountInput", "Account1"); FeedIterator <SalesOrder> resultSet = container.GetItemQueryIterator <SalesOrder>( query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Account1"), MaxItemCount = 1 }); List <SalesOrder> allSalesForAccount1 = new List <SalesOrder>(); while (resultSet.HasMoreResults) { FeedResponse <SalesOrder> response = await resultSet.ReadNextAsync(); SalesOrder sale = response.First(); Console.WriteLine($"\n1.4.1 Account Number: {sale.AccountNumber}; Id: {sale.Id};"); if (response.Diagnostics != null) { Console.WriteLine($" Diagnostics {response.Diagnostics.ToString()}"); } allSalesForAccount1.Add(sale); } Console.WriteLine($"\n1.4.2 Query found {allSalesForAccount1.Count} items."); // Use the same query as before but get the cosmos response message to access the stream directly FeedIterator streamResultSet = container.GetItemQueryStreamIterator( query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Account1"), MaxItemCount = 10, MaxConcurrency = 1 }); List <SalesOrder> allSalesForAccount1FromStream = new List <SalesOrder>(); while (streamResultSet.HasMoreResults) { using (ResponseMessage responseMessage = await streamResultSet.ReadNextAsync()) { // Item stream operations do not throw exceptions for better performance if (responseMessage.IsSuccessStatusCode) { dynamic streamResponse = FromStream <dynamic>(responseMessage.Content); List <SalesOrder> salesOrders = streamResponse.Documents.ToObject <List <SalesOrder> >(); Console.WriteLine($"\n1.4.3 - Item Query via stream {salesOrders.Count}"); allSalesForAccount1FromStream.AddRange(salesOrders); } else { Console.WriteLine($"Query item from stream failed. Status code: {responseMessage.StatusCode} Message: {responseMessage.ErrorMessage}"); } } } Console.WriteLine($"\n1.4.4 Query found {allSalesForAccount1FromStream.Count} items."); if (allSalesForAccount1.Count != allSalesForAccount1FromStream.Count) { throw new InvalidDataException($"Both query operations should return the same list"); } }
// Async main requires c# 7.1 which is set in the csproj with the LangVersion attribute // <Main> public static async Task Main(string[] args) { IConfigurationRoot configuration = new ConfigurationBuilder() .AddJsonFile("appSettings.json") .Build(); string endpoint = configuration["EndPointUrl"]; if (string.IsNullOrEmpty(endpoint)) { throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json"); } string authKey = configuration["AuthorizationKey"]; if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key")) { throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json"); } // Connecting to Emulator. Change if you want a live account CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder(endpoint, authKey); // Declare a JSON schema to use with the schema validation handler var myContainerSchema = JSchema.Parse(@"{ 'type': 'object', 'properties': { 'name': {'type': 'string'} }, 'required': ['name'] }"); cosmosClientBuilder.AddCustomHandlers( new LoggingHandler(), new ConcurrencyHandler(), new ThrottlingHandler(), new SchemaValidationHandler((database: "mydb", container: "mycoll2", schema: myContainerSchema)) ); CosmosClient client = cosmosClientBuilder.Build(); DatabaseResponse databaseResponse = await client.CreateDatabaseIfNotExistsAsync("mydb"); Database database = databaseResponse.Database; ContainerResponse containerResponse = await database.CreateContainerIfNotExistsAsync("mycoll", "/id"); Container container = containerResponse.Container; Item item = new Item() { Id = Guid.NewGuid().ToString(), Name = "Test Item", Description = "Some random test item", Completed = false }; // Create await container.CreateItemAsync <Item>(item, new PartitionKey(item.Id)); item.Completed = true; // Replace await container.ReplaceItemAsync <Item>(item, item.Id, new PartitionKey(item.Id)); // Querying FeedIterator <Item> query = container.GetItemQueryIterator <Item>(new QueryDefinition("SELECT * FROM c"), requestOptions: new QueryRequestOptions() { MaxConcurrency = 1 }); List <Item> results = new List <Item>(); while (query.HasMoreResults) { FeedResponse <Item> response = await query.ReadNextAsync(); results.AddRange(response.ToList()); } // Read Item ItemResponse <Item> cosmosItemResponse = await container.ReadItemAsync <Item>(item.Id, new PartitionKey(item.Id)); ItemRequestOptions itemRequestOptions = new ItemRequestOptions() { IfMatchEtag = cosmosItemResponse.ETag }; // Concurrency List <Task <ItemResponse <Item> > > tasks = new List <Task <ItemResponse <Item> > > { UpdateItemForConcurrency(container, itemRequestOptions, item), UpdateItemForConcurrency(container, itemRequestOptions, item) }; try { await Task.WhenAll(tasks); } catch (CosmosException ex) { // Verify that our custom handler caught the scenario Debug.Assert(999.Equals(ex.SubStatusCode)); } // Delete await container.DeleteItemAsync <Item>(item.Id, new PartitionKey(item.Id)); // Schema validation containerResponse = await database.CreateContainerIfNotExistsAsync("mycoll2", "/id"); container = containerResponse.Container; // Insert an item with invalid schema var writeSucceeded = true; try { await container.CreateItemAsync(new { id = "12345" }); } catch (InvalidItemSchemaException) { writeSucceeded = false; } Debug.Assert(!writeSucceeded); // Insert an item with valid schema try { await container.CreateItemAsync(new { id = "12345", name = "Youri" }); writeSucceeded = true; } catch (InvalidItemSchemaException) { writeSucceeded = false; } Debug.Assert(writeSucceeded); // Update an item with invalid schema try { await container.ReplaceItemAsync(new { id = "12345" }, "12345"); writeSucceeded = true; } catch (InvalidItemSchemaException) { writeSucceeded = false; } Debug.Assert(!writeSucceeded); // Update an item with valid schema try { await container.ReplaceItemAsync(new { id = "12345", name = "Vladimir" }, "12345"); writeSucceeded = true; } catch (InvalidItemSchemaException) { writeSucceeded = false; } Debug.Assert(writeSucceeded); }
private static async Task <List <WeakReference> > CreateWeakReferenceToFeedIterator( Container container) { List <WeakReference> weakReferences = new List <WeakReference>(); // Test draining typed iterator using (FeedIterator <JObject> feedIterator = container.GetItemQueryIterator <JObject>( queryDefinition: null, continuationToken: null, requestOptions: new QueryRequestOptions { MaxItemCount = 1000, })) { weakReferences.Add(new WeakReference(feedIterator, true)); while (feedIterator.HasMoreResults) { FeedResponse <JObject> response = await feedIterator.ReadNextAsync(); foreach (JObject jObject in response) { Assert.IsNotNull(jObject); } } } // Test draining stream iterator using (FeedIterator feedIterator = container.GetItemQueryStreamIterator( queryDefinition: null, continuationToken: null, requestOptions: new QueryRequestOptions { MaxItemCount = 1000, })) { weakReferences.Add(new WeakReference(feedIterator, true)); while (feedIterator.HasMoreResults) { using (ResponseMessage response = await feedIterator.ReadNextAsync()) { Assert.IsNotNull(response.Content); } } } // Test single page typed iterator using (FeedIterator <JObject> feedIterator = container.GetItemQueryIterator <JObject>( queryText: "SELECT * FROM c", continuationToken: null, requestOptions: new QueryRequestOptions { MaxItemCount = 10, })) { weakReferences.Add(new WeakReference(feedIterator, true)); FeedResponse <JObject> response = await feedIterator.ReadNextAsync(); foreach (JObject jObject in response) { Assert.IsNotNull(jObject); } } // Test single page stream iterator using (FeedIterator feedIterator = container.GetItemQueryStreamIterator( queryText: "SELECT * FROM c", continuationToken: null, requestOptions: new QueryRequestOptions { MaxItemCount = 10, })) { weakReferences.Add(new WeakReference(feedIterator, true)); using (ResponseMessage response = await feedIterator.ReadNextAsync()) { Assert.IsNotNull(response.Content); } } return(weakReferences); }
private static async Task RunDemo() { ToDoActivity activeActivity = new ToDoActivity() { Id = Guid.NewGuid().ToString(), ActivityId = Guid.NewGuid().ToString(), PartitionKey = "myPartitionKey", Status = "Active" }; ToDoActivity completedActivity = new ToDoActivity() { Id = Guid.NewGuid().ToString(), ActivityId = Guid.NewGuid().ToString(), PartitionKey = "myPartitionKey", Status = "Completed" }; // Create items that use System.Text.Json serialization attributes ItemResponse <ToDoActivity> createActiveActivity = await container.CreateItemAsync(activeActivity, new PartitionKey(activeActivity.PartitionKey)); Console.WriteLine($"Created Active activity with id {createActiveActivity.Resource.Id} that cost {createActiveActivity.RequestCharge}"); ItemResponse <ToDoActivity> createCompletedActivity = await container.CreateItemAsync(completedActivity, new PartitionKey(completedActivity.PartitionKey)); Console.WriteLine($"Created Completed activity with id {createCompletedActivity.Resource.Id} that cost {createCompletedActivity.RequestCharge}"); // Execute queries materializing responses using System.Text.Json // NOTE: GetItemLinqQueryable does not support System.Text.Json attributes. LINQ will not translate the name based on the attributes // which can result in no or invalid results coming back. https://github.com/Azure/azure-cosmos-dotnet-v3/issues/3250 using FeedIterator <ToDoActivity> iterator = container.GetItemQueryIterator <ToDoActivity>("select * from c where c.status = 'Completed'"); while (iterator.HasMoreResults) { FeedResponse <ToDoActivity> queryResponse = await iterator.ReadNextAsync(); Console.WriteLine($"Obtained {queryResponse.Count} results on query for {queryResponse.RequestCharge}"); } // Read items materializing responses using System.Text.Json ItemResponse <ToDoActivity> readActiveActivity = await container.ReadItemAsync <ToDoActivity>(activeActivity.Id, new PartitionKey(completedActivity.PartitionKey)); Console.WriteLine($"Read Active activity with id {activeActivity.Id} that cost {readActiveActivity.RequestCharge}"); // Using TransactionalBatch to atomically create multiple items as a single transaction string batchPartitionKey = "myPartitionKey"; ToDoActivity newActivity = new ToDoActivity() { Id = Guid.NewGuid().ToString(), ActivityId = Guid.NewGuid().ToString(), PartitionKey = batchPartitionKey, Status = "Active" }; ToDoActivity anotherNewActivity = new ToDoActivity() { Id = Guid.NewGuid().ToString(), ActivityId = Guid.NewGuid().ToString(), PartitionKey = batchPartitionKey, Status = "Active" }; TransactionalBatchResponse batchResponse = await container.CreateTransactionalBatch(new PartitionKey(batchPartitionKey)) .CreateItem(newActivity) .CreateItem(anotherNewActivity) .ExecuteAsync(); if (batchResponse.IsSuccessStatusCode) { Console.WriteLine($"Completed transactional batch that cost {batchResponse.RequestCharge}"); } }
public static async Task Main(string[] args) { using (CosmosClient client = new CosmosClient(_endpointUri, _primaryKey)) { DatabaseResponse databaseResponse = await client.CreateDatabaseIfNotExistsAsync("EntertainmentDatabase"); Database targetDatabase = databaseResponse.Database; await Console.Out.WriteLineAsync($"Database Id:\t{targetDatabase.Id}"); ContainerResponse response = await targetDatabase.CreateContainerIfNotExistsAsync("DefaultCollection", "/id"); Container defaultContainer = response.Container; await Console.Out.WriteLineAsync($"Default Container Id:\t{defaultContainer.Id}"); IndexingPolicy indexingPolicy = new IndexingPolicy { IndexingMode = IndexingMode.Consistent, Automatic = true, IncludedPaths = { new IncludedPath { Path = "/*" } } }; ContainerProperties containerProperties = new ContainerProperties("CustomCollection", $"/{nameof(IInteraction.type)}") { IndexingPolicy = indexingPolicy, }; var containerResponse = await targetDatabase.CreateContainerIfNotExistsAsync(containerProperties, 10000); var customContainer = containerResponse.Container; //var customContainer = targetDatabase.GetContainer("CustomCollection"); await Console.Out.WriteLineAsync($"Custom Container Id:\t{customContainer.Id}"); var foodInteractions = new Bogus.Faker <PurchaseFoodOrBeverage>() .RuleFor(i => i.id, (fake) => Guid.NewGuid().ToString()) .RuleFor(i => i.type, (fake) => nameof(PurchaseFoodOrBeverage)) .RuleFor(i => i.unitPrice, (fake) => Math.Round(fake.Random.Decimal(1.99m, 15.99m), 2)) .RuleFor(i => i.quantity, (fake) => fake.Random.Number(1, 5)) .RuleFor(i => i.totalPrice, (fake, user) => Math.Round(user.unitPrice * user.quantity, 2)) .GenerateLazy(500); foreach (var interaction in foodInteractions) { ItemResponse <PurchaseFoodOrBeverage> result = await customContainer.CreateItemAsync(interaction); await Console.Out.WriteLineAsync($"Item Created\t{result.Resource.id}"); } var tvInteractions = new Bogus.Faker <WatchLiveTelevisionChannel>() .RuleFor(i => i.id, (fake) => Guid.NewGuid().ToString()) .RuleFor(i => i.type, (fake) => nameof(WatchLiveTelevisionChannel)) .RuleFor(i => i.minutesViewed, (fake) => fake.Random.Number(1, 45)) .RuleFor(i => i.channelName, (fake) => fake.PickRandom(new List <string> { "NEWS-6", "DRAMA-15", "ACTION-12", "DOCUMENTARY-4", "SPORTS-8" })) .GenerateLazy(500); foreach (var interaction in tvInteractions) { ItemResponse <WatchLiveTelevisionChannel> result = await customContainer.CreateItemAsync(interaction); await Console.Out.WriteLineAsync($"Item Created\t{result.Resource.id}"); } var mapInteractions = new Bogus.Faker <ViewMap>() .RuleFor(i => i.id, (fake) => Guid.NewGuid().ToString()) .RuleFor(i => i.type, (fake) => nameof(ViewMap)) .RuleFor(i => i.minutesViewed, (fake) => fake.Random.Number(1, 45)) .GenerateLazy(500); foreach (var interaction in mapInteractions) { ItemResponse <ViewMap> result = await customContainer.CreateItemAsync(interaction); await Console.Out.WriteLineAsync($"Item Created\t{result.Resource.id}"); } FeedIterator <GeneralInteraction> query = customContainer.GetItemQueryIterator <GeneralInteraction>("SELECT * FROM c"); while (query.HasMoreResults) { foreach (GeneralInteraction interaction in await query.ReadNextAsync()) { Console.Out.WriteLine($"[{interaction.type}]\t{interaction.id}"); } } } }
// </Main> // <RunDemoAsync> private static async Task RunDemoAsync( CosmosClient client, Database database) { //-------------------------------------------------------------------------------------------------- // We need Two Containers, Two Users, and some permissions for this sample, // So let's go ahead and set these up initially //-------------------------------------------------------------------------------------------------- // Get, or Create, two separate Containers Container container1 = await database.CreateContainerAsync( id : "Container1", partitionKeyPath : "/AccountNumber"); Container container2 = await database.CreateContainerAsync( id : "Container2", partitionKeyPath : "/AccountNumber"); // Insert two documents in to col1 SalesOrder salesOrder1 = new SalesOrder() { Id = "order1", AccountNumber = "partitionKey1" }; await container1.CreateItemAsync <SalesOrder>( salesOrder1, new PartitionKey(salesOrder1.AccountNumber)); SalesOrder salesOrder2 = new SalesOrder() { Id = "order2", AccountNumber = "pk2" }; await container1.CreateItemAsync <SalesOrder>( salesOrder2, new PartitionKey(salesOrder2.AccountNumber)); // Create a user User user1 = await database.CreateUserAsync("Thomas Andersen"); // Get an existing user and permission. // This is a client side reference and does no verification against Cosmos DB. user1 = database.GetUser("Thomas Andersen"); // Verify the user exists UserProperties userProperties = await user1.ReadAsync(); //Add the read permission to the user and validate the user can //read only the container it has access to await ValidateReadPermissions( client.Endpoint.OriginalString, database.Id, container1, user1); // Insert one item in to container 2 SalesOrder salesOrder3 = new SalesOrder() { Id = "doc3", AccountNumber = "partitionKey" }; await container2.CreateItemAsync <SalesOrder>( salesOrder3, new PartitionKey(salesOrder3.AccountNumber)); // Create a new user User user2 = await database.CreateUserAsync("Robin Wakefield"); //Add the all permission to the user for a single item and validate the user can //only access the single item await ValidateAllPermissionsForItem( client.Endpoint.OriginalString, database.Id, container2, user2, salesOrder3); // Add read permission to user1 on container 2 so query has multiple results PermissionResponse permissionUser1Container2Response = await user1.CreatePermissionAsync( new PermissionProperties( id : "permissionUser1Container2", permissionMode : PermissionMode.Read, container : container2)); Permission permissionUser1Container2 = permissionUser1Container2Response; PermissionProperties user1Container2Properties = permissionUser1Container2Response; Console.WriteLine(); Console.WriteLine($"Created {permissionUser1Container2.Id} with resource URI: {user1Container2Properties.ResourceUri}"); // Get an existing permission and token permissionUser1Container2 = user1.GetPermission("permissionUser1Container2"); // Get an existing permission properties user1Container2Properties = await permissionUser1Container2.ReadAsync(); Console.WriteLine($"Read existing {permissionUser1Container2.Id} with resource URI: {user1Container2Properties.ResourceUri}"); // All user1's permissions in a List List <PermissionProperties> user1Permissions = new List <PermissionProperties>(); FeedIterator <PermissionProperties> feedIterator = user1.GetPermissionQueryIterator <PermissionProperties>(); while (feedIterator.HasMoreResults) { FeedResponse <PermissionProperties> permissions = await feedIterator.ReadNextAsync(); user1Permissions.AddRange(permissions); } }
public static async Task Testing() { var client = new CosmosClient(EndpointUri, PrimaryKey); var database = client.GetDatabase(databaseId); var container = database.GetContainer(containerId); //TODO: delete and recreate container to mimic "truncate" var t = new Team() { LongName = "EYE EM GEE", ShortName = "IMG", Class = "6A", District = 1 }; ItemResponse <Team> teamResponse = await container.CreateItemAsync <Team>(t); Console.WriteLine("Created item in database with id: {0} Operation consumed {1} RUs.\n", teamResponse.Resource.Id, teamResponse.RequestCharge); //ItemResponse<Team> andersenFamilyResponse = await container.ReadItemAsync<Team>(t.Id, new PartitionKey(t.Class)); //Console.WriteLine("Item in database with id: {0} already exists\n", andersenFamilyResponse.Resource.Id); var sqlQueryText = "SELECT * FROM c WHERE c.Class = '6A'"; Console.WriteLine("Running query: {0}\n", sqlQueryText); QueryDefinition queryDefinition = new(sqlQueryText); FeedIterator <Team> queryResultSetIterator = container.GetItemQueryIterator <Team>(queryDefinition); List <Team> teams = new(); while (queryResultSetIterator.HasMoreResults) { FeedResponse <Team> currentResultSet = await queryResultSetIterator.ReadNextAsync(); foreach (Team teem in currentResultSet) { teams.Add(teem); Console.WriteLine("\tRead {0}\n", teem); } } foreach (Team tm in teams) { Console.Write(tm.Id); } ItemResponse <Team> updateResponse = await container.ReadItemAsync <Team>("EYE EM GEE", new PartitionKey("6A")); var itemBody = updateResponse.Resource; itemBody.District = 2; // replace the item with the updated content updateResponse = await container.ReplaceItemAsync <Team>(itemBody, itemBody.Id, new PartitionKey(itemBody.Class)); Console.WriteLine("Updated Team [{0},{1}].\n \tBody is now: {2}\n", itemBody.LongName, itemBody.Id, updateResponse.Resource); // Delete an item. Note we must provide the partition key value and id of the item to delete ItemResponse <Team> wakefieldFamilyResponse = await container.DeleteItemAsync <Team>(t.Id, new PartitionKey(t.Class)); Console.WriteLine("Deleted Team [{0},{1}]\n", t.Class, t.Id); }
public async Task ItemLINQQueryWithContinuationTokenTest() { // Creating items for query. IList <ToDoActivity> itemList = await ToDoActivity.CreateRandomItems( container : this.Container, pkCount : 10, perPKItemCount : 1, randomPartitionKey : true); IList <ToDoActivity> filteredList = itemList.Where(item => item.taskNum < 100).ToList(); int filteredDocumentCount = filteredList.Count(); Console.WriteLine($"Filtered List: {JsonConvert.SerializeObject(filteredList)}."); QueryRequestOptions queryRequestOptions = new QueryRequestOptions(); queryRequestOptions.MaxConcurrency = 1; queryRequestOptions.MaxItemCount = 5; IOrderedQueryable <ToDoActivity> linqQueryable = this.Container.GetItemLinqQueryable <ToDoActivity>(requestOptions: queryRequestOptions); IQueryable <ToDoActivity> queriable = linqQueryable.Where(item => item.taskNum < 100); FeedIterator <ToDoActivity> feedIterator = queriable.ToFeedIterator(); int firstItemSet = 0; string continuationToken = null; while (feedIterator.HasMoreResults) { FeedResponse <ToDoActivity> feedResponse = await feedIterator.ReadNextAsync(); firstItemSet = feedResponse.Count(); continuationToken = feedResponse.ContinuationToken; Console.WriteLine($"First page: {JsonConvert.SerializeObject(feedResponse.Resource)}."); if (firstItemSet > 0) { break; } } linqQueryable = this.Container.GetItemLinqQueryable <ToDoActivity>( continuationToken: continuationToken, requestOptions: queryRequestOptions); queriable = linqQueryable.Where(item => item.taskNum < 100); feedIterator = queriable.ToFeedIterator(); // Test continuationToken with LINQ query generation and asynchronous feedIterator execution. int secondItemSet = 0; while (feedIterator.HasMoreResults) { FeedResponse <ToDoActivity> feedResponse = await feedIterator.ReadNextAsync(); secondItemSet += feedResponse.Count(); Console.WriteLine($"Second Async page: {JsonConvert.SerializeObject(feedResponse.Resource)}."); } Assert.AreEqual( filteredDocumentCount - firstItemSet, secondItemSet, "Failed to resume execution for async iterator."); // Test continuationToken with blocking LINQ execution linqQueryable = this.Container.GetItemLinqQueryable <ToDoActivity>( allowSynchronousQueryExecution: true, continuationToken: continuationToken, requestOptions: queryRequestOptions); List <ToDoActivity> secondSyncPage = linqQueryable.Where(item => item.taskNum < 100).ToList(); Console.WriteLine($"Second Sync page: {JsonConvert.SerializeObject(secondSyncPage)}."); int linqExecutionItemCount = secondSyncPage.Count(); Assert.AreEqual( filteredDocumentCount - firstItemSet, linqExecutionItemCount, "Failed to resume execution for sync iterator"); }
public async Task ItemLinqReadFeedTest(bool useStatelessIterator) { IList <ToDoActivity> deleteList = await ToDoActivity.CreateRandomItems(this.Container, pkCount : 3, randomPartitionKey : true); HashSet <string> itemIds = deleteList.Select(x => x.id).ToHashSet <string>(); QueryRequestOptions requestOptions = new QueryRequestOptions() { MaxItemCount = 1 }; List <ToDoActivity> itemsViaReadFeed = this.Container.GetItemLinqQueryable <ToDoActivity>( allowSynchronousQueryExecution: true, requestOptions: requestOptions).ToList(); Assert.IsTrue(itemsViaReadFeed.Count >= 3); CollectionAssert.AreEqual(deleteList.ToList(), itemsViaReadFeed); string lastContinuationToken = null; FeedIterator <ToDoActivity> feedIterator = this.Container.GetItemLinqQueryable <ToDoActivity>( requestOptions: requestOptions).ToFeedIterator(); while (feedIterator.HasMoreResults) { if (useStatelessIterator) { feedIterator = this.Container.GetItemLinqQueryable <ToDoActivity>( continuationToken: lastContinuationToken, requestOptions: requestOptions).ToFeedIterator(); } FeedResponse <ToDoActivity> responseMessage = await feedIterator.ReadNextAsync(this.cancellationToken); lastContinuationToken = responseMessage.ContinuationToken; foreach (ToDoActivity toDoActivity in responseMessage) { if (itemIds.Contains(toDoActivity.id)) { itemIds.Remove(toDoActivity.id); } } } Assert.IsNull(lastContinuationToken); Assert.AreEqual(itemIds.Count, 0); itemIds = deleteList.Select(x => x.id).ToHashSet <string>(); FeedIterator streamIterator = this.Container.GetItemLinqQueryable <ToDoActivity>( requestOptions: requestOptions).ToStreamIterator(); while (streamIterator.HasMoreResults) { if (useStatelessIterator) { streamIterator = this.Container.GetItemLinqQueryable <ToDoActivity>( continuationToken: lastContinuationToken, requestOptions: requestOptions).ToStreamIterator(); } using (ResponseMessage responseMessage = await streamIterator.ReadNextAsync(this.cancellationToken)) { lastContinuationToken = responseMessage.Headers.ContinuationToken; Collection <ToDoActivity> items = TestCommon.SerializerCore.FromStream <CosmosFeedResponseUtil <ToDoActivity> >(responseMessage.Content).Data; foreach (ToDoActivity toDoActivity in items) { if (itemIds.Contains(toDoActivity.id)) { itemIds.Remove(toDoActivity.id); } } } } Assert.IsNull(lastContinuationToken); Assert.AreEqual(itemIds.Count, 0); }
public async Task RunAsync( CTLConfig config, CosmosClient cosmosClient, ILogger logger, IMetrics metrics, string loggingContextIdentifier, CancellationToken cancellationToken) { Stopwatch stopWatch = Stopwatch.StartNew(); GaugeOptions documentGauge = new GaugeOptions { Name = "#Documents received", Context = loggingContextIdentifier }; Container container = cosmosClient.GetContainer(config.Database, config.Collection); try { while (stopWatch.Elapsed <= config.RunningTimeDurationAsTimespan) { long documentTotal = 0; string continuation = null; using FeedIterator <Dictionary <string, string> > changeFeedPull = container.GetChangeFeedIterator <Dictionary <string, string> >(ChangeFeedStartFrom.Beginning(), ChangeFeedMode.Incremental); try { while (changeFeedPull.HasMoreResults) { FeedResponse <Dictionary <string, string> > response = await changeFeedPull.ReadNextAsync(); documentTotal += response.Count; continuation = response.ContinuationToken; if (response.StatusCode == HttpStatusCode.NotModified) { break; } } metrics.Measure.Gauge.SetValue(documentGauge, documentTotal); if (config.PreCreatedDocuments > 0) { if (this.initializationResult.InsertedDocuments == documentTotal) { logger.LogInformation($"Success: The number of new documents match the number of pre-created documents: {this.initializationResult.InsertedDocuments}"); } else { logger.LogError($"The prepopulated documents and the change feed documents don't match. Preconfigured Docs = {this.initializationResult.InsertedDocuments}, Change feed Documents = {documentTotal}.{Environment.NewLine}{continuation}"); } } } catch (CosmosException ce) when(ce.StatusCode == System.Net.HttpStatusCode.TooManyRequests) { //Logging 429s is not relevant } catch (Exception ex) { metrics.Measure.Gauge.SetValue(documentGauge, documentTotal); logger.LogError(ex, "Failure while looping through change feed documents"); } } } catch (Exception ex) { logger.LogError(ex, "Failure during Change Feed Pull scenario"); } finally { stopWatch.Stop(); if (this.initializationResult.CreatedContainer) { await cosmosClient.GetContainer(config.Database, config.Collection).DeleteContainerStreamAsync(); } if (this.initializationResult.CreatedDatabase) { await cosmosClient.GetDatabase(config.Database).DeleteStreamAsync(); } } }
public async Task ItemLINQQueryTest() { //Creating items for query. IList <ToDoActivity> itemList = await ToDoActivity.CreateRandomItems(container : this.Container, pkCount : 2, perPKItemCount : 1, randomPartitionKey : true); IOrderedQueryable <ToDoActivity> linqQueryable = this.Container.GetItemLinqQueryable <ToDoActivity>(); IQueryable <ToDoActivity> queriable = linqQueryable.Where(item => item.taskNum < 100); //V3 Asynchronous query execution with LINQ query generation sql text. FeedIterator <ToDoActivity> setIterator = this.Container.GetItemQueryIterator <ToDoActivity>( queriable.ToQueryDefinition(), requestOptions: new QueryRequestOptions() { MaxConcurrency = 2 }); int resultsFetched = 0; while (setIterator.HasMoreResults) { FeedResponse <ToDoActivity> queryResponse = await setIterator.ReadNextAsync(); resultsFetched += queryResponse.Count(); // For the items returned with NonePartitionKeyValue IEnumerator <ToDoActivity> iter = queryResponse.GetEnumerator(); while (iter.MoveNext()) { ToDoActivity activity = iter.Current; Assert.AreEqual(42, activity.taskNum); } Assert.AreEqual(2, resultsFetched); } //LINQ query execution without partition key. linqQueryable = this.Container.GetItemLinqQueryable <ToDoActivity>(allowSynchronousQueryExecution: true); queriable = linqQueryable.Where(item => item.taskNum < 100); Assert.AreEqual(2, queriable.Count()); Assert.AreEqual(itemList[0].id, queriable.ToList()[0].id); Assert.AreEqual(itemList[1].id, queriable.ToList()[1].id); //LINQ query execution with wrong partition key. linqQueryable = this.Container.GetItemLinqQueryable <ToDoActivity>( allowSynchronousQueryExecution: true, requestOptions: new QueryRequestOptions() { PartitionKey = new Cosmos.PartitionKey("test") }); queriable = linqQueryable.Where(item => item.taskNum < 100); Assert.AreEqual(0, queriable.Count()); //LINQ query execution with correct partition key. linqQueryable = this.Container.GetItemLinqQueryable <ToDoActivity>( allowSynchronousQueryExecution: true, requestOptions: new QueryRequestOptions { ConsistencyLevel = Cosmos.ConsistencyLevel.Eventual, PartitionKey = new Cosmos.PartitionKey(itemList[1].pk) }); queriable = linqQueryable.Where(item => item.taskNum < 100); Assert.AreEqual(1, queriable.Count()); Assert.AreEqual(itemList[1].id, queriable.ToList()[0].id); }
internal async Task <(IReadOnlyList <CosmosCmsItem> results, int total)> List(CmsType cmsType, string?sortField, string?sortOrder, int pageSize = 20, int pageIndex = 0, string?searchQuery = null) { Container container = GetContainer(); var totalItems = await container.GetItemLinqQueryable <CosmosCmsItem>().Where(x => x.CmsType == cmsType.Value).CountAsync().ConfigureAwait(false); int totalResults = totalItems.Resource; string whereClause = string.Empty; if (!string.IsNullOrEmpty(searchQuery)) { var typeInfo = cmsConfiguration.MenuItems.Where(x => x.Key == cmsType.Value).FirstOrDefault(); if (typeInfo != null) { StringBuilder sb = new StringBuilder(); sb.Append("AND ("); foreach (var prop in typeInfo.ListViewProperties) { sb.Append($"CONTAINS(c.{prop.Key}, '{searchQuery}') OR "); } sb.Remove(sb.Length - 3, 3); sb.Append(") "); whereClause = sb.ToString(); } //Only support one page of results for now //TODO: Create count query with Where clause totalResults = pageSize; } QueryDefinition queryDefinition = new QueryDefinition($"SELECT * FROM c WHERE c.cmstype = @cmstype {whereClause}OFFSET {pageSize*pageIndex} LIMIT {pageSize}").WithParameter("@cmstype", cmsType); if (sortField != null) { sortOrder = sortOrder ?? "Asc"; queryDefinition = new QueryDefinition($"SELECT * FROM c WHERE c.cmstype = @cmstype {whereClause}ORDER BY c.{sortField} {sortOrder.ToUpperInvariant()} OFFSET {pageSize * pageIndex} LIMIT {pageSize}") .WithParameter("@cmstype", cmsType); } FeedIterator <CosmosCmsItem> queryResultSetIterator = container.GetItemQueryIterator <CosmosCmsItem>(queryDefinition); List <CosmosCmsItem> results = new List <CosmosCmsItem>(); while (queryResultSetIterator.HasMoreResults) { try { FeedResponse <CosmosCmsItem> currentResultSet = await queryResultSetIterator.ReadNextAsync().ConfigureAwait(false); foreach (CosmosCmsItem item in currentResultSet) { results.Add(item); } } catch (CosmosException) { //TODO: Handle scenario if no documents are found, first time. Not initialized yet? break; } } return(results, totalResults); }
private async Task StartDemo() { // Setup a new database string databaseName = "demoDB_" + Guid.NewGuid().ToString().Substring(0, 5); this.client = new CosmosClient(EndpointUrl, Key); this.database = await this.client.CreateDatabaseIfNotExistsAsync(databaseName); //Create a new collection within the database string containerName = "collection_" + Guid.NewGuid().ToString().Substring(0, 5); this.container = await this.database.CreateContainerIfNotExistsAsync(containerName, "/LastName"); // Prepare data for the new collection Person person1 = new Person { Id = "Person.1", FirstName = "Santiago", LastName = "Fernandez", Devices = new Device[] { new Device { OperatingSystem = "iOS", CameraMegaPixels = 7, Ram = 16, Usage = "Personal" }, new Device { OperatingSystem = "Android", CameraMegaPixels = 12, Ram = 64, Usage = "Work" } }, Gender = "Male", Address = new Address { City = "Seville", Country = "Spain", PostalCode = "28973", Street = "Diagonal", State = "Andalucia" }, IsRegistered = true }; await this.CreateDocumentIfNotExistsAsync(databaseName, containerName, person1); Person person2 = new Person { Id = "Person.2", FirstName = "Santiago", LastName = "Perez", Devices = new Device[] { new Device { OperatingSystem = "iOS", CameraMegaPixels = 7, Ram = 16, Usage = "Work" }, new Device { OperatingSystem = "Android", CameraMegaPixels = 12, Ram = 32, Usage = "Personal" } }, Gender = "Female", Address = new Address { City = "Barcelona", Country = "Spain", PostalCode = "28973", Street = "Diagonal", State = "Barcelona" }, IsRegistered = true }; await this.CreateDocumentIfNotExistsAsync(databaseName, containerName, person2); // Make queries on the collection IQueryable <Person> queryablePeople = this.container.GetItemLinqQueryable <Person>(true) .Where(p => p.Gender == "Male"); foreach (var person in queryablePeople) { Console.Write($"\t Person: {person}"); } // Make query using SQL var sqlQuery = "SELECT * FROM Person WHERE Person.Gender = 'Female'"; QueryDefinition queryDefinition = new QueryDefinition(sqlQuery); FeedIterator <Person> peopleResultSetIterator = this.container.GetItemQueryIterator <Person>(queryDefinition); while (peopleResultSetIterator.HasMoreResults) { FeedResponse <Person> currentResultSet = await peopleResultSetIterator.ReadNextAsync(); foreach (var p in currentResultSet) { Console.WriteLine($"\tPerson: {p}"); } } Console.WriteLine("Press any key to continue before updating..."); Console.ReadKey(); person2.FirstName = "Esteban"; person2.Gender = "Male"; await this.container.UpsertItemAsync(person2); //Delete a single document PartitionKey partitionKey = new PartitionKey(person1.LastName); await this.container.DeleteItemAsync <Person>(person1.Id, partitionKey); await this.database.DeleteAsync(); }
public async Task ValidateQueryNotFoundResponse() { Database db = await CosmosNotFoundTests.client.CreateDatabaseAsync("NotFoundTest" + Guid.NewGuid().ToString()); Container container = await db.CreateContainerAsync("NotFoundTest" + Guid.NewGuid().ToString(), "/pk", 500); dynamic randomItem = new { id = "test", pk = "testpk" }; await container.CreateItemAsync(randomItem); await container.DeleteContainerAsync(); { // Querying after delete should be a gone exception even after the retry. FeedIterator crossPartitionQueryIterator = container.GetItemQueryStreamIterator( "select * from t where true", requestOptions: new QueryRequestOptions() { MaxConcurrency = 2 }); await this.VerifyQueryNotFoundResponse(crossPartitionQueryIterator); } { // Also try with partition key. FeedIterator queryIterator = container.GetItemQueryStreamIterator( "select * from t where true", requestOptions: new QueryRequestOptions() { MaxConcurrency = 1, PartitionKey = new Cosmos.PartitionKey("testpk"), }); await this.VerifyQueryNotFoundResponse(queryIterator); } { // Recreate the collection with the same name on a different client. CosmosClient newClient = TestCommon.CreateCosmosClient(); Database db2 = newClient.GetDatabase(db.Id); Container container2 = await db2.CreateContainerAsync( id : container.Id, partitionKeyPath : "/pk", throughput : 500); await container2.CreateItemAsync(randomItem); FeedIterator queryIterator = container.GetItemQueryStreamIterator( "select * from t where true", requestOptions: new QueryRequestOptions() { MaxConcurrency = 2 }); ResponseMessage response = await queryIterator.ReadNextAsync(); Assert.IsNotNull(response); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); } await db.DeleteAsync(); }
public async Task <IEnumerable <T> > QueryAsync <T>(QueryDefinition queryDefinition, QueryRequestOptions queryRequestOptions) { var methodIdentifier = $"{nameof(CosmosService<U>)}.{nameof(CosmosService<U>.QueryAsync)}"; var stopwatchService = _serviceProvider.GetRequiredService <IStopwatchService>(); var telemetry = new TelemetryData { Name = methodIdentifier, DateTime = _dateTimeService.GetDateTimeUTC(), TelemetryType = TelemetryType.NoSQL }; try { stopwatchService.Start(); var items = new List <T>(); using (FeedIterator <T> feedIterator = _cosmosContainer.GetItemQueryIterator <T>(queryDefinition, null, queryRequestOptions)) { while (feedIterator.HasMoreResults) { var response = await feedIterator.ReadNextAsync(); foreach (var item in response) { items.Add(item); } } }; stopwatchService.Stop(); telemetry.ElapsedMilliseconds = (int)stopwatchService.ElapsedMilliseconds; telemetry.TelemetryState = TelemetryState.Successful; _logger.LogInformationRedacted ( methodIdentifier, new Dictionary <string, object> { { nameof(queryDefinition), queryDefinition }, { nameof(queryRequestOptions), queryRequestOptions }, { nameof(items), items }, { nameof(stopwatchService.ElapsedMilliseconds), telemetry.ElapsedMilliseconds } } ); return(items); } catch (Exception exception) { stopwatchService.Stop(); telemetry.ElapsedMilliseconds = (int)stopwatchService.ElapsedMilliseconds; telemetry.TelemetryState = TelemetryState.Failed; _logger.LogErrorRedacted ( $"Unhandled exception {methodIdentifier}", exception, new Dictionary <string, object> { { nameof(queryDefinition), queryDefinition }, { nameof(queryRequestOptions), queryRequestOptions }, { nameof(stopwatchService.ElapsedMilliseconds), telemetry.ElapsedMilliseconds } } ); throw; } finally { _telemetryService.Insert(telemetry); } }
public void VerifySynchronizationContextDoesNotLock() { string databaseId = Guid.NewGuid().ToString(); SynchronizationContext prevContext = SynchronizationContext.Current; try { TestSynchronizationContext syncContext = new TestSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(syncContext); syncContext.Post(_ => { using (CosmosClient client = TestCommon.CreateCosmosClient()) { Cosmos.Database database = client.CreateDatabaseAsync(databaseId).GetAwaiter().GetResult(); database = client.CreateDatabaseIfNotExistsAsync(databaseId).GetAwaiter().GetResult(); database.ReadStreamAsync().ConfigureAwait(false).GetAwaiter().GetResult(); database.ReadAsync().ConfigureAwait(false).GetAwaiter().GetResult(); QueryDefinition databaseQuery = new QueryDefinition("select * from T where T.id = @id").WithParameter("@id", databaseId); FeedIterator <DatabaseProperties> databaseIterator = client.GetDatabaseQueryIterator <DatabaseProperties>(databaseQuery); while (databaseIterator.HasMoreResults) { databaseIterator.ReadNextAsync().GetAwaiter().GetResult(); } Container container = database.CreateContainerAsync(Guid.NewGuid().ToString(), "/pk").GetAwaiter().GetResult(); container = database.CreateContainerIfNotExistsAsync(container.Id, "/pk").GetAwaiter().GetResult(); ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity(); ItemResponse <ToDoActivity> response = container.CreateItemAsync <ToDoActivity>(item: testItem).ConfigureAwait(false).GetAwaiter().GetResult(); Assert.IsNotNull(response); string diagnostics = response.Diagnostics.ToString(); Assert.IsTrue(diagnostics.Contains("Synchronization Context")); using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); try { ToDoActivity tempItem = ToDoActivity.CreateRandomToDoActivity(); CancellationToken cancellationToken = cancellationTokenSource.Token; cancellationTokenSource.Cancel(); container.CreateItemAsync <ToDoActivity>(item: tempItem, cancellationToken: cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(); Assert.Fail("Should have thrown a cancellation token"); } catch (CosmosOperationCanceledException oe) { string exception = oe.ToString(); Assert.IsTrue(exception.Contains("Synchronization Context")); } // Test read feed container.GetItemLinqQueryable <ToDoActivity>( allowSynchronousQueryExecution: true, requestOptions: new QueryRequestOptions() { }).ToList(); FeedIterator feedIterator = container .GetItemLinqQueryable <ToDoActivity>() .ToStreamIterator(); while (feedIterator.HasMoreResults) { feedIterator.ReadNextAsync().GetAwaiter().GetResult(); } FeedIterator <ToDoActivity> feedIteratorTyped = container.GetItemLinqQueryable <ToDoActivity>() .ToFeedIterator <ToDoActivity>(); while (feedIteratorTyped.HasMoreResults) { feedIteratorTyped.ReadNextAsync().GetAwaiter().GetResult(); } // Test query container.GetItemLinqQueryable <ToDoActivity>( allowSynchronousQueryExecution: true, requestOptions: new QueryRequestOptions() { }).Where(item => item.id != "").ToList(); FeedIterator queryIterator = container.GetItemLinqQueryable <ToDoActivity>() .Where(item => item.id != "").ToStreamIterator(); while (queryIterator.HasMoreResults) { queryIterator.ReadNextAsync().GetAwaiter().GetResult(); } FeedIterator <ToDoActivity> queryIteratorTyped = container.GetItemLinqQueryable <ToDoActivity>() .Where(item => item.id != "").ToFeedIterator <ToDoActivity>(); while (queryIteratorTyped.HasMoreResults) { queryIteratorTyped.ReadNextAsync().GetAwaiter().GetResult(); } double costAsync = container.GetItemLinqQueryable <ToDoActivity>() .Select(x => x.cost).SumAsync().GetAwaiter().GetResult(); double cost = container.GetItemLinqQueryable <ToDoActivity>( allowSynchronousQueryExecution: true).Select(x => x.cost).Sum(); ItemResponse <ToDoActivity> deleteResponse = container.DeleteItemAsync <ToDoActivity>(partitionKey: new Cosmos.PartitionKey(testItem.pk), id: testItem.id).ConfigureAwait(false).GetAwaiter().GetResult(); Assert.IsNotNull(deleteResponse); } }, state: null); } finally { SynchronizationContext.SetSynchronizationContext(prevContext); using (CosmosClient client = TestCommon.CreateCosmosClient()) { client.GetDatabase(databaseId).DeleteAsync().GetAwaiter().GetResult(); } } }
public async Task ChangeFeedIteratorCore_PartitionKey_OfT_ReadAll() { int totalCount = 0; int firstRunTotal = 25; int batchSize = 25; string pkToRead = "pkToRead"; string otherPK = "otherPK"; for (int i = 0; i < batchSize; i++) { await this.Container.CreateItemAsync(this.CreateRandomToDoActivity(pkToRead)); } for (int i = 0; i < batchSize; i++) { await this.Container.CreateItemAsync(this.CreateRandomToDoActivity(otherPK)); } ContainerInternal itemsCore = this.Container; FeedIterator <ToDoActivity> feedIterator = itemsCore.GetChangeFeedIterator <ToDoActivity>( ChangeFeedStartFrom.Beginning(new FeedRangePartitionKey(new PartitionKey(pkToRead)))); string continuation = null; while (feedIterator.HasMoreResults) { FeedResponse <ToDoActivity> feedResponse = await feedIterator.ReadNextAsync(this.cancellationToken); totalCount += feedResponse.Count; foreach (ToDoActivity toDoActivity in feedResponse) { Assert.AreEqual(pkToRead, toDoActivity.status); } continuation = feedResponse.ContinuationToken; } Assert.AreEqual(firstRunTotal, totalCount); int expectedFinalCount = 50; // Insert another batch of 25 and use the last FeedToken from the first cycle for (int i = 0; i < batchSize; i++) { await this.Container.CreateItemAsync(this.CreateRandomToDoActivity(pkToRead)); } FeedIterator <ToDoActivity> setIteratorNew = itemsCore.GetChangeFeedIterator <ToDoActivity>( ChangeFeedStartFrom.ContinuationToken(continuation)); while (setIteratorNew.HasMoreResults) { FeedResponse <ToDoActivity> feedResponse = await setIteratorNew.ReadNextAsync(this.cancellationToken); totalCount += feedResponse.Count; foreach (ToDoActivity toDoActivity in feedResponse) { Assert.AreEqual(pkToRead, toDoActivity.status); } } Assert.AreEqual(expectedFinalCount, totalCount); }
public async Task TestQueryWithPartitionKeyAsync() { string[] inputDocs = new[] { @"{""id"":""documentId1"",""key"":""A"",""prop"":3,""shortArray"":[{""a"":5}]}", @"{""id"":""documentId2"",""key"":""A"",""prop"":2,""shortArray"":[{""a"":6}]}", @"{""id"":""documentId3"",""key"":""A"",""prop"":1,""shortArray"":[{""a"":7}]}", @"{""id"":""documentId4"",""key"":5,""prop"":3,""shortArray"":[{""a"":5}]}", @"{""id"":""documentId5"",""key"":5,""prop"":2,""shortArray"":[{""a"":6}]}", @"{""id"":""documentId6"",""key"":5,""prop"":1,""shortArray"":[{""a"":7}]}", @"{""id"":""documentId10"",""prop"":3,""shortArray"":[{""a"":5}]}", @"{""id"":""documentId11"",""prop"":2,""shortArray"":[{""a"":6}]}", @"{""id"":""documentId12"",""prop"":1,""shortArray"":[{""a"":7}]}", }; await this.CreateIngestQueryDeleteAsync( ConnectionModes.Direct | ConnectionModes.Gateway, CollectionTypes.SinglePartition | CollectionTypes.MultiPartition, inputDocs, ImplementationAsync, "/key"); async Task ImplementationAsync(Container container, IReadOnlyList <CosmosObject> documents) { Assert.AreEqual(0, (await QueryTestsBase.RunQueryAsync( container, @"SELECT * FROM Root r WHERE false", new QueryRequestOptions() { MaxConcurrency = 1, })).Count); object[] keys = new object[] { "A", 5, Undefined.Value }; for (int i = 0; i < keys.Length; ++i) { List <string> expected = documents .Skip(i * 3) .Take(3) .Select(doc => ((CosmosString)doc["id"]).Value) .ToList(); string expectedResult = string.Join(",", expected); // Order-by List <string> expectedCopy = new List <string>(expected); expectedCopy.Reverse(); string expectedOrderByResult = string.Join(",", expectedCopy); List <(string, string)> queries = new List <(string, string)>() { ($@"SELECT * FROM Root r WHERE r.id IN (""{expected[0]}"", ""{expected[1]}"", ""{expected[2]}"")", expectedResult), (@"SELECT * FROM Root r WHERE r.prop BETWEEN 1 AND 3", expectedResult), (@"SELECT VALUE r FROM Root r JOIN c IN r.shortArray WHERE c.a BETWEEN 5 and 7", expectedResult), ($@"SELECT TOP 10 * FROM Root r WHERE r.id IN (""{expected[0]}"", ""{expected[1]}"", ""{expected[2]}"")", expectedResult), (@"SELECT TOP 10 * FROM Root r WHERE r.prop BETWEEN 1 AND 3", expectedResult), (@"SELECT TOP 10 VALUE r FROM Root r JOIN c IN r.shortArray WHERE c.a BETWEEN 5 and 7", expectedResult), ($@"SELECT * FROM Root r WHERE r.id IN (""{expected[0]}"", ""{expected[1]}"", ""{expected[2]}"") ORDER BY r.prop", expectedOrderByResult), (@"SELECT * FROM Root r WHERE r.prop BETWEEN 1 AND 3 ORDER BY r.prop", expectedOrderByResult), (@"SELECT VALUE r FROM Root r JOIN c IN r.shortArray WHERE c.a BETWEEN 5 and 7 ORDER BY r.prop", expectedOrderByResult), }; if (i < keys.Length - 1) { string key; if (keys[i] is string) { key = "'" + keys[i].ToString() + "'"; } else { key = keys[i].ToString(); } queries.Add((string.Format(CultureInfo.InvariantCulture, @"SELECT * FROM Root r WHERE r.key = {0} ORDER BY r.prop", key), expectedOrderByResult)); } foreach ((string, string)queryAndExpectedResult in queries) { FeedIterator <Document> resultSetIterator = container.GetItemQueryIterator <Document>( queryText: queryAndExpectedResult.Item1, requestOptions: new QueryRequestOptions() { MaxItemCount = 1, PartitionKey = new Cosmos.PartitionKey(keys[i]), }); List <Document> result = new List <Document>(); while (resultSetIterator.HasMoreResults) { result.AddRange(await resultSetIterator.ReadNextAsync()); } string resultDocIds = string.Join(",", result.Select(doc => doc.Id)); Assert.AreEqual(queryAndExpectedResult.Item2, resultDocIds); } } } }
public async Task TestJsonSerializerSettings(bool useGateway) { CosmosClient cosmosClient = TestCommon.CreateCosmosClient((cosmosClientBuilder) => { if (useGateway) { cosmosClientBuilder.WithCustomSerializer(new CustomJsonSerializer(CustomSerializationTests.GetSerializerWithCustomConverterAndBinder())).WithConnectionModeGateway(); } else { cosmosClientBuilder.WithCustomSerializer(new CustomJsonSerializer(CustomSerializationTests.GetSerializerWithCustomConverterAndBinder())).WithConnectionModeDirect(); } }); Container container = cosmosClient.GetContainer(this.databaseName, this.partitionedCollectionName); Random rnd = new Random(); byte[] bytes = new byte[100]; rnd.NextBytes(bytes); TestDocument testDocument = new TestDocument(new KerberosTicketHashKey(bytes)); //create and read ItemResponse <TestDocument> createResponse = await container.CreateItemAsync <TestDocument>(testDocument); ItemResponse <TestDocument> readResponse = await container.ReadItemAsync <TestDocument>(testDocument.Id, new Cosmos.PartitionKey(testDocument.Name)); this.AssertEqual(testDocument, readResponse.Resource); this.AssertEqual(testDocument, createResponse.Resource); // upsert ItemResponse <TestDocument> upsertResponse = await container.UpsertItemAsync <TestDocument>(testDocument); readResponse = await container.ReadItemAsync <TestDocument>(testDocument.Id, new Cosmos.PartitionKey(testDocument.Name)); this.AssertEqual(testDocument, readResponse.Resource); this.AssertEqual(testDocument, upsertResponse.Resource); // replace ItemResponse <TestDocument> replacedResponse = await container.ReplaceItemAsync <TestDocument>(testDocument, testDocument.Id); readResponse = await container.ReadItemAsync <TestDocument>(testDocument.Id, new Cosmos.PartitionKey(testDocument.Name)); this.AssertEqual(testDocument, readResponse.Resource); this.AssertEqual(testDocument, replacedResponse.Resource); QueryDefinition sql = new QueryDefinition("select * from r"); FeedIterator <TestDocument> feedIterator = container.GetItemQueryIterator <TestDocument>(queryDefinition: sql, requestOptions: new QueryRequestOptions() { MaxItemCount = 1 }); List <TestDocument> allDocuments = new List <TestDocument>(); while (feedIterator.HasMoreResults) { allDocuments.AddRange(await feedIterator.ReadNextAsync()); } this.AssertEqual(testDocument, allDocuments.First()); //Will add LINQ test once it is available with new V3 OM // // LINQ Lambda // var query1 = client.CreateDocumentQuery<TestDocument>(partitionedCollectionUri, options) // .Where(_ => _.Id.CompareTo(String.Empty) > 0) // .Select(_ => _.Id); // string query1Str = query1.ToString(); // var result = query1.ToList(); // Assert.AreEqual(1, result.Count); // Assert.AreEqual(testDocument.Id, result[0]); // // LINQ Query // var query2 = // from f in client.CreateDocumentQuery<TestDocument>(partitionedCollectionUri, options) // where f.Id.CompareTo(String.Empty) > 0 // select f.Id; // string query2Str = query2.ToString(); // var result2 = query2.ToList(); // Assert.AreEqual(1, result2.Count); // Assert.AreEqual(testDocument.Id, result2[0]); }
public async Task TestQueryCrossPartitionWithLargeNumberOfKeysAsync() { int numberOfDocuments = 1000; string partitionKey = "key"; HashSet <int> expectedPartitionKeyValues = new HashSet <int>(); List <string> documents = new List <string>(); for (int i = 0; i < numberOfDocuments; i++) { Document doc = new Document(); doc.SetPropertyValue(partitionKey, i); documents.Add(doc.ToString()); expectedPartitionKeyValues.Add(i); } Assert.AreEqual(numberOfDocuments, expectedPartitionKeyValues.Count); QueryCrossPartitionWithLargeNumberOfKeysArgs args = new QueryCrossPartitionWithLargeNumberOfKeysArgs() { NumberOfDocuments = numberOfDocuments, PartitionKey = partitionKey, ExpectedPartitionKeyValues = expectedPartitionKeyValues, }; await this.CreateIngestQueryDeleteAsync <QueryCrossPartitionWithLargeNumberOfKeysArgs>( ConnectionModes.Direct | ConnectionModes.Gateway, CollectionTypes.SinglePartition | CollectionTypes.MultiPartition, documents, ImplementationAsync, args, "/" + partitionKey); async Task ImplementationAsync( Container container, IReadOnlyList <CosmosObject> inputDocs, QueryCrossPartitionWithLargeNumberOfKeysArgs testArgs) { QueryDefinition query = new QueryDefinition( $"SELECT VALUE r.{args.PartitionKey} FROM r WHERE ARRAY_CONTAINS(@keys, r.{testArgs.PartitionKey})").WithParameter("@keys", testArgs.ExpectedPartitionKeyValues); HashSet <int> actualPartitionKeyValues = new HashSet <int>(); FeedIterator <int> documentQuery = container.GetItemQueryIterator <int>( queryDefinition: query, requestOptions: new QueryRequestOptions() { MaxItemCount = -1, MaxConcurrency = 100 }); while (documentQuery.HasMoreResults) { FeedResponse <int> response = await documentQuery.ReadNextAsync(); foreach (int item in response) { actualPartitionKeyValues.Add(item); } } Assert.IsTrue(actualPartitionKeyValues.SetEquals(args.ExpectedPartitionKeyValues)); } }
public async static Task <QueryItemResult <T> > GetAllResultsAsync <T>(FeedIterator <T> query) { return(await GetAllResultsAsync(query, d => d)); }
public async Task TestQueryWithCustomJsonSerializer() { int toStreamCount = 0; int fromStreamCount = 0; CosmosSerializer serializer = new CosmosSerializerHelper(new Newtonsoft.Json.JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }, (item) => fromStreamCount++, (item) => toStreamCount++); CosmosClient client = TestCommon.CreateCosmosClient(builder => builder.WithCustomSerializer(serializer)); Database database = await client.CreateDatabaseAsync(Guid.NewGuid().ToString()); try { Container container = await database.CreateContainerAsync(Guid.NewGuid().ToString(), "/id"); Assert.AreEqual(0, toStreamCount); Assert.AreEqual(0, fromStreamCount); double cost = 9001.42; for (int i = 0; i < 5; i++) { ToDoActivity toDoActivity = new ToDoActivity() { id = "TestId" + i, cost = cost }; await container.CreateItemAsync <ToDoActivity>(toDoActivity, new PartitionKey(toDoActivity.id)); } Assert.AreEqual(5, toStreamCount); Assert.AreEqual(5, fromStreamCount); toStreamCount = 0; fromStreamCount = 0; QueryDefinition query = new QueryDefinition("select * from T where T.id != @id"). WithParameter("@id", Guid.NewGuid()); FeedIterator <DatabaseProperties> feedIterator = client.GetDatabaseQueryIterator <DatabaseProperties>( query); List <DatabaseProperties> databases = new List <DatabaseProperties>(); while (feedIterator.HasMoreResults) { databases.AddRange(await feedIterator.ReadNextAsync()); } Assert.AreEqual(1, toStreamCount, "parameter should use custom serializer"); Assert.AreEqual(0, fromStreamCount); toStreamCount = 0; fromStreamCount = 0; FeedIterator <ToDoActivity> itemIterator = container.GetItemQueryIterator <ToDoActivity>( query); List <ToDoActivity> items = new List <ToDoActivity>(); while (itemIterator.HasMoreResults) { items.AddRange(await itemIterator.ReadNextAsync()); } Assert.AreEqual(1, toStreamCount); Assert.AreEqual(5, fromStreamCount); toStreamCount = 0; fromStreamCount = 0; // Verify that the custom serializer is actually being used via stream FeedIterator itemStreamIterator = container.GetItemQueryStreamIterator( query); while (itemStreamIterator.HasMoreResults) { ResponseMessage response = await itemStreamIterator.ReadNextAsync(); using (StreamReader reader = new StreamReader(response.Content)) { string content = await reader.ReadToEndAsync(); Assert.IsTrue(content.Contains("9001.42")); Assert.IsFalse(content.Contains("description"), "Description should be ignored and not in the JSON"); } } Assert.AreEqual(1, toStreamCount); Assert.AreEqual(0, fromStreamCount); } finally { if (database != null) { using (await database.DeleteStreamAsync()) { } } } }
public async Task StandByFeedIterator() { int totalCount = 0; string lastcontinuation = string.Empty; int firstRunTotal = 25; int batchSize = 25; Documents.Routing.Range <string> previousRange = null; Documents.Routing.Range <string> currentRange = null; int pkRangesCount = (await this.Container.ClientContext.DocumentClient.ReadPartitionKeyRangeFeedAsync(this.Container.LinkUri)).Count; int visitedPkRanges = 0; await this.CreateRandomItems(batchSize, randomPartitionKey : true); ContainerCore itemsCore = (ContainerCore)this.Container; FeedIterator feedIterator = itemsCore.GetStandByFeedIterator(requestOptions: new ChangeFeedRequestOptions() { StartTime = DateTime.MinValue }); while (feedIterator.HasMoreResults) { using (ResponseMessage responseMessage = await feedIterator.ReadNextAsync(this.cancellationToken)) { lastcontinuation = responseMessage.Headers.ContinuationToken; List <CompositeContinuationToken> deserializedToken = JsonConvert.DeserializeObject <List <CompositeContinuationToken> >(lastcontinuation); currentRange = deserializedToken[0].Range; Assert.AreEqual(pkRangesCount, deserializedToken.Count); if (responseMessage.IsSuccessStatusCode) { Collection <ToDoActivity> response = TestCommon.Serializer.FromStream <CosmosFeedResponseUtil <ToDoActivity> >(responseMessage.Content).Data; totalCount += response.Count; } if (!currentRange.Equals(previousRange)) { visitedPkRanges++; } if (visitedPkRanges == pkRangesCount && responseMessage.StatusCode == System.Net.HttpStatusCode.NotModified) { break; } previousRange = currentRange; } } Assert.AreEqual(firstRunTotal, totalCount); int expectedFinalCount = 50; previousRange = null; currentRange = null; visitedPkRanges = 0; // Insert another batch of 25 and use the last continuation token from the first cycle await this.CreateRandomItems(batchSize, randomPartitionKey : true); FeedIterator setIteratorNew = itemsCore.GetStandByFeedIterator(lastcontinuation); while (setIteratorNew.HasMoreResults) { using (ResponseMessage responseMessage = await setIteratorNew.ReadNextAsync(this.cancellationToken)) { lastcontinuation = responseMessage.Headers.ContinuationToken; currentRange = JsonConvert.DeserializeObject <List <CompositeContinuationToken> >(lastcontinuation)[0].Range; if (responseMessage.IsSuccessStatusCode) { Collection <ToDoActivity> response = TestCommon.Serializer.FromStream <CosmosFeedResponseUtil <ToDoActivity> >(responseMessage.Content).Data; totalCount += response.Count; } if (!currentRange.Equals(previousRange)) { visitedPkRanges++; } if (visitedPkRanges == pkRangesCount && responseMessage.StatusCode == System.Net.HttpStatusCode.NotModified) { break; } previousRange = currentRange; } } Assert.AreEqual(expectedFinalCount, totalCount); }
public async Task QueryRequestRateTest(bool directMode) { string firstItemIdAndPk = "BasicQueryItem" + Guid.NewGuid(); // Prevent the test from changing the static client { CosmosClient client = directMode ? DirectCosmosClient : GatewayCosmosClient; Container container = client.GetContainer(DatabaseId, ContainerId); List <string> createdIds = new List <string>() { firstItemIdAndPk, "BasicQueryItem2" + Guid.NewGuid(), "BasicQueryItem3" + Guid.NewGuid() }; foreach (string id in createdIds) { dynamic item = new { id = id, pk = id, }; await container.CreateItemAsync <dynamic>(item : item); } } CosmosClient clientWithThrottle; if (directMode) { clientWithThrottle = TestCommon.CreateCosmosClient(); } else { clientWithThrottle = TestCommon.CreateCosmosClient((builder) => builder.WithConnectionModeGateway()); } Container containerWithThrottle = clientWithThrottle.GetContainer(DatabaseId, ContainerId); // Do a read to warm up all the caches to prevent them from getting the throttle errors using (await containerWithThrottle.ReadItemStreamAsync(firstItemIdAndPk, new PartitionKey(firstItemIdAndPk))) { } Documents.IStoreModel storeModel = clientWithThrottle.ClientContext.DocumentClient.StoreModel; Mock <Documents.IStoreModel> mockStore = new Mock <Documents.IStoreModel>(); clientWithThrottle.ClientContext.DocumentClient.StoreModel = mockStore.Object; // Cause 429 after the first call int callCount = 0; string activityId = null; string errorMessage = "QueryRequestRateTest Resource Not Found"; mockStore.Setup(x => x.ProcessMessageAsync(It.IsAny <Documents.DocumentServiceRequest>(), It.IsAny <CancellationToken>())) .Returns <Documents.DocumentServiceRequest, CancellationToken>((dsr, token) => { callCount++; if (callCount > 1) { INameValueCollection headers = new StoreRequestNameValueCollection(); headers.Add(Documents.HttpConstants.HttpHeaders.RetryAfterInMilliseconds, "42"); activityId = Guid.NewGuid().ToString(); headers.Add(Documents.HttpConstants.HttpHeaders.ActivityId, activityId); Documents.DocumentServiceResponse response = new Documents.DocumentServiceResponse( body: TestCommon.GenerateStreamFromString(@"{""Errors"":[""" + errorMessage + @"""]}"), headers: headers, statusCode: (HttpStatusCode)429, clientSideRequestStatistics: dsr.RequestContext.ClientRequestStatistics); return(Task.FromResult(response)); } return(storeModel.ProcessMessageAsync(dsr, token)); }); List <dynamic> results = new List <dynamic>(); try { using (FeedIterator <dynamic> feedIterator = containerWithThrottle.GetItemQueryIterator <dynamic>( "select * from T where STARTSWITH(T.id, \"BasicQueryItem\")", requestOptions: new QueryRequestOptions() { MaxItemCount = 1, MaxConcurrency = 1 })) { while (feedIterator.HasMoreResults) { FeedResponse <dynamic> response = await feedIterator.ReadNextAsync(); Assert.IsTrue(response.Count <= 1); Assert.IsTrue(response.Resource.Count() <= 1); results.AddRange(response); } } Assert.Fail("Should throw 429 exception after the first page."); } catch (CosmosException ce) { Assert.IsTrue(ce.RetryAfter.HasValue); Assert.AreEqual(42, ce.RetryAfter.Value.TotalMilliseconds); Assert.AreEqual(activityId, ce.ActivityId); Assert.IsTrue(ce.Message.Contains(errorMessage)); } callCount = 0; FeedIterator streamIterator = containerWithThrottle.GetItemQueryStreamIterator( "select * from T where STARTSWITH(T.id, \"BasicQueryItem\")", requestOptions: new QueryRequestOptions() { MaxItemCount = 1, MaxConcurrency = 1 }); // First request should be a success using (ResponseMessage response = await streamIterator.ReadNextAsync()) { response.EnsureSuccessStatusCode(); Assert.IsNotNull(response.Content); } // Second page should be a failure using (ResponseMessage response = await streamIterator.ReadNextAsync()) { Assert.AreEqual(429, (int)response.StatusCode); Assert.AreEqual("42", response.Headers.RetryAfterLiteral); Assert.AreEqual(activityId, response.Headers.ActivityId); Assert.IsNotNull(response.Trace); Assert.IsTrue(response.ErrorMessage.Contains(errorMessage)); } }
public async Task ItemStreamContractVerifier() { string PartitionKey = "/status"; Container container = await this.database.CreateContainerAsync( new ContainerProperties(id : Guid.NewGuid().ToString(), partitionKeyPath : PartitionKey), cancellationToken : this.cancellationToken); int totalCount = 4; Dictionary <string, ToDoActivity> toDoActivities = new Dictionary <string, ToDoActivity>(); // Create 3 constant items; for (int i = 0; i < totalCount; i++) { ToDoActivity toDoActivity = new ToDoActivity() { id = "toDoActivity" + i, status = "InProgress", cost = 9000 + i, description = "Constant to do activity", taskNum = i }; toDoActivities.Add(toDoActivity.id, toDoActivity); await container.CreateItemAsync <ToDoActivity>(toDoActivity); } List <FeedIterator> FeedIterators = new List <FeedIterator>(); // The stream contract should return the same contract as read feed. // { // "_rid": "containerRid", // "Documents": [{ // "id": "03230", // "_rid": "qHVdAImeKAQBAAAAAAAAAA==", // "_self": "dbs\/qHVdAA==\/colls\/qHVdAImeKAQ=\/docs\/qHVdAImeKAQBAAAAAAAAAA==\/", // "_etag": "\"410000b0-0000-0000-0000-597916b00000\"", // "_attachments": "attachments\/", // "_ts": 1501107886 // }], // "_count": 1 // } FeedIterator setIterator = container.GetItemQueryStreamIterator(); FeedIterators.Add(setIterator); QueryRequestOptions options = new QueryRequestOptions() { MaxItemCount = 4, MaxConcurrency = 1, }; FeedIterator queryIterator = container.GetItemQueryStreamIterator( queryText: @"select * from t where t.id != """" ", requestOptions: options); FeedIterators.Add(queryIterator); foreach (FeedIterator iterator in FeedIterators) { int count = 0; while (iterator.HasMoreResults) { ResponseMessage response = await iterator.ReadNextAsync(this.cancellationToken); response.EnsureSuccessStatusCode(); using (StreamReader sr = new StreamReader(response.Content)) { string jsonString = await sr.ReadToEndAsync(); Assert.IsNotNull(jsonString); JObject jObject = JsonConvert.DeserializeObject <JObject>(jsonString); Assert.IsNotNull(jObject["Documents"]); Assert.IsNotNull(jObject["_rid"]); Assert.IsNotNull(jObject["_count"]); Assert.IsTrue(jObject["_count"].ToObject <int>() >= 0); foreach (JObject item in jObject["Documents"]) { count++; Assert.IsNotNull(item["id"]); ToDoActivity createdItem = toDoActivities[item["id"].ToString()]; Assert.AreEqual(createdItem.taskNum, item["taskNum"].ToObject <int>()); Assert.AreEqual(createdItem.cost, item["cost"].ToObject <double>()); Assert.AreEqual(createdItem.description, item["description"].ToString()); Assert.AreEqual(createdItem.status, item["status"].ToString()); Assert.IsNotNull(item["_rid"]); Assert.IsNotNull(item["_self"]); Assert.IsNotNull(item["_etag"]); Assert.IsNotNull(item["_attachments"]); Assert.IsNotNull(item["_ts"]); } } } Assert.AreEqual(totalCount, count); } }
public async Task ItemTest(bool directMode) { CosmosClient client = directMode ? DirectCosmosClient : GatewayCosmosClient; Database database = client.GetDatabase(DatabaseId); Container container = await database.CreateContainerAsync(Guid.NewGuid().ToString(), "/pk"); List <string> createdIds = new List <string>() { "BasicQueryItem", "BasicQueryItem2", "BasicQueryItem3" }; List <dynamic> queryResults = await this.ToListAsync( container.GetItemQueryStreamIterator, container.GetItemQueryIterator <dynamic>, "select * from T where STARTSWITH(T.id, \"basicQueryItem\", true)", CosmosBasicQueryTests.RequestOptions); if (queryResults.Count < 3) { foreach (string id in createdIds) { dynamic item = new { id = id, pk = id, }; ItemResponse <dynamic> createResponse = await container.CreateItemAsync <dynamic>(item : item); } queryResults = await this.ToListAsync( container.GetItemQueryStreamIterator, container.GetItemQueryIterator <dynamic>, "select * from T where Contains(T.id, \"basicqueryitem\", true)", CosmosBasicQueryTests.RequestOptions); } List <string> ids = queryResults.Select(x => (string)x.id).ToList(); CollectionAssert.AreEquivalent(createdIds, ids); //Read All List <dynamic> results = await this.ToListAsync( container.GetItemQueryStreamIterator, container.GetItemQueryIterator <dynamic>, null, CosmosBasicQueryTests.RequestOptions); ids = results.Select(x => (string)x.id).ToList(); CollectionAssert.IsSubsetOf(createdIds, ids); //Read All with partition key results = await this.ToListAsync( container.GetItemQueryStreamIterator, container.GetItemQueryIterator <dynamic>, null, new QueryRequestOptions() { MaxItemCount = 1, PartitionKey = new PartitionKey("BasicQueryItem") }); Assert.AreEqual(1, results.Count); //Read All with partition key results = container.GetItemLinqQueryable <dynamic>( allowSynchronousQueryExecution: true, requestOptions: new QueryRequestOptions() { MaxItemCount = 1, PartitionKey = new PartitionKey("BasicQueryItem") }).ToList(); Assert.AreEqual(1, results.Count); // LINQ to feed iterator Read All with partition key using (FeedIterator <dynamic> iterator = container.GetItemLinqQueryable <dynamic>( allowSynchronousQueryExecution: true, requestOptions: new QueryRequestOptions() { MaxItemCount = 1, PartitionKey = new PartitionKey("BasicQueryItem") }).ToFeedIterator()) { List <dynamic> linqResults = new List <dynamic>(); while (iterator.HasMoreResults) { linqResults.AddRange(await iterator.ReadNextAsync()); } Assert.AreEqual(1, linqResults.Count); Assert.AreEqual("BasicQueryItem", linqResults.First().pk.ToString()); } }
public async Task StandByFeedIterator() { int totalCount = 0; string lastcontinuation = string.Empty; int firstRunTotal = 25; int batchSize = 25; int pkRangesCount = (await this.Container.ClientContext.DocumentClient.ReadPartitionKeyRangeFeedAsync(this.Container.LinkUri)).Count; await this.CreateRandomItems(this.Container, batchSize, randomPartitionKey : true); ContainerInternal itemsCore = this.Container; FeedIterator feedIterator = itemsCore.GetStandByFeedIterator(requestOptions: new StandByFeedIteratorRequestOptions() { StartTime = DateTime.MinValue }); while (feedIterator.HasMoreResults) { using (ResponseMessage responseMessage = await feedIterator.ReadNextAsync(this.cancellationToken)) { lastcontinuation = responseMessage.Headers.ContinuationToken; Assert.AreEqual(responseMessage.ContinuationToken, responseMessage.Headers.ContinuationToken); List <CompositeContinuationToken> deserializedToken = JsonConvert.DeserializeObject <List <CompositeContinuationToken> >(lastcontinuation); Assert.AreEqual(pkRangesCount, deserializedToken.Count); if (!responseMessage.IsSuccessStatusCode) { break; } Collection <ToDoActivity> response = TestCommon.SerializerCore.FromStream <CosmosFeedResponseUtil <ToDoActivity> >(responseMessage.Content).Data; totalCount += response.Count; } } Assert.AreEqual(firstRunTotal, totalCount); int expectedFinalCount = 50; // Insert another batch of 25 and use the last continuation token from the first cycle await this.CreateRandomItems(this.Container, batchSize, randomPartitionKey : true); FeedIterator setIteratorNew = itemsCore.GetStandByFeedIterator(lastcontinuation); while (setIteratorNew.HasMoreResults) { using (ResponseMessage responseMessage = await setIteratorNew.ReadNextAsync(this.cancellationToken)) { lastcontinuation = responseMessage.Headers.ContinuationToken; Assert.AreEqual(responseMessage.ContinuationToken, responseMessage.Headers.ContinuationToken); if (!responseMessage.IsSuccessStatusCode) { break; } Collection <ToDoActivity> response = TestCommon.SerializerCore.FromStream <CosmosFeedResponseUtil <ToDoActivity> >(responseMessage.Content).Data; totalCount += response.Count; } } Assert.AreEqual(expectedFinalCount, totalCount); }
private async Task <List <T> > ToListAsync <T>( QueryStream createStreamQuery, Query <T> createQuery, string queryText, QueryRequestOptions requestOptions) { HttpStatusCode expectedStatus = HttpStatusCode.OK; FeedIterator feedStreamIterator = createStreamQuery(queryText, null, requestOptions); List <T> streamResults = new List <T>(); while (feedStreamIterator.HasMoreResults) { ResponseMessage response = await feedStreamIterator.ReadNextAsync(); response.EnsureSuccessStatusCode(); Assert.AreEqual(expectedStatus, response.StatusCode); StreamReader sr = new StreamReader(response.Content); string result = await sr.ReadToEndAsync(); ICollection <T> responseResults; responseResults = JsonConvert.DeserializeObject <CosmosFeedResponseUtil <T> >(result).Data; Assert.IsTrue(responseResults.Count <= 1); streamResults.AddRange(responseResults); } string continuationToken = null; List <T> pagedStreamResults = new List <T>(); do { FeedIterator pagedFeedIterator = createStreamQuery(queryText, continuationToken, requestOptions); ResponseMessage response = await pagedFeedIterator.ReadNextAsync(); response.EnsureSuccessStatusCode(); Assert.AreEqual(expectedStatus, response.StatusCode); IEnumerable <T> responseResults = TestCommon.SerializerCore.FromStream <CosmosFeedResponseUtil <T> >(response.Content).Data; Assert.IsTrue(responseResults.Count() <= 1); pagedStreamResults.AddRange(responseResults); continuationToken = response.Headers.ContinuationToken; Assert.AreEqual(response.ContinuationToken, response.Headers.ContinuationToken); } while (continuationToken != null); Assert.AreEqual(pagedStreamResults.Count, streamResults.Count); // Both lists should be the same if not PermssionsProperties. PermissionProperties will have a different ResouceToken in the payload when read. string streamResultString = JsonConvert.SerializeObject(streamResults); string streamPagedResultString = JsonConvert.SerializeObject(pagedStreamResults); if (typeof(T) != typeof(PermissionProperties)) { Assert.AreEqual(streamPagedResultString, streamResultString); } FeedIterator <T> feedIterator = createQuery(queryText, null, requestOptions); List <T> results = new List <T>(); while (feedIterator.HasMoreResults) { FeedResponse <T> response = await feedIterator.ReadNextAsync(); Assert.AreEqual(expectedStatus, response.StatusCode); Assert.IsTrue(response.Count <= 1); Assert.IsTrue(response.Resource.Count() <= 1); results.AddRange(response); } continuationToken = null; List <T> pagedResults = new List <T>(); do { FeedIterator <T> pagedFeedIterator = createQuery(queryText, continuationToken, requestOptions); FeedResponse <T> response = await pagedFeedIterator.ReadNextAsync(); Assert.AreEqual(expectedStatus, response.StatusCode); Assert.IsTrue(response.Count <= 1); Assert.IsTrue(response.Resource.Count() <= 1); pagedResults.AddRange(response); continuationToken = response.ContinuationToken; } while (continuationToken != null); Assert.AreEqual(pagedResults.Count, results.Count); // Both lists should be the same string resultString = JsonConvert.SerializeObject(results); string pagedResultString = JsonConvert.SerializeObject(pagedResults); if (typeof(T) != typeof(PermissionProperties)) { Assert.AreEqual(pagedResultString, resultString); Assert.AreEqual(streamPagedResultString, resultString); } return(results); }
private async Task <long> ExecuteQueryAndReturnOutputDocumentCount( string queryText, int expectedItemCount, bool disableDiagnostics) { QueryDefinition sql = null; if (queryText != null) { sql = new QueryDefinition(queryText); } QueryRequestOptions requestOptions = new QueryRequestOptions() { MaxItemCount = 1, MaxConcurrency = 1, }; if (disableDiagnostics) { requestOptions.DiagnosticContextFactory = () => EmptyCosmosDiagnosticsContext.Singleton; } ; // Verify the typed query iterator FeedIterator <ToDoActivity> feedIterator = this.Container.GetItemQueryIterator <ToDoActivity>( sql, requestOptions: requestOptions); List <ToDoActivity> results = new List <ToDoActivity>(); long totalOutDocumentCount = 0; bool isFirst = true; while (feedIterator.HasMoreResults) { FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync(); results.AddRange(response); if (queryText == null) { CosmosDiagnosticsTests.VerifyPointDiagnostics( response.Diagnostics, disableDiagnostics); } else { VerifyQueryDiagnostics( response.Diagnostics, isFirst, disableDiagnostics); } isFirst = false; } Assert.AreEqual(expectedItemCount, results.Count); // Verify the stream query iterator FeedIterator streamIterator = this.Container.GetItemQueryStreamIterator( sql, requestOptions: requestOptions); List <ToDoActivity> streamResults = new List <ToDoActivity>(); long streamTotalOutDocumentCount = 0; isFirst = true; while (streamIterator.HasMoreResults) { ResponseMessage response = await streamIterator.ReadNextAsync(); Collection <ToDoActivity> result = TestCommon.SerializerCore.FromStream <CosmosFeedResponseUtil <ToDoActivity> >(response.Content).Data; streamResults.AddRange(result); if (queryText == null) { CosmosDiagnosticsTests.VerifyPointDiagnostics( response.Diagnostics, disableDiagnostics); } else { VerifyQueryDiagnostics( response.Diagnostics, isFirst, disableDiagnostics); } isFirst = false; } Assert.AreEqual(expectedItemCount, streamResults.Count); Assert.AreEqual(totalOutDocumentCount, streamTotalOutDocumentCount); return(results.Count); }
public async Task ParallelizeQueryThroughTokens_OfT() { ContainerInternal container = null; try { // Create a container large enough to have at least 2 partitions ContainerResponse containerResponse = await this.database.CreateContainerAsync( id : Guid.NewGuid().ToString(), partitionKeyPath : "/id", throughput : 15000); container = (ContainerInlineCore)containerResponse; List <string> generatedIds = Enumerable.Range(0, 1000).Select(n => $"BasicItem{n}").ToList(); foreach (string id in generatedIds) { string item = $@" {{ ""id"": ""{id}"" }}"; using (ResponseMessage createResponse = await container.CreateItemStreamAsync( QueryFeedRangeTests.GenerateStreamFromString(item), new Cosmos.PartitionKey(id))) { Assert.IsTrue(createResponse.IsSuccessStatusCode); } } IReadOnlyList <FeedRange> feedTokens = await container.GetFeedRangesAsync(); Assert.IsTrue(feedTokens.Count > 1, " RUs of the container needs to be increased to ensure at least 2 partitions."); List <Task <List <string> > > tasks = feedTokens.Select(async feedToken => { List <string> results = new List <string>(); FeedIterator <ToDoActivity> feedIterator = container.GetItemQueryIterator <ToDoActivity>(queryDefinition: new QueryDefinition("select * from T where STARTSWITH(T.id, \"BasicItem\")"), feedRange: feedToken, requestOptions: new QueryRequestOptions() { MaxItemCount = 10 }); string continuation = null; while (feedIterator.HasMoreResults) { FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync(); foreach (ToDoActivity toDoActivity in response) { results.Add(toDoActivity.id); } continuation = response.ContinuationToken; break; } feedIterator = container.GetItemQueryIterator <ToDoActivity>(queryDefinition: new QueryDefinition("select * from T where STARTSWITH(T.id, \"BasicItem\")"), feedRange: feedToken, continuationToken: continuation, requestOptions: new QueryRequestOptions() { MaxItemCount = 10 }); while (feedIterator.HasMoreResults) { FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync(); foreach (ToDoActivity toDoActivity in response) { results.Add(toDoActivity.id); } } return(results); }).ToList(); await Task.WhenAll(tasks); CollectionAssert.AreEquivalent(generatedIds, tasks.SelectMany(t => t.Result).ToList()); } finally { await container?.DeleteContainerAsync(); } }