private ToDoItem ConvertCosmosElement(CosmosElement element)
        {
            string   jsonValue = element.ToString();
            ToDoItem item      = JsonConvert.DeserializeObject <ToDoItem>(jsonValue);

            return(item);
        }
Esempio n. 2
0
        private static async Task <int> DrainWithUntilNotModifiedWithContinuationTokens(
            IDocumentContainer documentContainer,
            CrossPartitionChangeFeedAsyncEnumerator enumerator)
        {
            List <CosmosElement> globalChanges = new List <CosmosElement>();

            while (true)
            {
                if (!await enumerator.MoveNextAsync())
                {
                    throw new InvalidOperationException();
                }

                Assert.IsTrue(enumerator.Current.Succeeded);

                if (!(enumerator.Current.Result is ChangeFeedSuccessPage changeFeedSuccessPage))
                {
                    break;
                }

                CosmosArray changes = GetChanges(changeFeedSuccessPage.Content);
                globalChanges.AddRange(changes);

                CosmosElement continuationToken = ((ChangeFeedStateContinuation)enumerator.Current.Result.State).ContinuationToken;

                enumerator = CrossPartitionChangeFeedAsyncEnumerator.MonadicCreate(
                    documentContainer,
                    new ChangeFeedRequestOptions(),
                    ChangeFeedStartFrom.ContinuationToken(continuationToken.ToString()),
                    cancellationToken: default).Result;
            }

            return(globalChanges.Count);
        }
        public void TestRoundTripAsCosmosElement()
        {
            CompositeContinuationToken compositeContinuationToken = new CompositeContinuationToken()
            {
                Token = "someToken",
                Range = new Documents.Routing.Range <string>("asdf", "asdf", false, false),
            };

            List <OrderByItem> orderByItems = new List <OrderByItem>()
            {
                new OrderByItem(CosmosObject.Create(new Dictionary <string, CosmosElement>()
                {
                    { "item", CosmosString.Create("asdf") }
                })),
                new OrderByItem(CosmosObject.Create(new Dictionary <string, CosmosElement>()
                {
                    { "item", CosmosInt64.Create(1337) }
                })),
                new OrderByItem(CosmosObject.Create(new Dictionary <string, CosmosElement>()
                {
                    { "item", CosmosBinary.Create(new byte[] { 1, 2, 3 }) }
                })),
            };

            string rid       = "someRid";
            int    skipCount = 42;
            string filter    = "someFilter";
            OrderByContinuationToken orderByContinuationToken = new OrderByContinuationToken(
                compositeContinuationToken,
                orderByItems,
                rid,
                skipCount,
                filter);

            CosmosElement cosmosElementToken = OrderByContinuationToken.ToCosmosElement(orderByContinuationToken);

            Assert.AreEqual(
                @"{""compositeToken"":{""token"":""someToken"",""range"":{""min"":""asdf"",""max"":""asdf""}},""orderByItems"":[{""item"":""asdf""},{""item"":LL1337},{""item"":BAQID}],""rid"":""someRid"",""skipCount"":42,""filter"":""someFilter""}",
                cosmosElementToken.ToString());
            TryCatch <OrderByContinuationToken> tryOrderByContinuationTokenFromCosmosElement = OrderByContinuationToken.TryCreateFromCosmosElement(cosmosElementToken);

            Assert.IsTrue(tryOrderByContinuationTokenFromCosmosElement.Succeeded);
            OrderByContinuationToken orderByContinuationTokenFromCosmosElement = tryOrderByContinuationTokenFromCosmosElement.Result;

            Assert.IsNotNull(orderByContinuationTokenFromCosmosElement);
            Assert.AreEqual(cosmosElementToken.ToString(), OrderByContinuationToken.ToCosmosElement(orderByContinuationTokenFromCosmosElement).ToString());
        }
        internal static async Task <List <T> > QueryWithCosmosElementContinuationTokenAsync <T>(
            Container container,
            string query,
            QueryRequestOptions queryRequestOptions = null)
        {
            if (queryRequestOptions == null)
            {
                queryRequestOptions = new QueryRequestOptions();
            }

            List <T>      resultsFromCosmosElementContinuationToken = new List <T>();
            CosmosElement continuationToken = null;

            do
            {
                QueryRequestOptions computeRequestOptions = queryRequestOptions.Clone();
                computeRequestOptions.ExecutionEnvironment           = Cosmos.Query.Core.ExecutionContext.ExecutionEnvironment.Compute;
                computeRequestOptions.CosmosElementContinuationToken = continuationToken;

                FeedIteratorInternal <T> itemQuery = (FeedIteratorInternal <T>)container.GetItemQueryIterator <T>(
                    queryText: query,
                    requestOptions: computeRequestOptions);
                try
                {
                    FeedResponse <T> cosmosQueryResponse = await itemQuery.ReadNextAsync();

                    if (queryRequestOptions.MaxItemCount.HasValue)
                    {
                        Assert.IsTrue(
                            cosmosQueryResponse.Count <= queryRequestOptions.MaxItemCount.Value,
                            "Max Item Count is not being honored");
                    }

                    resultsFromCosmosElementContinuationToken.AddRange(cosmosQueryResponse);

                    // Force a rewrite of the continuation token, so that we test the case where we roundtrip it over the wire.
                    // There was a bug where resuming from double.NaN lead to an exception,
                    // since we parsed the type assuming it was always a double and not a string.
                    CosmosElement originalContinuationToken = itemQuery.GetCosmosElementContinuationToken();
                    if (originalContinuationToken != null)
                    {
                        continuationToken = CosmosElement.Parse(originalContinuationToken.ToString());
                    }
                    else
                    {
                        continuationToken = null;
                    }
                }
                catch (CosmosException cosmosException) when(cosmosException.StatusCode == (HttpStatusCode)429)
                {
                    itemQuery = (FeedIteratorInternal <T>)container.GetItemQueryIterator <T>(
                        queryText: query,
                        requestOptions: queryRequestOptions);
                }
            } while (continuationToken != null);

            return(resultsFromCosmosElementContinuationToken);
        }
            public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateTopDocumentQueryExecutionComponentAsync(
                int topCount,
                CosmosElement requestContinuationToken,
                Func <CosmosElement, Task <TryCatch <IDocumentQueryExecutionComponent> > > tryCreateSourceAsync)
            {
                if (topCount < 0)
                {
                    throw new ArgumentException($"{nameof(topCount)}: {topCount} must be a non negative number.");
                }

                if (tryCreateSourceAsync == null)
                {
                    throw new ArgumentNullException(nameof(tryCreateSourceAsync));
                }

                TopContinuationToken topContinuationToken;

                if (requestContinuationToken != null)
                {
                    if (!TopContinuationToken.TryParse(requestContinuationToken.ToString(), out topContinuationToken))
                    {
                        return(TryCatch <IDocumentQueryExecutionComponent> .FromException(
                                   new MalformedContinuationTokenException($"Malformed {nameof(LimitContinuationToken)}: {requestContinuationToken}.")));
                    }
                }
                else
                {
                    topContinuationToken = new TopContinuationToken(topCount, null);
                }

                if (topContinuationToken.Top > topCount)
                {
                    return(TryCatch <IDocumentQueryExecutionComponent> .FromException(
                               new MalformedContinuationTokenException($"{nameof(TopContinuationToken.Top)} in {nameof(TopContinuationToken)}: {requestContinuationToken}: {topContinuationToken.Top} can not be greater than the top count in the query: {topCount}.")));
                }

                CosmosElement sourceToken;

                if (topContinuationToken.SourceToken != null)
                {
                    if (!CosmosElement.TryParse(topContinuationToken.SourceToken, out sourceToken))
                    {
                        return(TryCatch <IDocumentQueryExecutionComponent> .FromException(
                                   new MalformedContinuationTokenException($"{nameof(TopContinuationToken.SourceToken)} in {nameof(TopContinuationToken)}: {requestContinuationToken}: {topContinuationToken.SourceToken} was malformed.")));
                    }
                }
                else
                {
                    sourceToken = null;
                }

                return((await tryCreateSourceAsync(sourceToken))
                       .Try <IDocumentQueryExecutionComponent>((source) => new ClientTakeDocumentQueryExecutionComponent(
                                                                   source,
                                                                   topContinuationToken.Top,
                                                                   TakeEnum.Top)));
            }
            public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateAsync(
                int offsetCount,
                CosmosElement continuationToken,
                Func <CosmosElement, Task <TryCatch <IDocumentQueryExecutionComponent> > > tryCreateSourceAsync)
            {
                if (tryCreateSourceAsync == null)
                {
                    throw new ArgumentNullException(nameof(tryCreateSourceAsync));
                }

                OffsetContinuationToken offsetContinuationToken;

                if (continuationToken != null)
                {
                    if (!OffsetContinuationToken.TryParse(continuationToken.ToString(), out offsetContinuationToken))
                    {
                        return(TryCatch <IDocumentQueryExecutionComponent> .FromException(
                                   new MalformedContinuationTokenException($"Invalid {nameof(SkipDocumentQueryExecutionComponent)}: {continuationToken}.")));
                    }
                }
                else
                {
                    offsetContinuationToken = new OffsetContinuationToken(offsetCount, null);
                }

                if (offsetContinuationToken.Offset > offsetCount)
                {
                    return(TryCatch <IDocumentQueryExecutionComponent> .FromException(
                               new MalformedContinuationTokenException("offset count in continuation token can not be greater than the offsetcount in the query.")));
                }

                CosmosElement sourceToken;

                if (offsetContinuationToken.SourceToken != null)
                {
                    TryCatch <CosmosElement> tryParse = CosmosElement.Monadic.Parse(offsetContinuationToken.SourceToken);
                    if (tryParse.Failed)
                    {
                        return(TryCatch <IDocumentQueryExecutionComponent> .FromException(
                                   new MalformedContinuationTokenException(
                                       message : $"source token: '{offsetContinuationToken.SourceToken ?? "<null>"}' is not valid.",
                                       innerException : tryParse.Exception)));
                    }

                    sourceToken = tryParse.Result;
                }
                else
                {
                    sourceToken = null;
                }

                return((await tryCreateSourceAsync(sourceToken))
                       .Try <IDocumentQueryExecutionComponent>((source) => new ClientSkipDocumentQueryExecutionComponent(
                                                                   source,
                                                                   offsetContinuationToken.Offset)));
            }
