public ChangeFeedIteratorCore(
            ContainerInternal container,
            ChangeFeedRequestOptions changeFeedRequestOptions)
        {
            this.container         = container ?? throw new ArgumentNullException(nameof(container));
            this.clientContext     = container.ClientContext;
            this.changeFeedOptions = changeFeedRequestOptions ?? new ChangeFeedRequestOptions();
            this.lazyContainerRid  = new AsyncLazy <TryCatch <string> >(valueFactory: (innerCancellationToken) =>
            {
                return(this.TryInitializeContainerRIdAsync(innerCancellationToken));
            });
            this.hasMoreResults = true;

            if (this.changeFeedOptions?.From is ChangeFeedRequestOptions.StartFromContinuation startFromContinuation)
            {
                if (!FeedRangeContinuation.TryParse(startFromContinuation.Continuation, out FeedRangeContinuation feedRangeContinuation))
                {
                    throw new ArgumentException(string.Format(ClientResources.FeedToken_UnknownFormat, startFromContinuation.Continuation));
                }

                this.FeedRangeContinuation       = feedRangeContinuation;
                this.changeFeedOptions.FeedRange = feedRangeContinuation.GetFeedRange();
                string continuationToken = feedRangeContinuation.GetContinuation();
                if (continuationToken != null)
                {
                    this.changeFeedOptions.From = ChangeFeedRequestOptions.StartFrom.CreateFromContinuation(continuationToken);
                }
                else
                {
                    this.changeFeedOptions.From = ChangeFeedRequestOptions.StartFrom.CreateFromBeginning();
                }
            }
        }
        public static ResponseMessage CreateSuccess(
            ResponseMessage responseMessage,
            FeedRangeContinuation feedRangeContinuation)
        {
            if (responseMessage == null)
            {
                throw new ArgumentNullException(nameof(responseMessage));
            }

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

            if (feedRangeContinuation.IsDone)
            {
                responseMessage.Headers.ContinuationToken = null;
            }
            else
            {
                responseMessage.Headers.ContinuationToken = feedRangeContinuation.ToString();
            }

            return(responseMessage);
        }
示例#3
0
        private async Task InitializeFeedContinuationAsync(CancellationToken cancellationToken)
        {
            Routing.PartitionKeyRangeCache partitionKeyRangeCache = await this.clientContext.DocumentClient.GetPartitionKeyRangeCacheAsync();

            List <Documents.Routing.Range <string> > ranges;

            if (this.FeedRangeInternal is FeedRangePartitionKey)
            {
                Documents.PartitionKeyDefinition partitionKeyDefinition = await this.container.GetPartitionKeyDefinitionAsync(cancellationToken);

                ranges = await this.FeedRangeInternal.GetEffectiveRangesAsync(partitionKeyRangeCache, this.lazyContainerRid.Result.Result, partitionKeyDefinition);
            }
            else
            {
                IReadOnlyList <Documents.PartitionKeyRange> pkRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync(
                    collectionRid : this.lazyContainerRid.Result.Result,
                    range : (this.FeedRangeInternal as FeedRangeEPK).Range,
                    forceRefresh : false);

                ranges = pkRanges.Select(pkRange => pkRange.ToRange()).ToList();
            }

            this.FeedRangeContinuation = new FeedRangeCompositeContinuation(
                containerRid: this.lazyContainerRid.Result.Result,
                feedRange: this.FeedRangeInternal,
                ranges: ranges);
        }
 internal ChangeFeedIteratorCore(
     ContainerInternal container,
     FeedRangeContinuation feedRangeContinuation,
     ChangeFeedRequestOptions changeFeedRequestOptions)
     : this(container, feedRangeContinuation.FeedRange, changeFeedRequestOptions)
 {
     this.FeedRangeContinuation = feedRangeContinuation ?? throw new ArgumentNullException(nameof(feedRangeContinuation));
 }
示例#5
0
 /// <summary>
 /// For unit tests
 /// </summary>
 internal FeedRangeIteratorCore(
     ContainerCore containerCore,
     FeedRangeContinuation feedRangeContinuation,
     QueryRequestOptions options)
     : this(containerCore, feedRangeContinuation.FeedRange, options)
 {
     this.FeedRangeContinuation = feedRangeContinuation;
 }
