コード例 #1
0
        public override FeedIterator <T> GetChangeFeedIterator <T>(
            ChangeFeedStartFrom changeFeedStartFrom,
            ChangeFeedMode changeFeedMode,
            ChangeFeedRequestOptions changeFeedRequestOptions = null)
        {
            if (changeFeedStartFrom == null)
            {
                throw new ArgumentNullException(nameof(changeFeedStartFrom));
            }

            if (changeFeedMode == null)
            {
                throw new ArgumentNullException(nameof(changeFeedMode));
            }

            NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                this,
                this.queryClient,
                changeFeedRequestOptions: changeFeedRequestOptions);
            DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer);

            ChangeFeedIteratorCore changeFeedIteratorCore = new ChangeFeedIteratorCore(
                documentContainer: documentContainer,
                changeFeedStartFrom: changeFeedStartFrom,
                changeFeedMode: changeFeedMode,
                changeFeedRequestOptions: changeFeedRequestOptions,
                clientContext: this.ClientContext);

            return(new FeedIteratorCore <T>(
                       changeFeedIteratorCore,
                       responseCreator: this.ClientContext.ResponseFactory.CreateChangeFeedUserTypeResponse <T>));
        }
コード例 #2
0
        /// <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>
        public override FeedIteratorInternal GetItemQueryStreamIteratorInternal(
            SqlQuerySpec sqlQuerySpec,
            bool isContinuationExcpected,
            string continuationToken,
            FeedRangeInternal feedRange,
            QueryRequestOptions requestOptions)
        {
            requestOptions ??= new QueryRequestOptions();

            if (requestOptions.IsEffectivePartitionKeyRouting)
            {
                if (feedRange != null)
                {
                    throw new ArgumentException(nameof(feedRange), ClientResources.FeedToken_EffectivePartitionKeyRouting);
                }

                requestOptions.PartitionKey = null;
            }

            if (sqlQuerySpec == null)
            {
                NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                    this,
                    this.queryClient,
                    diagnosticsContext: null,
                    requestOptions);

                DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer);

                return(new ReadFeedIteratorCore(
                           documentContainer: documentContainer,
                           queryRequestOptions: requestOptions,
                           continuationToken: continuationToken,
                           pageSize: requestOptions.MaxItemCount ?? int.MaxValue,
                           cancellationToken: default));
コード例 #3
0
        public override FeedIterator GetChangeFeedStreamIterator(
            ChangeFeedStartFrom changeFeedStartFrom,
            ChangeFeedMode changeFeedMode,
            ChangeFeedRequestOptions changeFeedRequestOptions = null)
        {
            if (changeFeedStartFrom == null)
            {
                throw new ArgumentNullException(nameof(changeFeedStartFrom));
            }

            if (changeFeedMode == null)
            {
                throw new ArgumentNullException(nameof(changeFeedMode));
            }

            NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                this,
                this.queryClient,
                changeFeedRequestOptions: changeFeedRequestOptions);
            DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer);

            return(new ChangeFeedIteratorCore(
                       documentContainer: documentContainer,
                       changeFeedStartFrom: changeFeedStartFrom,
                       changeFeedMode: changeFeedMode,
                       changeFeedRequestOptions: changeFeedRequestOptions,
                       clientContext: this.ClientContext));
        }
コード例 #4
0
        /// <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>
        public override FeedIteratorInternal GetItemQueryStreamIteratorInternal(
            SqlQuerySpec sqlQuerySpec,
            bool isContinuationExcpected,
            string continuationToken,
            FeedRangeInternal feedRange,
            QueryRequestOptions requestOptions)
        {
            requestOptions ??= new QueryRequestOptions();

            if (requestOptions.IsEffectivePartitionKeyRouting)
            {
                if (feedRange != null)
                {
                    throw new ArgumentException(nameof(feedRange), ClientResources.FeedToken_EffectivePartitionKeyRouting);
                }

                requestOptions.PartitionKey = null;
            }

            if (sqlQuerySpec == null)
            {
                NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                    this,
                    this.queryClient,
                    requestOptions);

                DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer);

                ReadFeedPaginationOptions.PaginationDirection?direction = null;
                if ((requestOptions.Properties != null) && requestOptions.Properties.TryGetValue(HttpConstants.HttpHeaders.EnumerationDirection, out object enumerationDirection))
                {
                    direction = (byte)enumerationDirection == (byte)RntbdConstants.RntdbEnumerationDirection.Reverse ? ReadFeedPaginationOptions.PaginationDirection.Reverse : ReadFeedPaginationOptions.PaginationDirection.Forward;
                }

                ReadFeedPaginationOptions readFeedPaginationOptions = new ReadFeedPaginationOptions(
                    direction,
                    pageSizeHint: requestOptions.MaxItemCount ?? int.MaxValue);

                return(new ReadFeedIteratorCore(
                           documentContainer,
                           continuationToken,
                           readFeedPaginationOptions,
                           requestOptions,
                           cancellationToken: default));
            }

            return(QueryIterator.Create(
                       containerCore: this,
                       client: this.queryClient,
                       clientContext: this.ClientContext,
                       sqlQuerySpec: sqlQuerySpec,
                       continuationToken: continuationToken,
                       feedRangeInternal: feedRange,
                       queryRequestOptions: requestOptions,
                       resourceLink: this.LinkUri,
                       isContinuationExpected: isContinuationExcpected,
                       allowNonValueAggregateQuery: true,
                       forcePassthrough: false,
                       partitionedQueryExecutionInfo: null));
        }
