private async Task<TryCatch<FeedTokenInternal>> TryInitializeFeedTokenAsync(CancellationToken cancellationToken)
        {
            string containerRId = string.Empty;
            if (this.containerCore != null)
            {
                try
                {
                    containerRId = await this.containerCore.GetRIDAsync(cancellationToken);
                }
                catch (Exception cosmosException)
                {
                    return TryCatch<FeedTokenInternal>.FromException(cosmosException);
                }
            }

            // Create FeedToken for the full Range
            FeedTokenEPKRange feedTokenInternal = new FeedTokenEPKRange(
                containerRId,
                new PartitionKeyRange()
                {
                    MinInclusive = Documents.Routing.PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                    MaxExclusive = Documents.Routing.PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey
                });
            // Initialize with the ContinuationToken that the user passed, if any
            if (this.ContinuationToken != null)
            {
                feedTokenInternal.UpdateContinuation(this.ContinuationToken);
            }

            return TryCatch<FeedTokenInternal>.FromResult(feedTokenInternal);
        }
        public FeedTokenEPKRange(
            string containerRid,
            Documents.PartitionKeyRange keyRange)
            : this(containerRid)
        {
            if (keyRange == null)
            {
                throw new ArgumentNullException(nameof(keyRange));
            }

            this.CompleteRange = new Documents.Routing.Range <string>(keyRange.MinInclusive, keyRange.MaxExclusive, true, false);
            this.CompositeContinuationTokens.Enqueue(FeedTokenEPKRange.CreateCompositeContinuationTokenForRange(keyRange.MinInclusive, keyRange.MaxExclusive, null));

            this.currentToken = this.CompositeContinuationTokens.Peek();
        }
        public override async Task <bool> ShouldRetryAsync(
            ContainerCore containerCore,
            ResponseMessage responseMessage,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (this.FeedTokenEPKRange != null)
            {
                return(await this.FeedTokenEPKRange.ShouldRetryAsync(containerCore, responseMessage, cancellationToken));
            }

            if (responseMessage.IsSuccessStatusCode)
            {
                return(false);
            }

            bool partitionSplit = responseMessage.StatusCode == HttpStatusCode.Gone &&
                                  (responseMessage.Headers.SubStatusCode == Documents.SubStatusCodes.PartitionKeyRangeGone || responseMessage.Headers.SubStatusCode == Documents.SubStatusCodes.CompletingSplit);

            if (partitionSplit)
            {
                string containerRid = await containerCore.GetRIDAsync(cancellationToken);

                Routing.PartitionKeyRangeCache partitionKeyRangeCache = await containerCore.ClientContext.DocumentClient.GetPartitionKeyRangeCacheAsync();

                IReadOnlyList <Documents.PartitionKeyRange> keyRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync(
                    containerRid,
                    new Documents.Routing.Range <string>(
                        Documents.Routing.PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                        Documents.Routing.PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey,
                        isMaxInclusive: false,
                        isMinInclusive: true),
                    forceRefresh : true);

                List <Documents.PartitionKeyRange> addedRanges = keyRanges.Where(range => range.Parents.Contains(this.PartitionKeyRangeId)).ToList();
                if (addedRanges.Count == 0)
                {
                    DefaultTrace.TraceError("FeedTokenPartitionKeyRange - Could not obtain children after split for {0}", this.PartitionKeyRangeId);
                    return(false);
                }

                this.FeedTokenEPKRange = new FeedTokenEPKRange(containerRid,
                                                               new Documents.Routing.Range <string>(addedRanges[0].MinInclusive, addedRanges[addedRanges.Count - 1].MaxExclusive, true, false),
                                                               addedRanges.Select(range => FeedTokenEPKRange.CreateCompositeContinuationTokenForRange(range.MinInclusive, range.MaxExclusive, this.continuationToken)).ToList());
                return(true);
            }

            return(false);
        }
        private void HandleSplit(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(FeedTokenEPKRange.CreateCompositeContinuationTokenForRange(keyRange.MinInclusive, keyRange.MaxExclusive, this.currentToken.Token));
            }
        }
        public static bool TryParse(
            string toStringValue,
            out FeedToken parsedToken)
        {
            if (FeedTokenEPKRange.TryParseInstance(toStringValue, out parsedToken))
            {
                return(true);
            }

            if (FeedTokenPartitionKey.TryParseInstance(toStringValue, out parsedToken))
            {
                return(true);
            }

            if (FeedTokenPartitionKeyRange.TryParseInstance(toStringValue, out parsedToken))
            {
                return(true);
            }

            parsedToken = null;
            return(false);
        }
        public FeedTokenEPKRange(
            string containerRid,
            IReadOnlyList <Documents.PartitionKeyRange> keyRanges)
            : this(containerRid)
        {
            if (keyRanges == null)
            {
                throw new ArgumentNullException(nameof(keyRanges));
            }

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

            this.CompleteRange = new Documents.Routing.Range <string>(keyRanges[0].MinInclusive, keyRanges[keyRanges.Count - 1].MaxExclusive, true, false);
            foreach (Documents.PartitionKeyRange keyRange in keyRanges)
            {
                this.CompositeContinuationTokens.Enqueue(FeedTokenEPKRange.CreateCompositeContinuationTokenForRange(keyRange.MinInclusive, keyRange.MaxExclusive, null));
            }

            this.currentToken = this.CompositeContinuationTokens.Peek();
        }