예제 #1
0
        public static IReadOnlyList <Record> GetRecords(this ReadFeedPage page)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                page.Content.CopyTo(memoryStream);
                CosmosObject responseEnvolope = CosmosObject.CreateFromBuffer(memoryStream.ToArray());
                if (!responseEnvolope.TryGetValue("Documents", out CosmosArray documents))
                {
                    throw new InvalidOperationException();
                }

                List <Record> records = new List <Record>();
                foreach (CosmosElement document in documents)
                {
                    CosmosObject documentObject = (CosmosObject)document;
                    ResourceId   rid            = ResourceId.Parse(((CosmosString)documentObject["_rid"]).Value);
                    long         ticks          = Number64.ToLong(((CosmosNumber)documentObject["_ts"]).Value);
                    string       id             = ((CosmosString)documentObject["id"]).Value;
                    CosmosObject payload        = documentObject;

                    Record record = new Record(rid, new DateTime(ticks: ticks, DateTimeKind.Utc), id, payload);
                    records.Add(record);
                }

                return(records);
            }
        }
예제 #2
0
        private static CosmosArray GetChanges(Stream stream)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                stream.CopyTo(memoryStream);
                CosmosObject element = CosmosObject.CreateFromBuffer(memoryStream.ToArray());
                if (!element.TryGetValue("Documents", out CosmosArray value))
                {
                    Assert.Fail();
                }

                return(value);
            }
        }
예제 #3
0
        private static int GetResponseCount(Stream stream)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                stream.CopyTo(memoryStream);
                CosmosObject element = CosmosObject.CreateFromBuffer(memoryStream.ToArray());
                if (!element.TryGetValue("_count", out CosmosElement value))
                {
                    Assert.Fail();
                }

                return((int)Number64.ToLong(((CosmosNumber)value).Value));
            }
        }
