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));
        }
Пример #3
0
        FeedIterator GetChangeFeedStreamIterator(
            FeedToken feedToken,
            ChangeFeedRequestOptions changeFeedRequestOptions = null)
        {
            FeedTokenInternal feedTokenInternal = feedToken as FeedTokenInternal;

            return(new ChangeFeedIteratorCore(
                       this,
                       feedTokenInternal,
                       changeFeedRequestOptions));
        }
Пример #4
0
        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);
        }
Пример #9
0
        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);
        }