コード例 #1
0
        public FeedRangeCompositeContinuation(
            string containerRid,
            FeedRangeInternal feedRange,
            IReadOnlyList <Documents.Routing.Range <string> > ranges,
            string continuation = null)
            : this(containerRid, feedRange)
        {
            if (ranges == null)
            {
                throw new ArgumentNullException(nameof(ranges));
            }

            if (ranges.Count == 0)
            {
                throw new ArgumentOutOfRangeException(nameof(ranges));
            }

            foreach (Documents.Routing.Range <string> range in ranges)
            {
                this.CompositeContinuationTokens.Enqueue(
                    FeedRangeCompositeContinuation.CreateCompositeContinuationTokenForRange(
                        range.Min,
                        range.Max,
                        continuation));
            }

            this.CurrentToken = this.CompositeContinuationTokens.Peek();
        }
コード例 #2
0
        public static FeedRangeIteratorCore Create(
            ContainerCore containerCore,
            FeedRangeInternal feedRangeInternal,
            string continuation,
            QueryRequestOptions options)
        {
            if (!string.IsNullOrEmpty(continuation))
            {
                if (FeedRangeContinuation.TryParse(continuation, out FeedRangeContinuation feedRangeContinuation))
                {
                    return(new FeedRangeIteratorCore(containerCore, feedRangeContinuation, options));
                }

                // Backward compatible with old format
                feedRangeInternal     = FeedRangeEPK.ForCompleteRange();
                feedRangeContinuation = new FeedRangeCompositeContinuation(
                    string.Empty,
                    feedRangeInternal,
                    new List <Documents.Routing.Range <string> >()
                {
                    new Documents.Routing.Range <string>(
                        Documents.Routing.PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                        Documents.Routing.PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey,
                        isMinInclusive: true,
                        isMaxInclusive: false)
                },
                    continuation);
                return(new FeedRangeIteratorCore(containerCore, feedRangeContinuation, options));
            }

            feedRangeInternal = feedRangeInternal ?? FeedRangeEPK.ForCompleteRange();
            return(new FeedRangeIteratorCore(containerCore, feedRangeInternal, options));
        }
        public void Visit(FeedRangeCompositeContinuation feedRangeCompositeContinuation)
        {
            // In case EPK has already been set by compute
            if (!this.request.Properties.ContainsKey(HandlerConstants.StartEpkString))
            {
                this.request.Properties[HandlerConstants.StartEpkString] = feedRangeCompositeContinuation.CurrentToken.Range.Min;
                this.request.Properties[HandlerConstants.EndEpkString]   = feedRangeCompositeContinuation.CurrentToken.Range.Max;
            }

            this.fillContinuation(this.request, feedRangeCompositeContinuation.GetContinuation());
        }
コード例 #4
0
        public static bool TryParse(
            string toStringValue,
            out FeedRangeContinuation parsedToken)
        {
            if (!FeedRangeCompositeContinuation.TryParse(toStringValue, out parsedToken))
            {
                parsedToken = null;
                return(false);
            }

            return(true);
        }
コード例 #5
0
        private void CreateChildRanges(IReadOnlyList <Documents.PartitionKeyRange> keyRanges)
        {
            if (keyRanges == null)
            {
                throw new ArgumentNullException(nameof(keyRanges));
            }

            // Update current
            Documents.PartitionKeyRange firstRange = keyRanges[0];
            this.CurrentToken.Range = new Documents.Routing.Range <string>(firstRange.MinInclusive, firstRange.MaxExclusive, true, false);
            // Add children
            foreach (Documents.PartitionKeyRange keyRange in keyRanges.Skip(1))
            {
                this.CompositeContinuationTokens.Enqueue(
                    FeedRangeCompositeContinuation.CreateCompositeContinuationTokenForRange(
                        keyRange.MinInclusive,
                        keyRange.MaxExclusive,
                        this.CurrentToken.Token));
            }
        }
