[Ignore] /* Buffer cannot be null */
        public async Task TestAddFormattedContinuationToHeader()
        {
            using (Stream stream = new MemoryStream(Properties.Resources.BaselineTest_PartitionRoutingHelper_AddFormattedContinuationToHeader))
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    AddFormattedContinuationToHeaderTestData testData = JsonConvert.DeserializeObject <AddFormattedContinuationToHeaderTestData>(reader.ReadToEnd());

                    CollectionRoutingMap routingMap =
                        CollectionRoutingMap.TryCreateCompleteRoutingMap(
                            testData.RoutingMap.Select(range => Tuple.Create(range, (ServiceIdentity)null)), string.Empty);
                    RoutingMapProvider routingMapProvider = new RoutingMapProvider(routingMap);

                    foreach (AddFormattedContinuationToHeaderTestUnit positiveTestData in testData.TestSet.Postive)
                    {
                        INameValueCollection headers;
                        List <CompositeContinuationToken> resolvedContinuationTokens;
                        List <PartitionKeyRange>          resolvedRanges;

                        this.AddFormattedContinuationHeaderHelper(positiveTestData, out headers, out resolvedRanges, out resolvedContinuationTokens);

                        bool answer = await this.partitionRoutingHelper.TryAddPartitionKeyRangeToContinuationTokenAsync(headers, positiveTestData.ProvidedRanges, routingMapProvider, null, new PartitionRoutingHelper.ResolvedRangeInfo(resolvedRanges[0], (resolvedContinuationTokens.Count > 0) ? resolvedContinuationTokens : null));

                        Assert.AreEqual(positiveTestData.OutputCompositeContinuationToken, headers[HttpConstants.HttpHeaders.Continuation]);
                    }

                    foreach (AddFormattedContinuationToHeaderTestUnit negativeTestData in testData.TestSet.Negative)
                    {
                        try
                        {
                            INameValueCollection headers;
                            List <CompositeContinuationToken> resolvedContinuationTokens;
                            List <PartitionKeyRange>          resolvedRanges;

                            this.AddFormattedContinuationHeaderHelper(negativeTestData, out headers, out resolvedRanges, out resolvedContinuationTokens);

                            bool answer = await this.partitionRoutingHelper.TryAddPartitionKeyRangeToContinuationTokenAsync(headers, negativeTestData.ProvidedRanges, routingMapProvider, null, new PartitionRoutingHelper.ResolvedRangeInfo(resolvedRanges[0], (resolvedContinuationTokens.Count > 0) ? resolvedContinuationTokens : null));

                            Assert.Fail("Expect BadRequestException");
                        }
                        catch (BadRequestException)
                        {
                        }
                        catch (InternalServerErrorException)
                        {
                        }
                    }
                }
            }
        }
        public async Task TestGetPartitionRoutingInfo()
        {
            using (Stream stream = new MemoryStream(Properties.Resources.BaselineTest_PartitionRoutingHelper_GetPartitionRoutingInfo))
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    GetPartitionRoutingInfoTestData testData = JsonConvert.DeserializeObject <GetPartitionRoutingInfoTestData>(reader.ReadToEnd());

                    CollectionRoutingMap routingMap =
                        CollectionRoutingMap.TryCreateCompleteRoutingMap(
                            testData.RoutingMap.Select(range => Tuple.Create(range, (ServiceIdentity)null)), string.Empty);

                    foreach (GetPartitionRoutingInfoTestCase testCase in testData.TestCases)
                    {
                        List <string> actualPartitionKeyRangeIds = new List <string>();

                        Range <string> startRange = Range <string> .GetEmptyRange(PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey);

                        for (Range <string> currentRange = startRange; currentRange != null;)
                        {
                            RoutingMapProvider routingMapProvider = new RoutingMapProvider(routingMap);
                            PartitionRoutingHelper.ResolvedRangeInfo resolvedRangeInfo = await this.partitionRoutingHelper.TryGetTargetRangeFromContinuationTokenRangeAsync(testCase.ProvidedRanges, routingMapProvider, string.Empty, currentRange, null);

                            actualPartitionKeyRangeIds.Add(resolvedRangeInfo.ResolvedRange.Id);
                            INameValueCollection headers = new DictionaryNameValueCollection();

                            await this.partitionRoutingHelper.TryAddPartitionKeyRangeToContinuationTokenAsync(headers, testCase.ProvidedRanges, routingMapProvider, string.Empty, resolvedRangeInfo);

                            List <CompositeContinuationToken> suppliedTokens;
                            Range <string> nextRange = this.partitionRoutingHelper.ExtractPartitionKeyRangeFromContinuationToken(headers, out suppliedTokens);
                            currentRange = nextRange.IsEmpty ? null : nextRange;
                        }

                        Assert.AreEqual(string.Join(", ", testCase.RoutingRangeIds), string.Join(", ", actualPartitionKeyRangeIds));
                    }
                }
            }
        }