示例#6
0
 /// <summary>
 /// For unit tests
 /// </summary>
 internal FeedRangeIteratorCore(
     ContainerInternal containerCore,
     FeedRangeContinuation feedRangeContinuation,
     QueryRequestOptions options,
     ResourceType resourceType,
     QueryDefinition queryDefinition)
     : this(containerCore, feedRangeContinuation.FeedRange, options, resourceType, queryDefinition)
 {
     this.FeedRangeContinuation = feedRangeContinuation;
 }
        public static bool TryParse(
            string toStringValue,
            out FeedRangeContinuation parsedToken)
        {
            if (!FeedRangeCompositeContinuation.TryParse(toStringValue, out parsedToken))
            {
                parsedToken = null;
                return(false);
            }

            return(true);
        }
示例#8
0
 public static new bool TryParse(string toStringValue, out FeedRangeContinuation feedToken)
 {
     try
     {
         feedToken = JsonConvert.DeserializeObject <FeedRangeCompositeContinuation>(toStringValue);
         return(true);
     }
     catch (JsonReaderException)
     {
         feedToken = null;
         return(false);
     }
 }
        private async Task InitializeFeedContinuationAsync(CancellationToken cancellationToken)
        {
            Routing.PartitionKeyRangeCache partitionKeyRangeCache = await this.clientContext.DocumentClient.GetPartitionKeyRangeCacheAsync();
            List<Documents.Routing.Range<string>> effectiveRanges = await this.FeedRangeInternal.GetEffectiveRangesAsync(
                routingMapProvider: partitionKeyRangeCache,
                containerRid: this.lazyContainerRid.Result.Result,
                partitionKeyDefinition: null);

            this.FeedRangeContinuation = new FeedRangeCompositeContinuation(
                containerRid: this.lazyContainerRid.Result.Result,
                feedRange: this.FeedRangeInternal,
                effectiveRanges);
        }
        private async Task InitializeFeedContinuationAsync(CancellationToken cancellationToken)
        {
            if (this.FeedRangeContinuation == null)
            {
                Routing.PartitionKeyRangeCache partitionKeyRangeCache = await this.clientContext.DocumentClient.GetPartitionKeyRangeCacheAsync();

                List <Documents.Routing.Range <string> > ranges;
                if (this.FeedRangeInternal is FeedRangePartitionKey)
                {
                    PartitionKeyDefinition partitionKeyDefinition = await this.container.GetPartitionKeyDefinitionAsync(cancellationToken);

                    ranges = await this.FeedRangeInternal.GetEffectiveRangesAsync(partitionKeyRangeCache, this.lazyContainerRid.Result.Result, partitionKeyDefinition);
                }
                else
                {
                    IReadOnlyList <PartitionKeyRange> pkRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync(
                        collectionRid : this.lazyContainerRid.Result.Result,
                        range : (this.FeedRangeInternal as FeedRangeEPK).Range,
                        forceRefresh : false);

                    ranges = pkRanges.Select(pkRange => pkRange.ToRange()).ToList();
                }

                this.FeedRangeContinuation = new FeedRangeCompositeContinuation(
                    containerRid: this.lazyContainerRid.Result.Result,
                    feedRange: this.FeedRangeInternal,
                    ranges: ranges);
            }
            else if (this.FeedRangeInternal is FeedRangePartitionKeyRange)
            {
                // Migration from PKRangeId scenario
                Routing.PartitionKeyRangeCache partitionKeyRangeCache = await this.clientContext.DocumentClient.GetPartitionKeyRangeCacheAsync();

                List <Documents.Routing.Range <string> > effectiveRanges = await this.FeedRangeInternal.GetEffectiveRangesAsync(
                    routingMapProvider : partitionKeyRangeCache,
                    containerRid : this.lazyContainerRid.Result.Result,
                    partitionKeyDefinition : null);

                // Override the original PKRangeId based FeedRange
                this.FeedRangeInternal     = new FeedRangeEPK(effectiveRanges[0]);
                this.FeedRangeContinuation = new FeedRangeCompositeContinuation(
                    containerRid: this.lazyContainerRid.Result.Result,
                    feedRange: this.FeedRangeInternal,
                    ranges: effectiveRanges,
                    continuation: this.FeedRangeContinuation.GetContinuation());
            }
        }
示例#11
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;
        }