コード例 #6
0
 private void CreateChildRanges(IReadOnlyList <Documents.PartitionKeyRange> keyRanges)
 {
     if (keyRanges == null)
     {
         throw new ArgumentNullException(nameof(keyRanges));
     }
     // Update current
     Documents.PartitionKeyRange firstRange = keyRanges[0];
     this.CurrentToken.Range = new Documents.Routing.Range <string>(firstRange.MinInclusive, firstRange.MaxExclusive, true, false);
     if (FeedRangeCompositeContinuation.TryParseAsCompositeContinuationToken(
             this.CurrentToken.Token,
             out CompositeContinuationToken continuationAsComposite))
     {
         // Update the internal composite continuation
         continuationAsComposite.Range = this.CurrentToken.Range;
         this.CurrentToken.Token       = JsonConvert.SerializeObject(continuationAsComposite);
         // Add children
         foreach (Documents.PartitionKeyRange keyRange in keyRanges.Skip(1))
         {
             continuationAsComposite.Range = keyRange.ToRange();
             this.CompositeContinuationTokens.Enqueue(
                 FeedRangeCompositeContinuation.CreateCompositeContinuationTokenForRange(
                     keyRange.MinInclusive,
                     keyRange.MaxExclusive,
                     JsonConvert.SerializeObject(continuationAsComposite)));
         }
     }
     else
     {
         // Add children
         foreach (Documents.PartitionKeyRange keyRange in keyRanges.Skip(1))
         {
             this.CompositeContinuationTokens.Enqueue(
                 FeedRangeCompositeContinuation.CreateCompositeContinuationTokenForRange(
                     keyRange.MinInclusive,
                     keyRange.MaxExclusive,
                     this.CurrentToken.Token));
         }
     }
 }