예제 #4
0
        public async Task TestCosmosOrderByQueryExecutionContextWithFailurePageAsync(bool createInitialContinuationToken)
        {
            int maxPageSize = 5;

            List <MockPartitionResponse[]> mockResponsesScenario = MockQueryFactory.GetFailureScenarios();

            Mock <CosmosQueryClient> mockQueryClient = new Mock <CosmosQueryClient>();

            foreach (MockPartitionResponse[] mockResponse in mockResponsesScenario)
            {
                string initialContinuationToken = null;
                string fullContinuationToken    = null;
                if (createInitialContinuationToken)
                {
                    ToDoItem itemToRepresentPreviousQuery = ToDoItem.CreateItems(
                        1,
                        "itemToRepresentPreviousQuery",
                        MockQueryFactory.DefaultCollectionRid).First();

                    initialContinuationToken = $" - RID:{itemToRepresentPreviousQuery._rid} ==#RT:1#TRC:1";
                    CompositeContinuationToken compositeContinuation = new CompositeContinuationToken()
                    {
                        Range = new Documents.Routing.Range <string>(
                            min: MockQueryFactory.DefaultPartitionKeyRange.MinInclusive,
                            max: MockQueryFactory.DefaultPartitionKeyRange.MaxExclusive,
                            isMaxInclusive: false,
                            isMinInclusive: true),
                        Token = initialContinuationToken
                    };

                    List <OrderByItem> orderByItems = new List <OrderByItem>()
                    {
                        new OrderByItem(CosmosObject.CreateFromBuffer(Encoding.UTF8.GetBytes("{\"item\":\"2c4ce711-13c3-4c93-817c-49287b71b6c3\"}")))
                    };

                    OrderByContinuationToken orderByContinuationToken = new OrderByContinuationToken(
                        compositeContinuationToken: compositeContinuation,
                        orderByItems: orderByItems,
                        rid: itemToRepresentPreviousQuery._rid,
                        skipCount: 0,
                        filter: null);

                    fullContinuationToken = CosmosArray.Create(
                        new List <CosmosElement>()
                    {
                        OrderByContinuationToken.ToCosmosElement(orderByContinuationToken)
                    }).ToString();
                }

                IList <ToDoItem> allItems = MockQueryFactory.GenerateAndMockResponse(
                    mockQueryClient,
                    isOrderByQuery: true,
                    sqlQuerySpec: MockQueryFactory.DefaultQuerySpec,
                    containerRid: MockQueryFactory.DefaultCollectionRid,
                    initContinuationToken: initialContinuationToken,
                    maxPageSize: maxPageSize,
                    mockResponseForSinglePartition: mockResponse,
                    cancellationTokenForMocks: this.cancellationToken);

                // Order by drains the partitions until it finds an item
                // If there are no items then it's not possible to have a continuation token
                if (allItems.Count == 0 && createInitialContinuationToken)
                {
                    continue;
                }

                CosmosQueryContext context = MockQueryFactory.CreateContext(
                    mockQueryClient.Object);

                QueryInfo queryInfo = new QueryInfo()
                {
                    OrderBy            = new SortOrder[] { SortOrder.Ascending },
                    OrderByExpressions = new string[] { "id" }
                };

                CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams initParams = new CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams(
                    sqlQuerySpec: MockQueryFactory.DefaultQuerySpec,
                    collectionRid: MockQueryFactory.DefaultCollectionRid,
                    partitionedQueryExecutionInfo: new PartitionedQueryExecutionInfo()
                {
                    QueryInfo = queryInfo
                },
                    partitionKeyRanges: new List <PartitionKeyRange>()
                {
                    MockQueryFactory.DefaultPartitionKeyRange
                },
                    initialPageSize: maxPageSize,
                    maxConcurrency: null,
                    maxItemCount: maxPageSize,
                    maxBufferedItemCount: null,
                    returnResultsInDeterministicOrder: true,
                    testSettings: new TestInjections(simulate429s: false, simulateEmptyPages: false));

                TryCatch <IDocumentQueryExecutionComponent> tryCreate = await CosmosOrderByItemQueryExecutionContext.TryCreateAsync(
                    context,
                    initParams,
                    fullContinuationToken != null?CosmosElement.Parse(fullContinuationToken) : null,
                    this.cancellationToken);

                if (tryCreate.Succeeded)
                {
                    IDocumentQueryExecutionComponent executionContext = tryCreate.Result;

                    Assert.IsTrue(!executionContext.IsDone);

                    // Read all the pages from both splits
                    List <ToDoItem>   itemsRead = new List <ToDoItem>();
                    QueryResponseCore?failure   = null;
                    while (!executionContext.IsDone)
                    {
                        QueryResponseCore queryResponse = await executionContext.DrainAsync(
                            maxPageSize,
                            this.cancellationToken);

                        if (queryResponse.IsSuccess)
                        {
                            string responseContinuationToken = queryResponse.ContinuationToken;
                            foreach (CosmosElement element in queryResponse.CosmosElements)
                            {
                                string   jsonValue = element.ToString();
                                ToDoItem item      = JsonConvert.DeserializeObject <ToDoItem>(jsonValue);
                                itemsRead.Add(item);
                            }
                        }
                        else
                        {
                            Assert.IsNull(failure, "There should only be one error");
                            failure = queryResponse;
                        }
                    }

                    Assert.IsNotNull(failure);
                    Assert.AreEqual((HttpStatusCode)429, failure.Value.StatusCode);
                    Assert.IsNotNull(failure.Value.CosmosException.ToString());

                    Assert.AreEqual(0 /*We don't get any items, since we don't buffer the failure anymore*/, itemsRead.Count);

                    //CollectionAssert.AreEqual(allItems.ToList(), itemsRead, new ToDoItemComparer());
                }
                else
                {
                    QueryResponseCore queryResponseCore = QueryResponseFactory.CreateFromException(tryCreate.Exception);
                    Assert.AreEqual((HttpStatusCode)429, queryResponseCore.StatusCode);
                }
            }
        }