Esempio n. 7
0
            public static TryCatch <IQueryPipelineStage> MonadicCreate(
                int offsetCount,
                CosmosElement continuationToken,
                CancellationToken cancellationToken,
                MonadicCreatePipelineStage monadicCreatePipelineStage)
            {
                if (monadicCreatePipelineStage == null)
                {
                    throw new ArgumentNullException(nameof(monadicCreatePipelineStage));
                }

                OffsetContinuationToken offsetContinuationToken;

                if (continuationToken != null)
                {
                    if (!OffsetContinuationToken.TryParse(continuationToken.ToString(), out offsetContinuationToken))
                    {
                        return(TryCatch <IQueryPipelineStage> .FromException(
                                   new MalformedContinuationTokenException(
                                       $"Invalid {nameof(SkipQueryPipelineStage)}: {continuationToken}.")));
                    }
                }
                else
                {
                    offsetContinuationToken = new OffsetContinuationToken(offsetCount, null);
                }

                if (offsetContinuationToken.Offset > offsetCount)
                {
                    return(TryCatch <IQueryPipelineStage> .FromException(
                               new MalformedContinuationTokenException(
                                   "offset count in continuation token can not be greater than the offsetcount in the query.")));
                }

                CosmosElement sourceToken;

                if (offsetContinuationToken.SourceToken != null)
                {
                    TryCatch <CosmosElement> tryParse = CosmosElement.Monadic.Parse(offsetContinuationToken.SourceToken);
                    if (tryParse.Failed)
                    {
                        return(TryCatch <IQueryPipelineStage> .FromException(
                                   new MalformedContinuationTokenException(
                                       message : $"source token: '{offsetContinuationToken.SourceToken ?? "<null>"}' is not valid.",
                                       innerException : tryParse.Exception)));
                    }

                    sourceToken = tryParse.Result;
                }
                else
                {
                    sourceToken = null;
                }

                TryCatch <IQueryPipelineStage> tryCreateSource = monadicCreatePipelineStage(sourceToken, cancellationToken);

                if (tryCreateSource.Failed)
                {
                    return(tryCreateSource);
                }

                IQueryPipelineStage stage = new ClientSkipQueryPipelineStage(
                    tryCreateSource.Result,
                    cancellationToken,
                    offsetContinuationToken.Offset);

                return(TryCatch <IQueryPipelineStage> .FromResult(stage));
            }
