internal virtual Task <ResponseMessage> NextResultSetDelegateAsync(
            string continuationToken,
            string partitionKeyRangeId,
            int?maxItemCount,
            ChangeFeedRequestOptions options,
            CancellationToken cancellationToken)
        {
            Uri resourceUri = this.container.LinkUri;

            return(this.clientContext.ProcessResourceOperationAsync <ResponseMessage>(
                       resourceUri: resourceUri,
                       resourceType: Documents.ResourceType.Document,
                       operationType: Documents.OperationType.ReadFeed,
                       requestOptions: options,
                       cosmosContainerCore: this.container,
                       requestEnricher: request =>
            {
                ChangeFeedRequestOptions.FillContinuationToken(request, continuationToken);
                ChangeFeedRequestOptions.FillMaxItemCount(request, maxItemCount);
                ChangeFeedRequestOptions.FillPartitionKeyRangeId(request, partitionKeyRangeId);
            },
                       responseCreator: response => response,
                       partitionKey: null,
                       streamPayload: null,
                       cancellationToken: cancellationToken));
        }
Exemple #2
0
        public void ChangeFeedRequestOptions_ContinuationIsSet()
        {
            RequestMessage           request        = new RequestMessage();
            ChangeFeedRequestOptions requestOptions = new ChangeFeedRequestOptions()
            {
            };

            ChangeFeedRequestOptions.FillContinuationToken(request, "something");
            requestOptions.PopulateRequestOptions(request);

            Assert.AreEqual("something", request.Headers.IfNoneMatch);
            Assert.IsNull(request.Headers[Documents.HttpConstants.HttpHeaders.IfModifiedSince]);
        }
Exemple #3
0
        public void ChangeFeedRequestOptions_ContinuationBeatsStartTime()
        {
            CosmosRequestMessage     request        = new CosmosRequestMessage();
            ChangeFeedRequestOptions requestOptions = new ChangeFeedRequestOptions()
            {
                StartTime = new DateTime(1985, 1, 1)
            };

            ChangeFeedRequestOptions.FillContinuationToken(request, "something");
            requestOptions.FillRequestOptions(request);

            Assert.AreEqual("something", request.Headers.IfNoneMatch);
            Assert.IsNull(request.Headers[Documents.HttpConstants.HttpHeaders.IfModifiedSince]);
        }
Exemple #4
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 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);
        }