示例#1
0
        public async Task NextReadHasUpdatedContinuation()
        {
            int      itemCount = 5;
            string   pkRangeId = "0";
            string   etag      = Guid.NewGuid().ToString();
            DateTime startTime = DateTime.UtcNow;
            DocumentServiceLeaseCore documentServiceLeaseCore = new DocumentServiceLeaseCore()
            {
                LeaseToken = pkRangeId
            };

            ResponseMessage firstResponse = new ResponseMessage(System.Net.HttpStatusCode.OK);

            firstResponse.Headers.ETag = etag;
            ResponseMessage secondResponse = new ResponseMessage(System.Net.HttpStatusCode.OK);

            int responseCount = 0;
            Func <Action <RequestMessage>, bool> validateEnricher = (Action <RequestMessage> enricher) =>
            {
                RequestMessage requestMessage = new RequestMessage();
                enricher(requestMessage);
                return(responseCount++ == 0 || requestMessage.Headers.IfNoneMatch == etag);
            };

            Mock <ContainerInternal>   containerMock = new Mock <ContainerInternal>();
            Mock <CosmosClientContext> mockContext   = new Mock <CosmosClientContext>();

            mockContext.SetupSequence(c => c.ProcessResourceOperationStreamAsync(
                                          It.IsAny <string>(),
                                          It.Is <Documents.ResourceType>(rt => rt == Documents.ResourceType.Document),
                                          It.Is <Documents.OperationType>(rt => rt == Documents.OperationType.ReadFeed),
                                          It.Is <ChangeFeedRequestOptions>(cfo => cfo.PageSizeHint == itemCount),
                                          It.Is <ContainerInternal>(o => o == containerMock.Object),
                                          It.IsAny <FeedRange>(),
                                          It.IsAny <Stream>(),
                                          It.Is <Action <RequestMessage> >(enricher => validateEnricher(enricher)),
                                          It.IsAny <CosmosDiagnosticsContext>(),
                                          It.IsAny <ITrace>(),
                                          It.IsAny <CancellationToken>()
                                          )
                                      )
            .ReturnsAsync(firstResponse)
            .ReturnsAsync(secondResponse);
            containerMock.Setup(c => c.ClientContext).Returns(mockContext.Object);
            containerMock.Setup(c => c.LinkUri).Returns("http://localhot");

            ChangeFeedPartitionKeyResultSetIteratorCore iterator = ChangeFeedPartitionKeyResultSetIteratorCore.Create(
                lease: documentServiceLeaseCore,
                continuationToken: null,
                maxItemCount: itemCount,
                container: containerMock.Object,
                startTime: startTime,
                startFromBeginning: false);

            await iterator.ReadNextAsync();

            await iterator.ReadNextAsync();

            Assert.AreEqual(2, responseCount);
        }
示例#2
0
        public override FeedProcessor Create(DocumentServiceLease lease, ChangeFeedObserver <T> observer)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (lease == null)
            {
                throw new ArgumentNullException(nameof(lease));
            }

            ProcessorOptions options = new ProcessorOptions
            {
                StartContinuation = !string.IsNullOrEmpty(lease.ContinuationToken) ?
                                    lease.ContinuationToken :
                                    this.changeFeedProcessorOptions.StartContinuation,
                LeaseToken         = lease.CurrentLeaseToken,
                FeedPollDelay      = this.changeFeedProcessorOptions.FeedPollDelay,
                MaxItemCount       = this.changeFeedProcessorOptions.MaxItemCount,
                StartFromBeginning = this.changeFeedProcessorOptions.StartFromBeginning,
                StartTime          = this.changeFeedProcessorOptions.StartTime,
                SessionToken       = this.changeFeedProcessorOptions.SessionToken,
            };

            PartitionCheckpointerCore checkpointer = new PartitionCheckpointerCore(this.leaseCheckpointer, lease);
            ChangeFeedPartitionKeyResultSetIteratorCore iterator = ChangeFeedPartitionKeyResultSetIteratorCore.Create(
                lease: lease,
                continuationToken: options.StartContinuation,
                maxItemCount: options.MaxItemCount,
                container: this.container,
                startTime: options.StartTime,
                startFromBeginning: options.StartFromBeginning);

            return(new FeedProcessorCore <T>(observer, iterator, options, checkpointer, this.serializerCore));
        }