Esempio n. 8
0
 internal Input(CosmosElement cosmosElement)
     : base(description: cosmosElement.ToString())
 {
     this.CosmosElement = cosmosElement;
 }
            public static TryCatch <IQueryPipelineStage> MonadicCreateLimitStage(
                int limitCount,
                CosmosElement requestContinuationToken,
                CancellationToken cancellationToken,
                MonadicCreatePipelineStage monadicCreatePipelineStage)
            {
                if (limitCount < 0)
                {
                    throw new ArgumentException($"{nameof(limitCount)}: {limitCount} must be a non negative number.");
                }

                if (monadicCreatePipelineStage == null)
                {
                    throw new ArgumentNullException(nameof(monadicCreatePipelineStage));
                }

                LimitContinuationToken limitContinuationToken;

                if (requestContinuationToken != null)
                {
                    if (!LimitContinuationToken.TryParse(requestContinuationToken.ToString(), out limitContinuationToken))
                    {
                        return(TryCatch <IQueryPipelineStage> .FromException(
                                   new MalformedContinuationTokenException(
                                       $"Malformed {nameof(LimitContinuationToken)}: {requestContinuationToken}.")));
                    }
                }
                else
                {
                    limitContinuationToken = new LimitContinuationToken(limitCount, null);
                }

                if (limitContinuationToken.Limit > limitCount)
                {
                    return(TryCatch <IQueryPipelineStage> .FromException(
                               new MalformedContinuationTokenException(
                                   $"{nameof(LimitContinuationToken.Limit)} in {nameof(LimitContinuationToken)}: {requestContinuationToken}: {limitContinuationToken.Limit} can not be greater than the limit count in the query: {limitCount}.")));
                }

                CosmosElement sourceToken;

                if (limitContinuationToken.SourceToken != null)
                {
                    TryCatch <CosmosElement> tryParse = CosmosElement.Monadic.Parse(limitContinuationToken.SourceToken);
                    if (tryParse.Failed)
                    {
                        return(TryCatch <IQueryPipelineStage> .FromException(
                                   new MalformedContinuationTokenException(
                                       message : $"Malformed {nameof(LimitContinuationToken)}: {requestContinuationToken}.",
                                       innerException : tryParse.Exception)));
                    }

                    sourceToken = tryParse.Result;
                }
                else
                {
                    sourceToken = null;
                }

                TryCatch <IQueryPipelineStage> tryCreateSource = monadicCreatePipelineStage(sourceToken, cancellationToken);

                if (tryCreateSource.Failed)
                {
                    return(tryCreateSource);
                }

                IQueryPipelineStage stage = new ClientTakeQueryPipelineStage(
                    tryCreateSource.Result,
                    cancellationToken,
                    limitContinuationToken.Limit,
                    TakeEnum.Limit);

                return(TryCatch <IQueryPipelineStage> .FromResult(stage));
            }