コード例 #5
0
        public override FeedIteratorInternal GetReadFeedIterator(
            QueryDefinition queryDefinition,
            QueryRequestOptions queryRequestOptions,
            string resourceLink,
            ResourceType resourceType,
            string continuationToken,
            int pageSize)
        {
            queryRequestOptions ??= new QueryRequestOptions();

            NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                this,
                this.queryClient,
                queryRequestOptions,
                resourceLink: resourceLink,
                resourceType: resourceType);

            DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer);

            FeedIteratorInternal feedIterator;

            if (queryDefinition != null)
            {
                feedIterator = QueryIterator.Create(
                    containerCore: this,
                    client: this.queryClient,
                    clientContext: this.ClientContext,
                    sqlQuerySpec: queryDefinition.ToSqlQuerySpec(),
                    continuationToken: continuationToken,
                    feedRangeInternal: FeedRangeEpk.FullRange,
                    queryRequestOptions: queryRequestOptions,
                    resourceLink: resourceLink,
                    isContinuationExpected: false,
                    allowNonValueAggregateQuery: true,
                    forcePassthrough: false,
                    partitionedQueryExecutionInfo: null);
            }
            else
            {
                ReadFeedPaginationOptions.PaginationDirection?direction = null;
                if ((queryRequestOptions.Properties != null) && queryRequestOptions.Properties.TryGetValue(HttpConstants.HttpHeaders.EnumerationDirection, out object enumerationDirection))
                {
                    direction = (byte)enumerationDirection == (byte)RntbdConstants.RntdbEnumerationDirection.Reverse ? ReadFeedPaginationOptions.PaginationDirection.Reverse : ReadFeedPaginationOptions.PaginationDirection.Forward;
                }

                ReadFeedPaginationOptions readFeedPaginationOptions = new ReadFeedPaginationOptions(
                    direction,
                    pageSizeHint: queryRequestOptions.MaxItemCount ?? int.MaxValue);

                feedIterator = new ReadFeedIteratorCore(
                    documentContainer: documentContainer,
                    queryRequestOptions: queryRequestOptions,
                    continuationToken: continuationToken,
                    readFeedPaginationOptions: readFeedPaginationOptions,
                    cancellationToken: default);
コード例 #6
0
        public async Task MonadicChangeFeedAsync_ChangeFeedMode_Incremental()
        {
            Mock <ContainerInternal>   container = new Mock <ContainerInternal>();
            Mock <CosmosClientContext> context   = new Mock <CosmosClientContext>();

            container.Setup(m => m.ClientContext).Returns(context.Object);

            Func <Action <RequestMessage>, bool> validateEnricher = (Action <RequestMessage> enricher) =>
            {
                RequestMessage requestMessage = new RequestMessage();
                enricher(requestMessage);
                Assert.AreEqual(HttpConstants.A_IMHeaderValues.IncrementalFeed, requestMessage.Headers[HttpConstants.HttpHeaders.A_IM]);
                return(true);
            };

            ResponseMessage response = new ResponseMessage(System.Net.HttpStatusCode.NotModified);

            response.Headers.ETag          = Guid.NewGuid().ToString();
            response.Headers.ActivityId    = Guid.NewGuid().ToString();
            response.Headers.RequestCharge = 1;

            context.SetupSequence(c => c.ProcessResourceOperationStreamAsync(
                                      It.IsAny <string>(),
                                      It.Is <ResourceType>(rt => rt == ResourceType.Document),
                                      It.Is <OperationType>(rt => rt == OperationType.ReadFeed),
                                      It.IsAny <RequestOptions>(),
                                      It.Is <ContainerInternal>(o => o == container.Object),
                                      It.IsAny <FeedRangeInternal>(),
                                      It.IsAny <Stream>(),
                                      It.Is <Action <RequestMessage> >(enricher => validateEnricher(enricher)),
                                      It.IsAny <CosmosDiagnosticsContext>(),
                                      It.IsAny <ITrace>(),
                                      It.IsAny <CancellationToken>()
                                      )
                                  ).ReturnsAsync(response);

            NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                container.Object,
                Mock.Of <CosmosQueryClient>(),
                Mock.Of <CosmosDiagnosticsContext>());

            await networkAttachedDocumentContainer.MonadicChangeFeedAsync(
                state : ChangeFeedState.Beginning(),
                feedRange : new FeedRangePartitionKeyRange("0"),
                pageSize : 10,
                changeFeedMode : ChangeFeedMode.Incremental,
                jsonSerializationFormat : null,
                trace : NoOpTrace.Singleton,
                cancellationToken : default);
コード例 #7
0
        public override IAsyncEnumerable <TryCatch <ChangeFeed.ChangeFeedPage> > GetChangeFeedAsyncEnumerable(
            ChangeFeedCrossFeedRangeState state,
            ChangeFeedRequestOptions changeFeedRequestOptions = default)
        {
            NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                this,
                this.queryClient,
                new CosmosDiagnosticsContextCore());
            DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer);

            return(new ChangeFeedCrossFeedRangeAsyncEnumerable(
                       documentContainer,
                       changeFeedRequestOptions,
                       state));
        }
