internal ChangeFeedPartitionKeyResultSetIteratorCore( CosmosClientContext clientContext, ContainerCore container, string partitionKeyRangeId, string continuationToken, int?maxItemCount, ChangeFeedRequestOptions options) { if (container == null) { throw new ArgumentNullException(nameof(container)); } if (partitionKeyRangeId == null) { throw new ArgumentNullException(nameof(partitionKeyRangeId)); } this.clientContext = clientContext; this.container = container; this.changeFeedOptions = options; this.MaxItemCount = maxItemCount; this.continuationToken = continuationToken; this.partitionKeyRangeId = partitionKeyRangeId; this.feedToken = new FeedTokenPartitionKeyRange(this.partitionKeyRangeId); this.feedToken.UpdateContinuation(this.continuationToken); }
/// <summary> /// Creates a <see cref="FeedToken"/> from a previously serialized instance. /// </summary> /// <param name="toStringValue">A string representation obtained from <see cref="FeedToken.ToString()"/>.</param> /// <returns>A <see cref="FeedToken"/> instance.</returns> public static FeedToken FromString(string toStringValue) { if (FeedTokenInternal.TryParse(toStringValue, out FeedToken feedToken)) { return(feedToken); } throw new ArgumentOutOfRangeException(nameof(toStringValue), string.Format(ClientResources.FeedToken_CannotParse, toStringValue)); }
FeedIterator GetChangeFeedStreamIterator( FeedToken feedToken, ChangeFeedRequestOptions changeFeedRequestOptions = null) { FeedTokenInternal feedTokenInternal = feedToken as FeedTokenInternal; return(new ChangeFeedIteratorCore( this, feedTokenInternal, changeFeedRequestOptions)); }
FeedIterator <T> GetChangeFeedIterator <T>( FeedToken feedToken, ChangeFeedRequestOptions changeFeedRequestOptions = null) { FeedTokenInternal feedTokenInternal = feedToken as FeedTokenInternal; ChangeFeedIteratorCore changeFeedIteratorCore = new ChangeFeedIteratorCore( this, feedTokenInternal, changeFeedRequestOptions); return(new FeedIteratorCore <T>(changeFeedIteratorCore, responseCreator: this.ClientContext.ResponseFactory.CreateChangeFeedUserTypeResponse <T>)); }
internal ChangeFeedIteratorCore( ContainerCore container, FeedTokenInternal feedTokenInternal, ChangeFeedRequestOptions changeFeedRequestOptions) : this(container, changeFeedRequestOptions) { if (feedTokenInternal == null) { throw new ArgumentNullException(nameof(feedTokenInternal)); } this.feedTokenInternal = feedTokenInternal; }
/// <summary> /// Helper method to create a stream feed iterator. /// It decides if it is a query or read feed and create /// the correct instance. /// </summary> internal FeedIteratorInternal GetItemQueryStreamIteratorInternal( SqlQuerySpec sqlQuerySpec, bool isContinuationExcpected, string continuationToken, FeedTokenInternal feedToken, QueryRequestOptions requestOptions) { requestOptions = requestOptions ?? new QueryRequestOptions(); if (requestOptions.IsEffectivePartitionKeyRouting) { if (feedToken != null) { throw new ArgumentException(nameof(feedToken), ClientResources.FeedToken_EffectivePartitionKeyRouting); } requestOptions.PartitionKey = null; } if (sqlQuerySpec == null) { return(FeedIteratorCore.CreateForPartitionedResource( this, this.LinkUri, resourceType: ResourceType.Document, queryDefinition: null, continuationToken: continuationToken, feedTokenInternal: feedToken, options: requestOptions)); } return(QueryIterator.Create( client: this.queryClient, clientContext: this.ClientContext, sqlQuerySpec: sqlQuerySpec, continuationToken: continuationToken, queryRequestOptions: requestOptions, resourceLink: this.LinkUri, isContinuationExpected: isContinuationExcpected, allowNonValueAggregateQuery: true, partitionedQueryExecutionInfo: null)); }
private FeedIteratorCore( ContainerCore containerCore, CosmosClientContext clientContext, Uri resourceLink, ResourceType resourceType, QueryDefinition queryDefinition, string continuationToken, FeedTokenInternal feedTokenInternal, QueryRequestOptions options) { this.resourceLink = resourceLink; this.containerCore = containerCore; this.clientContext = clientContext; this.resourceType = resourceType; this.querySpec = queryDefinition?.ToSqlQuerySpec(); this.feedTokenInternal = feedTokenInternal; this.ContinuationToken = continuationToken ?? this.feedTokenInternal?.GetContinuation(); this.requestOptions = options; this.hasMoreResultsInternal = true; }
internal static FeedIteratorCore CreateForPartitionedResource( ContainerCore containerCore, Uri resourceLink, ResourceType resourceType, QueryDefinition queryDefinition, string continuationToken, FeedTokenInternal feedTokenInternal, QueryRequestOptions options) { if (containerCore == null) { throw new ArgumentNullException(nameof(containerCore)); } return new FeedIteratorCore( containerCore: containerCore, clientContext: containerCore.ClientContext, resourceLink: resourceLink, resourceType: resourceType, queryDefinition: queryDefinition, continuationToken: continuationToken, feedTokenInternal: feedTokenInternal, options: options); }
private async Task <ResponseMessage> ReadNextInternalAsync( CosmosDiagnosticsContext diagnosticsScope, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); if (this.feedTokenInternal == null) { Routing.PartitionKeyRangeCache partitionKeyRangeCache = await this.clientContext.DocumentClient.GetPartitionKeyRangeCacheAsync(); string containerRId = await this.container.GetRIDAsync(cancellationToken); IReadOnlyList <Documents.PartitionKeyRange> partitionKeyRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync( containerRId, new Documents.Routing.Range <string>( Documents.Routing.PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey, Documents.Routing.PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey, isMinInclusive: true, isMaxInclusive: false), forceRefresh : true); // ReadAll scenario, initialize with one token for all this.feedTokenInternal = new FeedTokenEPKRange(containerRId, partitionKeyRanges); } Uri resourceUri = this.container.LinkUri; ResponseMessage responseMessage = await this.clientContext.ProcessResourceOperationStreamAsync( resourceUri : resourceUri, resourceType : Documents.ResourceType.Document, operationType : Documents.OperationType.ReadFeed, requestOptions : this.changeFeedOptions, cosmosContainerCore : this.container, requestEnricher : request => { ChangeFeedRequestOptions.FillContinuationToken(request, this.feedTokenInternal.GetContinuation()); this.feedTokenInternal.EnrichRequest(request); }, partitionKey : null, streamPayload : null, diagnosticsScope : diagnosticsScope, cancellationToken : cancellationToken); // Retry in case of splits or other scenarios if (await this.feedTokenInternal.ShouldRetryAsync(this.container, responseMessage, cancellationToken)) { if (responseMessage.IsSuccessStatusCode || responseMessage.StatusCode == HttpStatusCode.NotModified) { // Change Feed read uses Etag for continuation this.feedTokenInternal.UpdateContinuation(responseMessage.Headers.ETag); } return(await this.ReadNextInternalAsync(diagnosticsScope, cancellationToken)); } if (responseMessage.IsSuccessStatusCode || responseMessage.StatusCode == HttpStatusCode.NotModified) { // Change Feed read uses Etag for continuation this.feedTokenInternal.UpdateContinuation(responseMessage.Headers.ETag); } this.hasMoreResults = responseMessage.IsSuccessStatusCode; return(responseMessage); }
private async Task<ResponseMessage> ReadNextInternalAsync( CosmosDiagnosticsContext diagnostics, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); Stream stream = null; OperationType operation = OperationType.ReadFeed; if (this.querySpec != null) { stream = this.clientContext.SerializerCore.ToStreamSqlQuerySpec(this.querySpec, this.resourceType); operation = OperationType.Query; } if (this.feedTokenInternal == null) { TryCatch<FeedTokenInternal> tryCatchFeedTokeninternal = await this.TryInitializeFeedTokenAsync(cancellationToken); if (!tryCatchFeedTokeninternal.Succeeded) { if (tryCatchFeedTokeninternal.Exception.InnerException is CosmosException cosmosException) { return cosmosException.ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnostics)); } return CosmosExceptionFactory.CreateInternalServerErrorException( message: tryCatchFeedTokeninternal.Exception.InnerException.Message, innerException: tryCatchFeedTokeninternal.Exception.InnerException, diagnosticsContext: diagnostics).ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnostics)); } this.feedTokenInternal = tryCatchFeedTokeninternal.Result; } ResponseMessage response = await this.clientContext.ProcessResourceOperationStreamAsync( resourceUri: this.resourceLink, resourceType: this.resourceType, operationType: operation, requestOptions: this.requestOptions, cosmosContainerCore: null, partitionKey: this.requestOptions?.PartitionKey, streamPayload: stream, requestEnricher: request => { QueryRequestOptions.FillContinuationToken(request, this.ContinuationToken); if (this.querySpec != null) { request.Headers.Add(HttpConstants.HttpHeaders.ContentType, MediaTypes.QueryJson); request.Headers.Add(HttpConstants.HttpHeaders.IsQuery, bool.TrueString); } this.feedTokenInternal?.EnrichRequest(request); }, diagnosticsContext: diagnostics, cancellationToken: cancellationToken); // Retry in case of splits or other scenarios only on partitioned resources if (this.containerCore != null && await this.feedTokenInternal.ShouldRetryAsync(this.containerCore, response, cancellationToken)) { return await this.ReadNextInternalAsync(diagnostics, cancellationToken); } if (response.IsSuccessStatusCode) { this.feedTokenInternal.UpdateContinuation(response.Headers.ContinuationToken); this.ContinuationToken = this.feedTokenInternal.GetContinuation(); this.hasMoreResultsInternal = !this.feedTokenInternal.IsDone; } else { this.hasMoreResultsInternal = false; } return response; }
private async Task <ResponseMessage> ReadNextInternalAsync( CosmosDiagnosticsContext diagnosticsScope, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); if (this.feedTokenInternal == null) { TryCatch <FeedTokenInternal> tryCatchFeedTokeninternal = await this.TryInitializeFeedTokenAsync(cancellationToken); if (!tryCatchFeedTokeninternal.Succeeded) { if (tryCatchFeedTokeninternal.Exception.InnerException is CosmosException cosmosException) { return(cosmosException.ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnosticsScope))); } return(CosmosExceptionFactory.CreateInternalServerErrorException( message: tryCatchFeedTokeninternal.Exception.InnerException.Message, innerException: tryCatchFeedTokeninternal.Exception.InnerException, diagnosticsContext: diagnosticsScope).ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnosticsScope))); } this.feedTokenInternal = tryCatchFeedTokeninternal.Result; } Uri resourceUri = this.container.LinkUri; ResponseMessage responseMessage = await this.clientContext.ProcessResourceOperationStreamAsync( resourceUri : resourceUri, resourceType : Documents.ResourceType.Document, operationType : Documents.OperationType.ReadFeed, requestOptions : this.changeFeedOptions, cosmosContainerCore : this.container, requestEnricher : request => { ChangeFeedRequestOptions.FillContinuationToken(request, this.feedTokenInternal.GetContinuation()); this.feedTokenInternal.EnrichRequest(request); }, partitionKey : null, streamPayload : null, diagnosticsContext : diagnosticsScope, cancellationToken : cancellationToken); // Retry in case of splits or other scenarios if (await this.feedTokenInternal.ShouldRetryAsync(this.container, responseMessage, cancellationToken)) { if (responseMessage.IsSuccessStatusCode || responseMessage.StatusCode == HttpStatusCode.NotModified) { // Change Feed read uses Etag for continuation this.feedTokenInternal.UpdateContinuation(responseMessage.Headers.ETag); } return(await this.ReadNextInternalAsync(diagnosticsScope, cancellationToken)); } if (responseMessage.IsSuccessStatusCode || responseMessage.StatusCode == HttpStatusCode.NotModified) { // Change Feed read uses Etag for continuation this.feedTokenInternal.UpdateContinuation(responseMessage.Headers.ETag); } this.hasMoreResults = responseMessage.IsSuccessStatusCode; return(responseMessage); }