[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)); } } } }
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); }
public MockRoutingMapProvider(IList <PartitionKeyRange> ranges) { this.routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap(ranges.Select(r => Tuple.Create(r, (ServiceIdentity)null)), ""); }