示例#1
0
        // </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);
        }
示例#3
0
        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);
        }
示例#4
0
        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}");
            }
        }
示例#5
0
    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);
            }
        }
示例#7
0
        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);
        }
示例#8
0
        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");
        }
示例#9
0
        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);
        }
示例#10
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();
                }
            }
        }
示例#11
0
        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);
        }
示例#12
0
        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();
        }
示例#14
0
        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);
        }
示例#18
0
        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);
                    }
                }
            }
        }
示例#19
0
        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]);
        }
示例#20
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));
            }
        }
示例#21
0
 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()) { }
                }
            }
        }
示例#23
0
        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);
        }
示例#24
0
        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));
            }
        }
示例#25
0
        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);
            }
        }
示例#26
0
        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);
        }
示例#28
0
        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);
        }
示例#30
0
        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();
            }
        }