Esempio n. 1
0
        public async Task GetTargetPartitionKeyRangesAsyncWithFeedRange()
        {
            ContainerCore 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 : "/pk",
                    throughput : 15000);

                container = (ContainerInlineCore)containerResponse;

                // Get all the partition key ranges to verify there is more than one partition
                IRoutingMapProvider routingMapProvider = await this.cosmosClient.DocumentClient.GetPartitionKeyRangeCacheAsync();

                ContainerQueryProperties containerQueryProperties = new ContainerQueryProperties(
                    containerResponse.Resource.ResourceId,
                    null,
                    containerResponse.Resource.PartitionKey);

                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.");

                // There should only be one range since we get 1 FeedRange per range
                foreach (FeedRange feedToken in feedTokens)
                {
                    List <PartitionKeyRange> partitionKeyRanges = await CosmosQueryExecutionContextFactory.GetTargetPartitionKeyRangesAsync(
                        queryClient : new CosmosQueryClientCore(container.ClientContext, container),
                        resourceLink : container.LinkUri.OriginalString,
                        partitionedQueryExecutionInfo : null,
                        containerQueryProperties : containerQueryProperties,
                        properties : null,
                        feedRangeInternal : feedToken as FeedRangeInternal);

                    Assert.IsTrue(partitionKeyRanges.Count == 1, "Only 1 partition key range should be selected since the FeedRange represents a single range.");
                }
            }
            finally
            {
                await container?.DeleteContainerAsync();
            }
        }