コード例 #7
0
        /// <summary>
        /// Get the next set of results from the cosmos service
        /// </summary>
        /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param>
        /// <returns>A query response from cosmos service</returns>
        public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (!this.hasMoreResults)
            {
                throw new InvalidOperationException("Should not be calling FeedIterator that does not have any more results");
            }

            if (this.monadicEnumerator.Failed)
            {
                this.hasMoreResults = false;

                CosmosException cosmosException = ExceptionToCosmosException.CreateFromException(this.monadicEnumerator.Exception);
                return(new ResponseMessage(
                           statusCode: System.Net.HttpStatusCode.BadRequest,
                           requestMessage: null,
                           headers: cosmosException.Headers,
                           cosmosException: cosmosException,
                           diagnostics: cosmosException.DiagnosticsContext));
            }

            CrossPartitionReadFeedAsyncEnumerator enumerator = this.monadicEnumerator.Result;
            TryCatch <ReadFeedPage> monadicPage;

            try
            {
                if (!await enumerator.MoveNextAsync())
                {
                    throw new InvalidOperationException("Should not be calling enumerator that does not have any more results");
                }

                monadicPage = enumerator.Current;
            }
            catch (Exception ex)
            {
                monadicPage = TryCatch <ReadFeedPage> .FromException(ex);
            }

            if (monadicPage.Failed)
            {
                CosmosException cosmosException = ExceptionToCosmosException.CreateFromException(monadicPage.Exception);
                if (!IsRetriableException(cosmosException))
                {
                    this.hasMoreResults = false;
                }

                return(new ResponseMessage(
                           statusCode: cosmosException.StatusCode,
                           requestMessage: null,
                           headers: cosmosException.Headers,
                           cosmosException: cosmosException,
                           diagnostics: cosmosException.DiagnosticsContext));
            }

            ReadFeedPage readFeedPage = monadicPage.Result;

            if (readFeedPage.State == default)
            {
                this.hasMoreResults = false;
            }

            // Make the continuation token match the older format:
            string continuationToken;

            if (readFeedPage.State != null)
            {
                List <CompositeContinuationToken> compositeContinuationTokens = new List <CompositeContinuationToken>();
                CosmosArray compositeContinuationTokensCosmosArray            = (CosmosArray)readFeedPage.State.ContinuationToken;
                foreach (CosmosElement arrayItem in compositeContinuationTokensCosmosArray)
                {
                    ReadFeedContinuationToken readFeedContinuationToken = ReadFeedContinuationToken.MonadicConvertFromCosmosElement(arrayItem).Result;
                    FeedRangeEpk  feedRangeEpk  = (FeedRangeEpk)readFeedContinuationToken.Range;
                    ReadFeedState readFeedState = readFeedContinuationToken.State;
                    CompositeContinuationToken compositeContinuationToken = new CompositeContinuationToken()
                    {
                        Range = feedRangeEpk.Range,
                        Token = readFeedState.ContinuationToken.ToString(),
                    };

                    compositeContinuationTokens.Add(compositeContinuationToken);
                }

                FeedRangeCompositeContinuation feedRangeCompositeContinuation = new FeedRangeCompositeContinuation(
                    containerRid: string.Empty,
                    feedRange: FeedRangeEpk.FullRange,
                    compositeContinuationTokens);

                continuationToken = feedRangeCompositeContinuation.ToString();
            }
            else
            {
                continuationToken = null;
            }

            return(new ResponseMessage(
                       statusCode: System.Net.HttpStatusCode.OK,
                       requestMessage: default,
コード例 #8
0
        public ReadFeedIteratorCore(
            IDocumentContainer documentContainer,
            QueryRequestOptions queryRequestOptions,
            string continuationToken,
            int pageSize,
            CancellationToken cancellationToken)
        {
            if (!string.IsNullOrEmpty(continuationToken))
            {
                bool isNewArrayFormat = (continuationToken.Length >= 2) && (continuationToken[0] == '[') && (continuationToken[continuationToken.Length - 1] == ']');
                if (!isNewArrayFormat)
                {
                    // One of the two older formats
                    if (!FeedRangeContinuation.TryParse(continuationToken, out FeedRangeContinuation feedRangeContinuation))
                    {
                        // Backward compatible with old format
                        feedRangeContinuation = new FeedRangeCompositeContinuation(
                            containerRid: string.Empty,
                            FeedRangeEpk.FullRange,
                            new List <Documents.Routing.Range <string> >()
                        {
                            new Documents.Routing.Range <string>(
                                Documents.Routing.PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                                Documents.Routing.PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey,
                                isMinInclusive: true,
                                isMaxInclusive: false)
                        },
                            continuationToken);
                    }

                    // need to massage it a little
                    string       oldContinuationFormat = feedRangeContinuation.ToString();
                    CosmosObject cosmosObject          = CosmosObject.Parse(oldContinuationFormat);
                    CosmosArray  continuations         = (CosmosArray)cosmosObject["Continuation"];

                    List <CosmosElement> readFeedContinuationTokens = new List <CosmosElement>();
                    foreach (CosmosElement continuation in continuations)
                    {
                        CosmosObject  continuationObject = (CosmosObject)continuation;
                        CosmosObject  rangeObject        = (CosmosObject)continuationObject["range"];
                        string        min   = ((CosmosString)rangeObject["min"]).Value;
                        string        max   = ((CosmosString)rangeObject["max"]).Value;
                        CosmosElement token = CosmosElement.Parse(((CosmosString)continuationObject["token"]).Value);

                        FeedRangeInternal         feedRange = new FeedRangeEpk(new Documents.Routing.Range <string>(min, max, isMinInclusive: true, isMaxInclusive: false));
                        ReadFeedState             state     = new ReadFeedState(token);
                        ReadFeedContinuationToken readFeedContinuationToken = new ReadFeedContinuationToken(feedRange, state);
                        readFeedContinuationTokens.Add(ReadFeedContinuationToken.ToCosmosElement(readFeedContinuationToken));
                    }

                    CosmosArray cosmosArrayContinuationTokens = CosmosArray.Create(readFeedContinuationTokens);
                    continuationToken = cosmosArrayContinuationTokens.ToString();
                }
            }

            this.monadicEnumerator = CrossPartitionReadFeedAsyncEnumerator.MonadicCreate(
                documentContainer,
                queryRequestOptions,
                continuationToken: continuationToken,
                pageSize,
                cancellationToken);

            this.hasMoreResults = true;
        }