コード例 #8
0
        public override IAsyncEnumerable <TryCatch <ChangeFeed.ChangeFeedPage> > GetChangeFeedAsyncEnumerable(
            ChangeFeedCrossFeedRangeState state,
            ChangeFeedMode changeFeedMode,
            ChangeFeedRequestOptions changeFeedRequestOptions = default)
        {
            NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                this,
                this.queryClient,
                changeFeedRequestOptions: changeFeedRequestOptions);
            DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer);

            Dictionary <string, string> additionalHeaders;

            if ((changeFeedRequestOptions?.Properties != null) && changeFeedRequestOptions.Properties.Any())
            {
                Dictionary <string, object> additionalNonStringHeaders = new Dictionary <string, object>();
                additionalHeaders = new Dictionary <string, string>();
                foreach (KeyValuePair <string, object> keyValuePair in changeFeedRequestOptions.Properties)
                {
                    if (keyValuePair.Value is string stringValue)
                    {
                        additionalHeaders[keyValuePair.Key] = stringValue;
                    }
                    else
                    {
                        additionalNonStringHeaders[keyValuePair.Key] = keyValuePair.Value;
                    }
                }

                changeFeedRequestOptions.Properties = additionalNonStringHeaders;
            }
            else
            {
                additionalHeaders = null;
            }

            ChangeFeedPaginationOptions changeFeedPaginationOptions = new ChangeFeedPaginationOptions(
                changeFeedMode,
                changeFeedRequestOptions?.PageSizeHint,
                changeFeedRequestOptions?.JsonSerializationFormatOptions?.JsonSerializationFormat,
                additionalHeaders);

            return(new ChangeFeedCrossFeedRangeAsyncEnumerable(
                       documentContainer,
                       state,
                       changeFeedPaginationOptions,
                       changeFeedRequestOptions?.JsonSerializationFormatOptions));
        }
コード例 #9
0
        public async Task TestKeyRangeCacheRefresh()
        {
            const string resourceId              = "resourceId";
            Mock <CosmosClientContext> context   = new Mock <CosmosClientContext>();
            Mock <ContainerInternal>   container = new Mock <ContainerInternal>();

            container.Setup(c => c.ClientContext).Returns(context.Object);
            container.Setup(c => c.GetCachedRIDAsync(false, It.IsAny <ITrace>(), It.IsAny <CancellationToken>())).ReturnsAsync(resourceId);

            Mock <CosmosQueryClient>         client = new Mock <CosmosQueryClient>();
            NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                container.Object,
                client.Object);

            TryCatch result = await networkAttachedDocumentContainer.MonadicRefreshProviderAsync(
                trace : NoOpTrace.Singleton,
                cancellationToken : default);