Esempio n. 10
0
            public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateLimitDocumentQueryExecutionComponentAsync(
                int limitCount,
                CosmosElement requestContinuationToken,
                Func <CosmosElement, Task <TryCatch <IDocumentQueryExecutionComponent> > > tryCreateSourceAsync)
            {
                if (limitCount < 0)
                {
                    throw new ArgumentException($"{nameof(limitCount)}: {limitCount} must be a non negative number.");
                }

                if (tryCreateSourceAsync == null)
                {
                    throw new ArgumentNullException(nameof(tryCreateSourceAsync));
                }

                LimitContinuationToken limitContinuationToken;

                if (requestContinuationToken != null)
                {
                    if (!LimitContinuationToken.TryParse(requestContinuationToken.ToString(), out limitContinuationToken))
                    {
                        return(TryCatch <IDocumentQueryExecutionComponent> .FromException(
                                   new MalformedContinuationTokenException($"Malformed {nameof(LimitContinuationToken)}: {requestContinuationToken}.")));
                    }
                }
                else
                {
                    limitContinuationToken = new LimitContinuationToken(limitCount, null);
                }

                if (limitContinuationToken.Limit > limitCount)
                {
                    return(TryCatch <IDocumentQueryExecutionComponent> .FromException(
                               new MalformedContinuationTokenException($"{nameof(LimitContinuationToken.Limit)} in {nameof(LimitContinuationToken)}: {requestContinuationToken}: {limitContinuationToken.Limit} can not be greater than the limit count in the query: {limitCount}.")));
                }

                CosmosElement sourceToken;

                if (limitContinuationToken.SourceToken != null)
                {
                    TryCatch <CosmosElement> tryParse = CosmosElement.Monadic.Parse(limitContinuationToken.SourceToken);
                    if (tryParse.Failed)
                    {
                        return(TryCatch <IDocumentQueryExecutionComponent> .FromException(
                                   new MalformedContinuationTokenException(
                                       message : $"Malformed {nameof(LimitContinuationToken)}: {requestContinuationToken}.",
                                       innerException : tryParse.Exception)));
                    }

                    sourceToken = tryParse.Result;
                }
                else
                {
                    sourceToken = null;
                }

                return((await tryCreateSourceAsync(sourceToken))
                       .Try <IDocumentQueryExecutionComponent>((source) => new ClientTakeDocumentQueryExecutionComponent(
                                                                   source,
                                                                   limitContinuationToken.Limit,
                                                                   TakeEnum.Limit)));
            }