示例#3
0
        public async Task ShouldSetFeedRangePartitionKeyRange()
        {
            int      itemCount = 5;
            string   pkRangeId = "0";
            string   etag      = Guid.NewGuid().ToString();
            DateTime startTime = DateTime.UtcNow;
            DocumentServiceLeaseCore documentServiceLeaseCore = new DocumentServiceLeaseCore()
            {
                LeaseToken = pkRangeId
            };

            Mock <ContainerInternal>   containerMock = new Mock <ContainerInternal>();
            Mock <CosmosClientContext> mockContext   = new Mock <CosmosClientContext>();

            mockContext.Setup(c => c.ProcessResourceOperationStreamAsync(
                                  It.IsAny <string>(),
                                  It.Is <Documents.ResourceType>(rt => rt == Documents.ResourceType.Document),
                                  It.Is <Documents.OperationType>(rt => rt == Documents.OperationType.ReadFeed),
                                  It.Is <ChangeFeedRequestOptions>(cfo => cfo.PageSizeHint == itemCount),
                                  It.Is <ContainerInternal>(o => o == containerMock.Object),
                                  It.Is <FeedRange>(fr => fr is FeedRangePartitionKeyRange),
                                  It.IsAny <Stream>(),
                                  It.IsAny <Action <RequestMessage> >(),
                                  It.IsAny <CosmosDiagnosticsContext>(),
                                  It.IsAny <ITrace>(),
                                  It.IsAny <CancellationToken>()
                                  )
                              ).ReturnsAsync(new ResponseMessage(System.Net.HttpStatusCode.OK));
            containerMock.Setup(c => c.ClientContext).Returns(mockContext.Object);
            containerMock.Setup(c => c.LinkUri).Returns("http://localhot");

            ChangeFeedPartitionKeyResultSetIteratorCore iterator = ChangeFeedPartitionKeyResultSetIteratorCore.Create(
                lease: documentServiceLeaseCore,
                continuationToken: null,
                maxItemCount: itemCount,
                container: containerMock.Object,
                startTime: startTime,
                startFromBeginning: false);

            ResponseMessage response = await iterator.ReadNextAsync();

            Assert.AreEqual(System.Net.HttpStatusCode.OK, response.StatusCode);

            mockContext.Verify(c => c.ProcessResourceOperationStreamAsync(
                                   It.IsAny <string>(),
                                   It.Is <Documents.ResourceType>(rt => rt == Documents.ResourceType.Document),
                                   It.Is <Documents.OperationType>(rt => rt == Documents.OperationType.ReadFeed),
                                   It.Is <ChangeFeedRequestOptions>(cfo => cfo.PageSizeHint == itemCount),
                                   It.Is <ContainerInternal>(o => o == containerMock.Object),
                                   It.Is <FeedRange>(fr => fr is FeedRangePartitionKeyRange),
                                   It.IsAny <Stream>(),
                                   It.IsAny <Action <RequestMessage> >(),
                                   It.IsAny <CosmosDiagnosticsContext>(),
                                   It.IsAny <ITrace>(),
                                   It.IsAny <CancellationToken>()
                                   ), Times.Once);
        }
示例#4
0
        public async Task ShouldUseFeedRangeEpk()
        {
            int      itemCount = 5;
            string   pkRangeId = "0";
            DateTime startTime = DateTime.UtcNow;

            Documents.Routing.Range <string> range = new Documents.Routing.Range <string>("AA", "BB", true, false);
            FeedRangeEpk feedRange = new FeedRangeEpk(range);
            DocumentServiceLeaseCoreEpk documentServiceLeaseCore = new DocumentServiceLeaseCoreEpk()
            {
                LeaseToken = pkRangeId,
                FeedRange  = feedRange
            };

            Mock <ContainerInternal>   containerMock = new Mock <ContainerInternal>();
            Mock <CosmosClientContext> mockContext   = new Mock <CosmosClientContext>();

            mockContext.Setup(x => x.OperationHelperAsync <ResponseMessage>(
                                  It.Is <string>(str => str.Contains("Change Feed Processor")),
                                  It.IsAny <RequestOptions>(),
                                  It.IsAny <Func <ITrace, Task <ResponseMessage> > >(),
                                  It.Is <TraceComponent>(tc => tc == TraceComponent.ChangeFeed),
                                  It.IsAny <TraceLevel>()))
            .Returns <string, RequestOptions, Func <ITrace, Task <ResponseMessage> >, TraceComponent, TraceLevel>(
                (operationName, requestOptions, func, comp, level) =>
            {
                using (ITrace trace = Trace.GetRootTrace(operationName, comp, level))
                {
                    return(func(trace));
                }
            });

            mockContext.Setup(c => c.ProcessResourceOperationStreamAsync(
                                  It.IsAny <string>(),
                                  It.Is <Documents.ResourceType>(rt => rt == Documents.ResourceType.Document),
                                  It.Is <Documents.OperationType>(rt => rt == Documents.OperationType.ReadFeed),
                                  It.Is <ChangeFeedRequestOptions>(cfo => cfo.PageSizeHint == itemCount),
                                  It.Is <ContainerInternal>(o => o == containerMock.Object),
                                  It.Is <FeedRange>(fr => fr is FeedRangeEpk),
                                  It.IsAny <Stream>(),
                                  It.IsAny <Action <RequestMessage> >(),
                                  It.Is <ITrace>(t => !(t is NoOpTrace)),
                                  It.IsAny <CancellationToken>()
                                  )
                              ).ReturnsAsync(new ResponseMessage(System.Net.HttpStatusCode.OK));
            containerMock.Setup(c => c.ClientContext).Returns(mockContext.Object);
            containerMock.Setup(c => c.LinkUri).Returns("http://localhot");
            MockDocumentClient mockDocumentClient = new MockDocumentClient();

            mockContext.Setup(c => c.DocumentClient).Returns(mockDocumentClient);

            ChangeFeedPartitionKeyResultSetIteratorCore iterator = ChangeFeedPartitionKeyResultSetIteratorCore.Create(
                lease: documentServiceLeaseCore,
                continuationToken: null,
                maxItemCount: itemCount,
                container: containerMock.Object,
                startTime: startTime,
                startFromBeginning: false);

            ResponseMessage response = await iterator.ReadNextAsync();

            Assert.AreEqual(System.Net.HttpStatusCode.OK, response.StatusCode);

            mockContext.Verify(c => c.ProcessResourceOperationStreamAsync(
                                   It.IsAny <string>(),
                                   It.Is <Documents.ResourceType>(rt => rt == Documents.ResourceType.Document),
                                   It.Is <Documents.OperationType>(rt => rt == Documents.OperationType.ReadFeed),
                                   It.Is <ChangeFeedRequestOptions>(cfo => cfo.PageSizeHint == itemCount),
                                   It.Is <ContainerInternal>(o => o == containerMock.Object),
                                   It.Is <FeedRange>(fr => fr is FeedRangeEpk),
                                   It.IsAny <Stream>(),
                                   It.IsAny <Action <RequestMessage> >(),
                                   It.Is <ITrace>(t => !(t is NoOpTrace)),
                                   It.IsAny <CancellationToken>()
                                   ), Times.Once);
        }