コード例 #10
0
        public async Task TestKeyRangeCacheRefresh()
        {
            bool   validate     = false;
            bool   pass         = false;
            string expectedPath = null;
            HttpClientHandlerHelper httpClientHandler = new HttpClientHandlerHelper
            {
                RequestCallBack = (HttpRequestMessage request, CancellationToken cancellationToken) =>
                {
                    if (validate)
                    {
                        pass = request.RequestUri.LocalPath == expectedPath;
                    }

                    return(null);
                }
            };

            using (CosmosClient client = TestCommon.CreateCosmosClient(builder => builder
                                                                       .WithConnectionModeGateway()
                                                                       .WithHttpClientFactory(() => new HttpClient(httpClientHandler))))
            {
                ContainerInternal                containerInternal = client.GetContainer(this.database.Id, this.Container.Id) as ContainerInternal;
                CosmosQueryClientCore            queryClient       = new CosmosQueryClientCore(client.ClientContext, containerInternal);
                NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                    containerInternal,
                    queryClient,
                    Guid.NewGuid());

                // warm up the caches
                _ = await containerInternal.ReadItemStreamAsync("doesnotexist", PartitionKey.Null);

                ContainerProperties containerProperties = await containerInternal.GetCachedContainerPropertiesAsync(false, NoOpTrace.Singleton, default);

                expectedPath = "/" + containerProperties.SelfLink + "pkranges";
                validate     = true;

                TryCatch result = await networkAttachedDocumentContainer.MonadicRefreshProviderAsync(
                    trace : NoOpTrace.Singleton,
                    cancellationToken : default);
コード例 #11
0
        public static QueryIterator Create(
            ContainerCore containerCore,
            CosmosQueryClient client,
            CosmosClientContext clientContext,
            SqlQuerySpec sqlQuerySpec,
            string continuationToken,
            FeedRangeInternal feedRangeInternal,
            QueryRequestOptions queryRequestOptions,
            string resourceLink,
            bool isContinuationExpected,
            bool allowNonValueAggregateQuery,
            bool forcePassthrough,
            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo)
        {
            if (queryRequestOptions == null)
            {
                queryRequestOptions = new QueryRequestOptions();
            }

            CosmosQueryContextCore cosmosQueryContext = new CosmosQueryContextCore(
                client: client,
                resourceTypeEnum: Documents.ResourceType.Document,
                operationType: Documents.OperationType.Query,
                resourceType: typeof(QueryResponseCore),
                resourceLink: resourceLink,
                isContinuationExpected: isContinuationExpected,
                allowNonValueAggregateQuery: allowNonValueAggregateQuery,
                correlatedActivityId: Guid.NewGuid());

            NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                containerCore,
                client,
                queryRequestOptions);
            DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer);

            CosmosElement requestContinuationToken;

            switch (queryRequestOptions.ExecutionEnvironment.GetValueOrDefault(ExecutionEnvironment.Client))
            {
            case ExecutionEnvironment.Client:
                if (continuationToken != null)
                {
                    TryCatch <CosmosElement> tryParse = CosmosElement.Monadic.Parse(continuationToken);
                    if (tryParse.Failed)
                    {
                        return(new QueryIterator(
                                   cosmosQueryContext,
                                   new FaultedQueryPipelineStage(
                                       new MalformedContinuationTokenException(
                                           message: $"Malformed Continuation Token: {continuationToken}",
                                           innerException: tryParse.Exception)),
                                   queryRequestOptions.CosmosSerializationFormatOptions,
                                   queryRequestOptions,
                                   clientContext));
                    }

                    requestContinuationToken = tryParse.Result;
                }
                else
                {
                    requestContinuationToken = null;
                }
                break;

            case ExecutionEnvironment.Compute:
                requestContinuationToken = queryRequestOptions.CosmosElementContinuationToken;
                break;

            default:
                throw new ArgumentOutOfRangeException($"Unknown {nameof(ExecutionEnvironment)}: {queryRequestOptions.ExecutionEnvironment.Value}.");
            }

            CosmosQueryExecutionContextFactory.InputParameters inputParameters = new CosmosQueryExecutionContextFactory.InputParameters(
                sqlQuerySpec: sqlQuerySpec,
                initialUserContinuationToken: requestContinuationToken,
                initialFeedRange: feedRangeInternal,
                maxConcurrency: queryRequestOptions.MaxConcurrency,
                maxItemCount: queryRequestOptions.MaxItemCount,
                maxBufferedItemCount: queryRequestOptions.MaxBufferedItemCount,
                partitionKey: queryRequestOptions.PartitionKey,
                properties: queryRequestOptions.Properties,
                partitionedQueryExecutionInfo: partitionedQueryExecutionInfo,
                executionEnvironment: queryRequestOptions.ExecutionEnvironment,
                returnResultsInDeterministicOrder: queryRequestOptions.ReturnResultsInDeterministicOrder,
                forcePassthrough: forcePassthrough,
                testInjections: queryRequestOptions.TestSettings);

            return(new QueryIterator(
                       cosmosQueryContext,
                       CosmosQueryExecutionContextFactory.Create(documentContainer, cosmosQueryContext, inputParameters, NoOpTrace.Singleton),
                       queryRequestOptions.CosmosSerializationFormatOptions,
                       queryRequestOptions,
                       clientContext));
        }