Example #1
0
        internal async Task <IEnumerable <string> > GetChangeFeedTokensAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            Routing.PartitionKeyRangeCache pkRangeCache = await this.ClientContext.DocumentClient.GetPartitionKeyRangeCacheAsync();

            string containerRid = await this.GetRIDAsync(cancellationToken);

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

            return(allRanges.Select(e => StandByFeedContinuationToken.CreateForRange(containerRid, e.MinInclusive, e.MaxExclusive)));
        }
Example #2
0
        public async Task ConstructorWithInvalidTokenFormat()
        {
            IReadOnlyList <Documents.PartitionKeyRange> keyRanges = new List <Documents.PartitionKeyRange>()
            {
                new Documents.PartitionKeyRange()
                {
                    MinInclusive = "A", MaxExclusive = "B", Id = "0"
                },
                new Documents.PartitionKeyRange()
                {
                    MinInclusive = "C", MaxExclusive = "D", Id = "1"
                },
            };

            StandByFeedContinuationToken token = await StandByFeedContinuationToken.CreateAsync("containerRid", "notatoken", CreateCacheFromRange(keyRanges));

            await token.GetCurrentTokenAsync();
        }
Example #3
0
            internal CosmosChangeFeedResultSetIteratorCoreMock(
                ContainerCore container,
                string continuationToken,
                int?maxItemCount,
                ChangeFeedRequestOptions options) : base(
                    clientContext: container.ClientContext,
                    container: container,
                    continuationToken: continuationToken,
                    maxItemCount: maxItemCount,
                    options: options)
            {
                List <CompositeContinuationToken> compositeContinuationTokens = new List <CompositeContinuationToken>()
                {
                    new CompositeContinuationToken()
                    {
                        Token = null,
                        Range = new Documents.Routing.Range <string>("A", "B", true, false)
                    }
                };

                string serialized = JsonConvert.SerializeObject(compositeContinuationTokens);

                this.compositeContinuationToken = StandByFeedContinuationToken.CreateAsync("containerRid", serialized, (string containerRid, Documents.Routing.Range <string> ranges, bool forceRefresh) =>
                {
                    IReadOnlyList <Documents.PartitionKeyRange> filteredRanges = new List <Documents.PartitionKeyRange>()
                    {
                        new Documents.PartitionKeyRange()
                        {
                            MinInclusive = "A", MaxExclusive = "B", Id = "0"
                        }
                    };

                    if (forceRefresh)
                    {
                        this.HasCalledForceRefresh = true;
                    }

                    return(Task.FromResult(filteredRanges));
                }).Result;
            }
Example #4
0
        public async Task EnsureInitialized_CreatesToken_WithInitialContinuation()
        {
            List <CompositeContinuationToken> compositeContinuationTokens = new List <CompositeContinuationToken>()
            {
                StandByFeedContinuationTokenTests.BuildTokenForRange("A", "B", "token1"),
                StandByFeedContinuationTokenTests.BuildTokenForRange("C", "D", "token2")
            };

            string initialToken = JsonConvert.SerializeObject(compositeContinuationTokens);

            IReadOnlyList <Documents.PartitionKeyRange> keyRanges = new List <Documents.PartitionKeyRange>()
            {
                new Documents.PartitionKeyRange()
                {
                    MinInclusive = "A", MaxExclusive = "B", Id = "0"
                },
                new Documents.PartitionKeyRange()
                {
                    MinInclusive = "C", MaxExclusive = "D", Id = "1"
                },
            };

            StandByFeedContinuationToken compositeToken = await StandByFeedContinuationToken.CreateAsync(StandByFeedContinuationTokenTests.ContainerRid, initialToken, CreateCacheFromRange(keyRanges));

            (CompositeContinuationToken token, string rangeId) = await compositeToken.GetCurrentTokenAsync();

            Assert.AreEqual(keyRanges[0].MinInclusive, token.Range.Min);
            Assert.AreEqual(keyRanges[0].MaxExclusive, token.Range.Max);
            Assert.AreEqual(keyRanges[0].Id, rangeId);
            Assert.AreEqual(compositeContinuationTokens[0].Token, token.Token);

            compositeToken.MoveToNextToken();
            (CompositeContinuationToken token2, string rangeId2) = await compositeToken.GetCurrentTokenAsync();

            Assert.AreEqual(keyRanges[1].MinInclusive, token2.Range.Min);
            Assert.AreEqual(keyRanges[1].MaxExclusive, token2.Range.Max);
            Assert.AreEqual(keyRanges[1].Id, rangeId2);
            Assert.AreEqual(compositeContinuationTokens[1].Token, token2.Token);
        }
Example #5
0
 public void ConstructorWithNullMaxRange()
 {
     StandByFeedContinuationToken.CreateForRange("containerRid", "", null);
 }
Example #6
0
 public async Task ConstructorWithNullDelegate()
 {
     await StandByFeedContinuationToken.CreateAsync("something", null, null);
 }
Example #7
0
 public async Task ConstructorWithNullContainer()
 {
     await StandByFeedContinuationToken.CreateAsync(null, null, null);
 }
Example #8
0
        internal async Task <(string, ResponseMessage)> ReadNextInternalAsync(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (this.compositeContinuationToken == null)
            {
                PartitionKeyRangeCache pkRangeCache = await this.clientContext.DocumentClient.GetPartitionKeyRangeCacheAsync();

                this.containerRid = await this.container.GetRIDAsync(cancellationToken);

                if (this.changeFeedOptions?.From is ChangeFeedRequestOptions.StartFromContinuation startFromContinuation)
                {
                    this.compositeContinuationToken = await StandByFeedContinuationToken.CreateAsync(
                        this.containerRid,
                        startFromContinuation.Continuation,
                        pkRangeCache.TryGetOverlappingRangesAsync);

                    (CompositeContinuationToken token, string id) = await this.compositeContinuationToken.GetCurrentTokenAsync();

                    if (token.Token != null)
                    {
                        this.changeFeedOptions.From = ChangeFeedRequestOptions.StartFrom.CreateFromContinuation(token.Token);
                    }
                    else
                    {
                        this.changeFeedOptions.From = ChangeFeedRequestOptions.StartFrom.CreateFromBeginning();
                    }
                }
                else
                {
                    this.compositeContinuationToken = await StandByFeedContinuationToken.CreateAsync(
                        this.containerRid,
                        initialStandByFeedContinuationToken : null,
                        pkRangeCache.TryGetOverlappingRangesAsync);
                }
            }

            (CompositeContinuationToken currentRangeToken, string rangeId) = await this.compositeContinuationToken.GetCurrentTokenAsync();

            if (currentRangeToken.Token != null)
            {
                this.changeFeedOptions.From = ChangeFeedRequestOptions.StartFrom.CreateFromContinuation(currentRangeToken.Token);
            }

            this.changeFeedOptions.FeedRange = new FeedRangePartitionKeyRange(rangeId);
            ResponseMessage response = await this.NextResultSetDelegateAsync(this.changeFeedOptions, cancellationToken);

            if (await this.ShouldRetryFailureAsync(response, cancellationToken))
            {
                return(await this.ReadNextInternalAsync(cancellationToken));
            }

            if (response.IsSuccessStatusCode ||
                response.StatusCode == HttpStatusCode.NotModified)
            {
                // Change Feed read uses Etag for continuation
                currentRangeToken.Token = response.Headers.ETag;
            }

            return(rangeId, response);
        }