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>)); }
/// <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));
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)); }
/// <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)); }
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);
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);
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)); }
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)); }
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);
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);
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)); }