예제 #5
0
        public async Task TestCosmosOrderByQueryExecutionContextWithEmptyPagesAndSplitAsync(bool createInitialContinuationToken)
        {
            int maxPageSize = 5;

            List <MockPartitionResponse[]> mockResponsesScenario = MockQueryFactory.GetSplitScenarios();

            Mock <CosmosQueryClient> mockQueryClient = new Mock <CosmosQueryClient>();

            foreach (MockPartitionResponse[] mockResponse in mockResponsesScenario)
            {
                string initialContinuationToken = null;
                string fullConitnuationToken    = null;
                if (createInitialContinuationToken)
                {
                    ToDoItem itemToRepresentPreviousQuery = ToDoItem.CreateItems(
                        1,
                        "itemToRepresentPreviousQuery",
                        MockQueryFactory.DefaultCollectionRid).First();

                    initialContinuationToken = $" - RID:{itemToRepresentPreviousQuery._rid} ==#RT:1#TRC:1";
                    CompositeContinuationToken compositeContinuation = new CompositeContinuationToken()
                    {
                        Range = new Documents.Routing.Range <string>(
                            min: MockQueryFactory.DefaultPartitionKeyRange.MinInclusive,
                            max: MockQueryFactory.DefaultPartitionKeyRange.MaxExclusive,
                            isMaxInclusive: false,
                            isMinInclusive: true),
                        Token = initialContinuationToken
                    };

                    List <OrderByItem> orderByItems = new List <OrderByItem>()
                    {
                        new OrderByItem(CosmosObject.CreateFromBuffer(Encoding.UTF8.GetBytes("{\"item\":\"2c4ce711-13c3-4c93-817c-49287b71b6c3\"}")))
                    };

                    OrderByContinuationToken orderByContinuationToken = new OrderByContinuationToken(
                        queryClient: mockQueryClient.Object,
                        compositeContinuationToken: compositeContinuation,
                        orderByItems: orderByItems,
                        rid: itemToRepresentPreviousQuery._rid,
                        skipCount: 0,
                        filter: null);

                    fullConitnuationToken = JsonConvert.SerializeObject(new OrderByContinuationToken[] { orderByContinuationToken });
                }


                IList <ToDoItem> allItems = MockQueryFactory.GenerateAndMockResponse(
                    mockQueryClient,
                    isOrderByQuery: true,
                    sqlQuerySpec: MockQueryFactory.DefaultQuerySpec,
                    containerRid: MockQueryFactory.DefaultCollectionRid,
                    initContinuationToken: initialContinuationToken,
                    maxPageSize: maxPageSize,
                    mockResponseForSinglePartition: mockResponse,
                    cancellationTokenForMocks: this.cancellationToken);

                // Order by drains the partitions until it finds an item
                // If there are no items then it's not possible to have a continuation token
                if (allItems.Count == 0 && createInitialContinuationToken)
                {
                    continue;
                }

                CosmosQueryContext context = MockQueryFactory.CreateContext(
                    mockQueryClient.Object);

                QueryInfo queryInfo = new QueryInfo()
                {
                    OrderBy            = new SortOrder[] { SortOrder.Ascending },
                    OrderByExpressions = new string[] { "id" }
                };

                CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams initParams = new CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams(
                    sqlQuerySpec: MockQueryFactory.DefaultQuerySpec,
                    collectionRid: MockQueryFactory.DefaultCollectionRid,
                    partitionedQueryExecutionInfo: new PartitionedQueryExecutionInfo()
                {
                    QueryInfo = queryInfo
                },
                    partitionKeyRanges: new List <PartitionKeyRange>()
                {
                    MockQueryFactory.DefaultPartitionKeyRange
                },
                    initialPageSize: maxPageSize,
                    maxConcurrency: null,
                    maxItemCount: maxPageSize,
                    maxBufferedItemCount: null);

                CosmosOrderByItemQueryExecutionContext executionContext = (await CosmosOrderByItemQueryExecutionContext.TryCreateAsync(
                                                                               context,
                                                                               initParams,
                                                                               fullConitnuationToken,
                                                                               this.cancellationToken)).Result;

                // For order by it will drain all the pages till it gets a value.
                if (allItems.Count == 0)
                {
                    Assert.IsTrue(executionContext.IsDone);
                    continue;
                }

                Assert.IsTrue(!executionContext.IsDone);

                // Read all the pages from both splits
                List <ToDoItem> itemsRead = new List <ToDoItem>();
                while (!executionContext.IsDone)
                {
                    QueryResponseCore queryResponse = await executionContext.DrainAsync(
                        maxPageSize,
                        this.cancellationToken);

                    string responseContinuationToken = queryResponse.ContinuationToken;
                    foreach (CosmosElement element in queryResponse.CosmosElements)
                    {
                        string   jsonValue = element.ToString();
                        ToDoItem item      = JsonConvert.DeserializeObject <ToDoItem>(jsonValue);
                        itemsRead.Add(item);
                    }
                }

                Assert.AreEqual(allItems.Count, itemsRead.Count);

                CollectionAssert.AreEqual(allItems.ToList(), itemsRead, new ToDoItemComparer());
            }
        }