Esempio n. 2
0
        public async Task ParallelizeQueryThroughTokens()
        {
            ContainerCore 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>();
                    FeedIteratorInternal feedIterator = container.GetItemQueryStreamIterator(queryDefinition: new QueryDefinition("select * from T where STARTSWITH(T.id, \"BasicItem\")"), feedRange: feedToken, requestOptions: new QueryRequestOptions()
                    {
                        MaxItemCount = 10
                    }) as FeedIteratorInternal;
                    string continuation = null;
                    while (feedIterator.HasMoreResults)
                    {
                        using (ResponseMessage responseMessage =
                                   await feedIterator.ReadNextAsync(this.cancellationToken))
                        {
                            if (responseMessage.IsSuccessStatusCode)
                            {
                                using (StreamReader reader = new StreamReader(responseMessage.Content))
                                {
                                    string json      = await reader.ReadToEndAsync();
                                    JArray documents = (JArray)JObject.Parse(json).SelectToken("Documents");
                                    foreach (JObject document in documents)
                                    {
                                        results.Add(document.SelectToken("id").ToString());
                                    }
                                }
                            }

                            continuation = responseMessage.ContinuationToken;
                            break;
                        }
                    }

                    feedIterator = container.GetItemQueryStreamIterator(queryDefinition: new QueryDefinition("select * from T where STARTSWITH(T.id, \"BasicItem\")"), feedRange: feedToken, continuationToken: continuation, requestOptions: new QueryRequestOptions()
                    {
                        MaxItemCount = 10
                    }) as FeedIteratorInternal;
                    while (feedIterator.HasMoreResults)
                    {
                        using (ResponseMessage responseMessage =
                                   await feedIterator.ReadNextAsync(this.cancellationToken))
                        {
                            if (responseMessage.IsSuccessStatusCode)
                            {
                                using (StreamReader reader = new StreamReader(responseMessage.Content))
                                {
                                    string json      = await reader.ReadToEndAsync();
                                    JArray documents = (JArray)JObject.Parse(json).SelectToken("Documents");
                                    foreach (JObject document in documents)
                                    {
                                        results.Add(document.SelectToken("id").ToString());
                                    }
                                }
                            }
                        }
                    }

                    return(results);
                }).ToList();

                await Task.WhenAll(tasks);

                CollectionAssert.AreEquivalent(generatedIds, tasks.SelectMany(t => t.Result).ToList());
            }
            finally
            {
                await container?.DeleteContainerAsync();
            }
        }
        public async Task ReadFeedIteratorCore_CrossPartitionBiDirectional(bool useStatelessIteration)
        {
            ContainerCore container = null;

            try
            {
                ContainerResponse containerResponse = await this.database.CreateContainerAsync(
                    new ContainerProperties(id : Guid.NewGuid().ToString(), partitionKeyPath : "/id"),
                    throughput : 50000,
                    cancellationToken : this.cancellationToken);

                container = (ContainerInlineCore)containerResponse;

                //create items
                const int           total          = 30;
                QueryRequestOptions requestOptions = new QueryRequestOptions()
                {
                    MaxItemCount = 10
                };

                List <string> items = new List <string>();

                for (int i = 0; i < total; i++)
                {
                    string item = $@"
                    {{    
                        ""id"": ""{i}""
                    }}";

                    using (ResponseMessage createResponse = await container.CreateItemStreamAsync(
                               ReadFeedRangeTests.GenerateStreamFromString(item),
                               new Cosmos.PartitionKey(i.ToString())))
                    {
                        Assert.IsTrue(createResponse.IsSuccessStatusCode);
                    }
                }

                string       continuation = null;
                FeedIterator iter         = container.GetItemQueryStreamIterator(
                    continuationToken: continuation,
                    requestOptions: requestOptions);

                int           count        = 0;
                List <string> forwardOrder = new List <string>();
                while (iter.HasMoreResults)
                {
                    if (useStatelessIteration)
                    {
                        iter = container.GetItemQueryStreamIterator(
                            continuationToken: continuation,
                            requestOptions: requestOptions);
                    }

                    using (ResponseMessage response = await iter.ReadNextAsync())
                    {
                        Assert.IsNotNull(response);

                        continuation = response.ContinuationToken;

                        using (StreamReader reader = new StreamReader(response.Content))
                        {
                            string json = await reader.ReadToEndAsync();

                            JArray documents = (JArray)JObject.Parse(json).SelectToken("Documents");
                            count += documents.Count;
                            if (documents.Any())
                            {
                                forwardOrder.Add(documents.First().SelectToken("id").ToString());
                            }
                        }
                    }
                }

                Assert.IsNotNull(forwardOrder);
                Assert.AreEqual(total, count);
                Assert.IsFalse(forwardOrder.Where(x => string.IsNullOrEmpty(x)).Any());

                requestOptions.Properties = requestOptions.Properties = new Dictionary <string, object>();
                requestOptions.Properties.Add(Documents.HttpConstants.HttpHeaders.EnumerationDirection, (byte)BinaryScanDirection.Reverse);
                count = 0;
                List <string> reverseOrder = new List <string>();

                continuation = null;
                iter         = container
                               .GetItemQueryStreamIterator(queryDefinition: null, continuationToken: continuation, requestOptions: requestOptions);
                while (iter.HasMoreResults)
                {
                    if (useStatelessIteration)
                    {
                        iter = container
                               .GetItemQueryStreamIterator(queryDefinition: null, continuationToken: continuation, requestOptions: requestOptions);
                    }

                    using (ResponseMessage response = await iter.ReadNextAsync())
                    {
                        continuation = response.ContinuationToken;

                        Assert.IsNotNull(response);
                        using (StreamReader reader = new StreamReader(response.Content))
                        {
                            string json = await reader.ReadToEndAsync();

                            JArray documents = (JArray)JObject.Parse(json).SelectToken("Documents");
                            count += documents.Count;
                            if (documents.Any())
                            {
                                reverseOrder.Add(documents.First().SelectToken("id").ToString());
                            }
                        }
                    }
                }

                Assert.IsNotNull(reverseOrder);

                Assert.AreEqual(total, count);
                forwardOrder.Reverse();

                CollectionAssert.AreEqual(forwardOrder, reverseOrder);
                Assert.IsFalse(reverseOrder.Where(x => string.IsNullOrEmpty(x)).Any());
            }
            finally
            {
                await container?.DeleteContainerAsync();
            }
        }