示例#5
0
        public async Task EtagPassesContinuation()
        {
            int      itemCount = 5;
            string   pkRangeId = "0";
            string   etag      = Guid.NewGuid().ToString();
            DateTime startTime = DateTime.UtcNow;
            DocumentServiceLeaseCore documentServiceLeaseCore = new DocumentServiceLeaseCore()
            {
                LeaseToken = pkRangeId
            };

            ResponseMessage responseMessage = new ResponseMessage(System.Net.HttpStatusCode.OK);

            responseMessage.Headers.ETag = etag;

            Mock <ContainerInternal>   containerMock = new Mock <ContainerInternal>();
            Mock <CosmosClientContext> mockContext   = new Mock <CosmosClientContext>();

            mockContext.Setup(x => x.OperationHelperAsync <ResponseMessage>(
                                  It.Is <string>(str => str.Contains("Change Feed Processor")),
                                  It.IsAny <RequestOptions>(),
                                  It.IsAny <Func <ITrace, Task <ResponseMessage> > >(),
                                  It.Is <TraceComponent>(tc => tc == TraceComponent.ChangeFeed),
                                  It.IsAny <TraceLevel>()))
            .Returns <string, RequestOptions, Func <ITrace, Task <ResponseMessage> >, TraceComponent, TraceLevel>(
                (operationName, requestOptions, func, comp, level) =>
            {
                using (ITrace trace = Trace.GetRootTrace(operationName, comp, level))
                {
                    return(func(trace));
                }
            });

            mockContext.Setup(c => c.ProcessResourceOperationStreamAsync(
                                  It.IsAny <string>(),
                                  It.IsAny <Documents.ResourceType>(),
                                  It.IsAny <Documents.OperationType>(),
                                  It.IsAny <ChangeFeedRequestOptions>(),
                                  It.IsAny <ContainerInternal>(),
                                  It.IsAny <FeedRange>(),
                                  It.IsAny <Stream>(),
                                  It.IsAny <Action <RequestMessage> >(),
                                  It.Is <ITrace>(t => !(t is NoOpTrace)),
                                  It.IsAny <CancellationToken>()
                                  )
                              ).ReturnsAsync(responseMessage);
            containerMock.Setup(c => c.ClientContext).Returns(mockContext.Object);
            containerMock.Setup(c => c.LinkUri).Returns("http://localhot");

            ChangeFeedPartitionKeyResultSetIteratorCore iterator = ChangeFeedPartitionKeyResultSetIteratorCore.Create(
                lease: documentServiceLeaseCore,
                continuationToken: null,
                maxItemCount: itemCount,
                container: containerMock.Object,
                startTime: startTime,
                startFromBeginning: false);

            ResponseMessage response = await iterator.ReadNextAsync();

            Assert.AreEqual(System.Net.HttpStatusCode.OK, response.StatusCode);
            Assert.AreEqual(etag, response.Headers.ContinuationToken);
        }