示例#3
0
        private async Task <CollectionRoutingMap> GetRoutingMapForCollectionAsync(
            string collectionRid,
            CollectionRoutingMap previousRoutingMap,
            ITrace trace,
            IClientSideRequestStatistics clientSideRequestStatistics,
            CancellationToken cancellationToken)
        {
            List <PartitionKeyRange> ranges  = new List <PartitionKeyRange>();
            string changeFeedNextIfNoneMatch = previousRoutingMap == null ? null : previousRoutingMap.ChangeFeedNextIfNoneMatch;

            HttpStatusCode lastStatusCode = HttpStatusCode.OK;

            do
            {
                INameValueCollection headers = new StoreRequestNameValueCollection();

                headers.Set(HttpConstants.HttpHeaders.PageSize, PageSizeString);
                headers.Set(HttpConstants.HttpHeaders.A_IM, HttpConstants.A_IMHeaderValues.IncrementalFeed);
                if (changeFeedNextIfNoneMatch != null)
                {
                    headers.Set(HttpConstants.HttpHeaders.IfNoneMatch, changeFeedNextIfNoneMatch);
                }

                RetryOptions retryOptions = new RetryOptions();
                using (DocumentServiceResponse response = await BackoffRetryUtility <DocumentServiceResponse> .ExecuteAsync(
                           () => this.ExecutePartitionKeyRangeReadChangeFeedAsync(collectionRid, headers, trace, clientSideRequestStatistics),
                           new ResourceThrottleRetryPolicy(retryOptions.MaxRetryAttemptsOnThrottledRequests, retryOptions.MaxRetryWaitTimeInSeconds),
                           cancellationToken))
                {
                    lastStatusCode            = response.StatusCode;
                    changeFeedNextIfNoneMatch = response.Headers[HttpConstants.HttpHeaders.ETag];

                    FeedResource <PartitionKeyRange> feedResource = response.GetResource <FeedResource <PartitionKeyRange> >();
                    if (feedResource != null)
                    {
                        ranges.AddRange(feedResource);
                    }
                }
            }while (lastStatusCode != HttpStatusCode.NotModified);

            IEnumerable <Tuple <PartitionKeyRange, ServiceIdentity> > tuples = ranges.Select(range => Tuple.Create(range, (ServiceIdentity)null));

            CollectionRoutingMap routingMap;

            if (previousRoutingMap == null)
            {
                // Splits could have happened during change feed query and we might have a mix of gone and new ranges.
                HashSet <string> goneRanges = new HashSet <string>(ranges.SelectMany(range => range.Parents ?? Enumerable.Empty <string>()));
                routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap(
                    tuples.Where(tuple => !goneRanges.Contains(tuple.Item1.Id)),
                    string.Empty,
                    changeFeedNextIfNoneMatch);
            }
            else
            {
                routingMap = previousRoutingMap.TryCombine(tuples, changeFeedNextIfNoneMatch);
            }

            if (routingMap == null)
            {
                // Range information either doesn't exist or is not complete.
                throw new NotFoundException($"{DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)}: GetRoutingMapForCollectionAsync(collectionRid: {collectionRid}), Range information either doesn't exist or is not complete.");
            }

            return(routingMap);
        }
示例#4
0
 public MockRoutingMapProvider(IList <PartitionKeyRange> ranges)
 {
     this.routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap(ranges.Select(r => Tuple.Create(r, (ServiceIdentity)null)), "");
 }