Ejemplo n.º 1
0
        public async Task ReadFeedIteratorCore_AllowsParallelProcessing()
        {
            int batchSize = 1000;

            await this.CreateRandomItems(this.LargerContainer, batchSize, randomPartitionKey : true);

            ContainerInternal         itemsCore = this.LargerContainer;
            IReadOnlyList <FeedRange> tokens    = await itemsCore.GetFeedRangesAsync();

            List <Task <int> > tasks = tokens.Select(token => Task.Run(async() =>
            {
                int count = 0;
                FeedIterator feedIterator = itemsCore.GetItemQueryStreamIterator(
                    queryDefinition: null,
                    feedRange: token,
                    continuationToken: null,
                    requestOptions: null);
                while (feedIterator.HasMoreResults)
                {
                    using (ResponseMessage responseMessage =
                               await feedIterator.ReadNextAsync(this.cancellationToken))
                    {
                        if (responseMessage.IsSuccessStatusCode)
                        {
                            Collection <ToDoActivity> response = TestCommon.SerializerCore.FromStream <CosmosFeedResponseUtil <ToDoActivity> >(responseMessage.Content).Data;
                            count += response.Count;
                        }
                    }
                }

                return(count);
            })).ToList();

            await Task.WhenAll(tasks);

            int documentsRead = 0;

            foreach (Task <int> task in tasks)
            {
                documentsRead += task.Result;
            }

            Assert.AreEqual(batchSize, documentsRead);
        }
        public void ApplyBuildConfiguration(
            DocumentServiceLeaseStoreManager customDocumentServiceLeaseStoreManager,
            ContainerInternal leaseContainer,
            string instanceName,
            ChangeFeedLeaseOptions changeFeedLeaseOptions,
            ChangeFeedProcessorOptions changeFeedProcessorOptions,
            ContainerInternal monitoredContainer)
        {
            if (leaseContainer == null && customDocumentServiceLeaseStoreManager == null)
            {
                throw new ArgumentNullException(nameof(leaseContainer));
            }

            this.leaseContainer                = leaseContainer;
            this.monitoredContainer            = monitoredContainer ?? throw new ArgumentNullException(nameof(monitoredContainer));
            this.changeFeedLeaseOptions        = changeFeedLeaseOptions;
            this.documentServiceLeaseContainer = customDocumentServiceLeaseStoreManager?.LeaseContainer;
            this.healthMonitor = changeFeedProcessorOptions.HealthMonitor;
        }
        [TestCategory("Quarantine")] // Not currently working with emulator
        public async Task ContainerAutoscaleIfExistsTest()
        {
            DatabaseInternal database = (DatabaseInlineCore)await this.cosmosClient.CreateDatabaseAsync(
                nameof(CreateDropAutoscaleDatabase) + Guid.NewGuid().ToString());

            Container container = await database.CreateContainerAsync(
                containerProperties : new ContainerProperties("Test", "/id"),
                throughputProperties : ThroughputProperties.CreateAutoscaleThroughput(5000));

            ContainerInternal containerCore = (ContainerInlineCore)container;

            ThroughputResponse throughputResponse = await database.ReadThroughputIfExistsAsync(requestOptions : null);

            Assert.IsNotNull(throughputResponse);
            Assert.AreEqual(HttpStatusCode.NotFound, throughputResponse.StatusCode);
            Assert.IsNull(throughputResponse.Resource);

            throughputResponse = await database.ReplaceThroughputPropertiesIfExistsAsync(
                ThroughputProperties.CreateAutoscaleThroughput(6000));

            Assert.IsNotNull(throughputResponse);
            Assert.AreEqual(HttpStatusCode.NotFound, throughputResponse.StatusCode);
            Assert.IsNull(throughputResponse.Resource);

            throughputResponse = await containerCore.ReadThroughputIfExistsAsync(
                requestOptions : null,
                default(CancellationToken));

            Assert.IsNotNull(throughputResponse);
            Assert.IsTrue(throughputResponse.Resource.Throughput > 400);
            Assert.AreEqual(5000, throughputResponse.Resource.AutoscaleMaxThroughput);

            throughputResponse = await containerCore.ReplaceThroughputIfExistsAsync(
                ThroughputProperties.CreateAutoscaleThroughput(6000),
                requestOptions : null,
                default(CancellationToken));

            Assert.IsNotNull(throughputResponse);
            Assert.IsTrue(throughputResponse.Resource.Throughput > 400);
            Assert.AreEqual(6000, throughputResponse.Resource.AutoscaleMaxThroughput);

            await database.DeleteAsync();
        }
Ejemplo n.º 4
0
 public ChangeFeedEstimatorIterator(
     string processorName,
     ContainerInternal monitoredContainer,
     ContainerInternal leaseContainer,
     ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions)
     : this(
         processorName,
         monitoredContainer,
         leaseContainer,
         changeFeedEstimatorRequestOptions,
         (string partitionKeyRangeId, string continuationToken, bool startFromBeginning) => ResultSetIteratorUtils.BuildResultSetIterator(
             partitionKeyRangeId : partitionKeyRangeId,
             continuationToken : continuationToken,
             maxItemCount : 1,
             container : monitoredContainer,
             startTime : null,
             startFromBeginning : string.IsNullOrEmpty(continuationToken)))
 {
 }
        public async Task ReadFeedIteratorCore_OfT_WithFeedRange_ReadAll_StopResume()
        {
            int batchSize = 1000;

            await this.CreateRandomItems(this.LargerContainer, batchSize, randomPartitionKey : true);

            ContainerInternal         itemsCore = this.LargerContainer;
            IReadOnlyList <FeedRange> tokens    = await itemsCore.GetFeedRangesAsync();

            List <Task <int> > tasks = tokens.Select(token => Task.Run(async() =>
            {
                int count = 0;
                FeedIterator <ToDoActivity> feedIterator = itemsCore.GetItemQueryIterator <ToDoActivity>(queryDefinition: null, feedRange: token);
                string continuation = null;
                while (feedIterator.HasMoreResults)
                {
                    FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync(this.cancellationToken);
                    count       += response.Count;
                    continuation = response.ContinuationToken;
                    break;
                }

                feedIterator = itemsCore.GetItemQueryIterator <ToDoActivity>(queryDefinition: null, continuationToken: continuation);
                while (feedIterator.HasMoreResults)
                {
                    FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync(this.cancellationToken);
                    count += response.Count;
                }

                return(count);
            })).ToList();

            await Task.WhenAll(tasks);

            int documentsRead = 0;

            foreach (Task <int> task in tasks)
            {
                documentsRead += task.Result;
            }

            Assert.AreEqual(batchSize, documentsRead);
        }
 public CosmosLinqQueryProvider(
     ContainerInternal container,
     CosmosResponseFactoryInternal responseFactory,
     CosmosQueryClientCore queryClient,
     string continuationToken,
     QueryRequestOptions cosmosQueryRequestOptions,
     bool allowSynchronousQueryExecution,
     Action <IQueryable> onExecuteScalarQueryCallback = null,
     CosmosSerializationOptions serializationOptions  = null)
 {
     this.container                      = container;
     this.responseFactory                = responseFactory;
     this.queryClient                    = queryClient;
     this.continuationToken              = continuationToken;
     this.cosmosQueryRequestOptions      = cosmosQueryRequestOptions;
     this.allowSynchronousQueryExecution = allowSynchronousQueryExecution;
     this.onExecuteScalarQueryCallback   = onExecuteScalarQueryCallback;
     this.serializationOptions           = serializationOptions;
 }
Ejemplo n.º 7
0
 public CosmosLinqQuery(
     ContainerInternal container,
     CosmosResponseFactoryInternal responseFactory,
     CosmosQueryClientCore queryClient,
     string continuationToken,
     QueryRequestOptions cosmosQueryRequestOptions,
     bool allowSynchronousQueryExecution,
     CosmosSerializationOptions serializationOptions = null)
     : this(
         container,
         responseFactory,
         queryClient,
         continuationToken,
         cosmosQueryRequestOptions,
         null,
         allowSynchronousQueryExecution,
         serializationOptions)
 {
 }
        public async Task DeleteSendsCorrectPayload()
        {
            const string expectedId = "something";

            Cosmos.PartitionKey partitionKey = new Cosmos.PartitionKey("pk");
            Uri expectedRequestUri           = new Uri($"/dbs/conflictsDb/colls/conflictsColl/conflicts/{expectedId}", UriKind.Relative);
            ContainerInternal container      = CosmosConflictTests.GetMockedContainer((request, cancellationToken) => {
                Assert.AreEqual(OperationType.Delete, request.OperationType);
                Assert.AreEqual(ResourceType.Conflict, request.ResourceType);
                Assert.AreEqual(expectedRequestUri, request.RequestUri);
                return(TestHandler.ReturnSuccess());
            });

            ConflictProperties conflictSettings = new ConflictProperties();

            conflictSettings.Id = expectedId;

            await container.Conflicts.DeleteAsync(conflictSettings, partitionKey);
        }
Ejemplo n.º 9
0
 public ChangeFeedEstimatorIterator(
     string processorName,
     ContainerInternal monitoredContainer,
     ContainerInternal leaseContainer,
     ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions)
     : this(
         processorName,
         monitoredContainer,
         leaseContainer,
         changeFeedEstimatorRequestOptions,
         (DocumentServiceLease lease, string continuationToken, bool startFromBeginning) => ChangeFeedPartitionKeyResultSetIteratorCore.Create(
             lease : lease,
             continuationToken : continuationToken,
             maxItemCount : 1,
             container : monitoredContainer,
             startTime : null,
             startFromBeginning : string.IsNullOrEmpty(continuationToken)))
 {
 }
        public async Task ReadFeedIteratorCore_HandlesSplitsThroughPipeline()
        {
            int executionCount = 0;
            CosmosClientContext cosmosClientContext = GetMockedClientContext((RequestMessage requestMessage, CancellationToken cancellationToken) =>
            {
                // Force OnBeforeRequestActions call
                requestMessage.ToDocumentServiceRequest();
                if (executionCount++ == 0)
                {
                    return(TestHandler.ReturnStatusCode(HttpStatusCode.Gone, Documents.SubStatusCodes.PartitionKeyRangeGone));
                }

                return(TestHandler.ReturnStatusCode(HttpStatusCode.OK));
            });

            ContainerInternal containerCore = Mock.Of <ContainerInternal>();

            Mock.Get(containerCore)
            .Setup(c => c.ClientContext)
            .Returns(cosmosClientContext);
            Mock.Get(containerCore)
            .Setup(c => c.LinkUri)
            .Returns(new Uri($"/dbs/db/colls/colls", UriKind.Relative));
            FeedRangeInternal range = Mock.Of <FeedRangeInternal>();

            Mock.Get(range)
            .Setup(f => f.Accept(It.IsAny <FeedRangeRequestMessagePopulatorVisitor>()));
            FeedRangeContinuation feedToken = Mock.Of <FeedRangeContinuation>();

            Mock.Get(feedToken)
            .Setup(f => f.FeedRange)
            .Returns(range);
            Mock.Get(feedToken)
            .Setup(f => f.HandleSplitAsync(It.Is <ContainerInternal>(c => c == containerCore), It.IsAny <ResponseMessage>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(Documents.ShouldRetryResult.NoRetry()));

            FeedRangeIteratorCore changeFeedIteratorCore = new FeedRangeIteratorCore(containerCore, feedToken, new QueryRequestOptions(), Documents.ResourceType.Document, queryDefinition: null);

            ResponseMessage response = await changeFeedIteratorCore.ReadNextAsync();

            Assert.AreEqual(1, executionCount, "Pipeline handled the Split");
            Assert.AreEqual(HttpStatusCode.Gone, response.StatusCode);
        }
        public static async Task ClassInitialize(TestContext context)
        {
            EncryptionTests.dekProvider = new CosmosDataEncryptionKeyProvider(new TestKeyWrapProvider());
            EncryptionTests.encryptor   = new TestEncryptor(EncryptionTests.dekProvider);

            EncryptionTests.client       = EncryptionTests.GetClient();
            EncryptionTests.databaseCore = (DatabaseInlineCore)await EncryptionTests.client.CreateDatabaseAsync(Guid.NewGuid().ToString());

            EncryptionTests.keyContainer = await EncryptionTests.databaseCore.CreateContainerAsync(Guid.NewGuid().ToString(), "/id", 400);

            await EncryptionTests.dekProvider.InitializeAsync(EncryptionTests.databaseCore, EncryptionTests.keyContainer.Id);


            EncryptionTests.itemContainer = await EncryptionTests.databaseCore.CreateContainerAsync(Guid.NewGuid().ToString(), "/PK", 400);

            EncryptionTests.itemContainerCore = (ContainerInlineCore)EncryptionTests.itemContainer;

            EncryptionTests.dekProperties = await EncryptionTests.CreateDekAsync(EncryptionTests.dekProvider, EncryptionTests.dekId);
        }
        public static ChangeFeedPartitionKeyResultSetIteratorCore Create(
            DocumentServiceLease lease,
            string continuationToken,
            int?maxItemCount,
            ContainerInternal container,
            DateTime?startTime,
            bool startFromBeginning)
        {
            // If the lease represents a full partition (old schema) then use a FeedRangePartitionKeyRange
            // If the lease represents an EPK range (new schema) the use the FeedRange in the lease
            FeedRangeInternal feedRange = lease is DocumentServiceLeaseCoreEpk ? lease.FeedRange : new FeedRangePartitionKeyRange(lease.CurrentLeaseToken);

            ChangeFeedStartFrom startFrom;

            if (continuationToken != null)
            {
                // For continuation based feed range we need to manufactor a new continuation token that has the partition key range id in it.
                startFrom = new ChangeFeedStartFromContinuationAndFeedRange(continuationToken, feedRange);
            }
            else if (startTime.HasValue)
            {
                startFrom = ChangeFeedStartFrom.Time(startTime.Value, feedRange);
            }
            else if (startFromBeginning)
            {
                startFrom = ChangeFeedStartFrom.Beginning(feedRange);
            }
            else
            {
                startFrom = ChangeFeedStartFrom.Now(feedRange);
            }

            ChangeFeedRequestOptions requestOptions = new ChangeFeedRequestOptions()
            {
                PageSizeHint = maxItemCount,
            };

            return(new ChangeFeedPartitionKeyResultSetIteratorCore(
                       container: container,
                       changeFeedStartFrom: startFrom,
                       options: requestOptions));
        }
        public async Task TestPassthroughQueryAsync()
        {
            string[] inputDocs = new[]
            {
                @"{""id"":""documentId1"",""key"":""A"",""prop"":3,""shortArray"":[{""a"":5}]}",
                @"{""id"":""documentId2"",""key"":""A"",""prop"":2,""shortArray"":[{""a"":6}]}",
                @"{""id"":""documentId3"",""key"":""A"",""prop"":1,""shortArray"":[{""a"":7}]}",
                @"{""id"":""documentId4"",""key"":5,""prop"":3,""shortArray"":[{""a"":5}]}",
                @"{""id"":""documentId5"",""key"":5,""prop"":2,""shortArray"":[{""a"":6}]}",
                @"{""id"":""documentId6"",""key"":5,""prop"":1,""shortArray"":[{""a"":7}]}",
                @"{""id"":""documentId10"",""prop"":3,""shortArray"":[{""a"":5}]}",
                @"{""id"":""documentId11"",""prop"":2,""shortArray"":[{""a"":6}]}",
                @"{""id"":""documentId12"",""prop"":1,""shortArray"":[{""a"":7}]}",
            };

            await this.CreateIngestQueryDeleteAsync(
                ConnectionModes.Direct,
                CollectionTypes.SinglePartition | CollectionTypes.MultiPartition,
                inputDocs,
                ImplementationAsync,
                "/key");

            async Task ImplementationAsync(Container container, IReadOnlyList <CosmosObject> documents)
            {
                foreach (int maxDegreeOfParallelism in new int[] { 1, 100 })
                {
                    foreach (int maxItemCount in new int[] { 10, 100 })
                    {
                        ContainerInternal containerCore = (ContainerInlineCore)container;

                        foreach (bool isGatewayQueryPlan in new bool[] { true, false })
                        {
                            foreach (Cosmos.PartitionKey?partitionKey in new Cosmos.PartitionKey?[] { new Cosmos.PartitionKey(5), default })
                            {
                                QueryRequestOptions feedOptions = new QueryRequestOptions
                                {
                                    MaxBufferedItemCount = 7000,
                                    MaxConcurrency       = maxDegreeOfParallelism,
                                    MaxItemCount         = maxItemCount,
                                };

                                async Task <List <CosmosElement> > AssertPassthroughAsync(string query, Cosmos.PartitionKey?pk = default)
        public void ApplyBuildConfiguration(
            DocumentServiceLeaseStoreManager customDocumentServiceLeaseStoreManager,
            ContainerInternal leaseContainer,
            string instanceName,
            ChangeFeedLeaseOptions changeFeedLeaseOptions,
            ChangeFeedProcessorOptions changeFeedProcessorOptions,
            ContainerInternal monitoredContainer)
        {
            if (customDocumentServiceLeaseStoreManager == null && leaseContainer == null)
            {
                throw new ArgumentNullException(nameof(leaseContainer));
            }

            this.documentServiceLeaseStoreManager = customDocumentServiceLeaseStoreManager;
            this.leaseContainer             = leaseContainer;
            this.instanceName               = instanceName ?? throw new ArgumentNullException("InstanceName is required for the processor to initialize.");
            this.changeFeedProcessorOptions = changeFeedProcessorOptions;
            this.changeFeedLeaseOptions     = changeFeedLeaseOptions;
            this.monitoredContainer         = monitoredContainer ?? throw new ArgumentNullException(nameof(monitoredContainer));
        }
        public async Task ReadCurrentGetsCorrectRID()
        {
            const string expectedRID = "something";

            Cosmos.PartitionKey partitionKey = new Cosmos.PartitionKey("pk");
            // Using "test" as container name because the Mocked DocumentClient has it hardcoded
            Uri expectedRequestUri      = new Uri($"dbs/conflictsDb/colls/test/docs/{expectedRID}", UriKind.Relative);
            ContainerInternal container = CosmosConflictTests.GetMockedContainer((request, cancellationToken) => {
                Assert.AreEqual(OperationType.Read, request.OperationType);
                Assert.AreEqual(ResourceType.Document, request.ResourceType);
                Assert.AreEqual(expectedRequestUri, request.RequestUri);
                return(TestHandler.ReturnSuccess());
            });

            ConflictProperties conflictSettings = new ConflictProperties();

            conflictSettings.SourceResourceId = expectedRID;

            await container.Conflicts.ReadCurrentAsync <JObject>(conflictSettings, partitionKey);
        }
        public static ChangeFeedPartitionKeyResultSetIteratorCore BuildResultSetIterator(
            string partitionKeyRangeId,
            string continuationToken,
            int?maxItemCount,
            ContainerInternal container,
            DateTime?startTime,
            bool startFromBeginning)
        {
            FeedRangeInternal feedRange = new FeedRangePartitionKeyRange(partitionKeyRangeId);

            ChangeFeedStartFrom startFrom;

            if (continuationToken != null)
            {
                // For continuation based feed range we need to manufactor a new continuation token that has the partition key range id in it.
                startFrom = new ChangeFeedStartFromContinuationAndFeedRange(continuationToken, feedRange);
            }
            else if (startTime.HasValue)
            {
                startFrom = ChangeFeedStartFrom.Time(startTime.Value, feedRange);
            }
            else if (startFromBeginning)
            {
                startFrom = ChangeFeedStartFrom.Beginning(feedRange);
            }
            else
            {
                startFrom = ChangeFeedStartFrom.Now(feedRange);
            }

            ChangeFeedRequestOptions requestOptions = new ChangeFeedRequestOptions()
            {
                PageSizeHint = maxItemCount,
            };

            return(new ChangeFeedPartitionKeyResultSetIteratorCore(
                       clientContext: container.ClientContext,
                       container: container,
                       changeFeedStartFrom: startFrom,
                       options: requestOptions));
        }
Ejemplo n.º 17
0
        public async Task ChangeFeedIteratorCore_EmptyBeginning()
        {
            int  totalCount        = 0;
            int  expectedDocuments = 5;
            bool createdDocuments  = false;

            ContainerInternal itemsCore = await this.InitializeContainerAsync();

            ChangeFeedIteratorCore feedIterator = itemsCore.GetChangeFeedStreamIterator(
                ChangeFeedStartFrom.Beginning(),
                ChangeFeedMode.Incremental) as ChangeFeedIteratorCore;

            while (feedIterator.HasMoreResults ||
                   (createdDocuments && totalCount == 0))
            {
                using (ResponseMessage responseMessage =
                           await feedIterator.ReadNextAsync(this.cancellationToken))
                {
                    if (responseMessage.IsSuccessStatusCode)
                    {
                        Collection <ToDoActivity> response = TestCommon.SerializerCore.FromStream <CosmosFeedResponseUtil <ToDoActivity> >(responseMessage.Content).Data;
                        totalCount += response.Count;
                    }
                    else
                    {
                        if (!createdDocuments)
                        {
                            await this.CreateRandomItems(itemsCore, expectedDocuments, randomPartitionKey : true);

                            createdDocuments = true;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

            Assert.AreEqual(expectedDocuments, totalCount);
        }
Ejemplo n.º 18
0
        public async Task ChangeFeedIteratorCore_CannotMixTokensFromOtherContainers()
        {
            ContainerInternal oneContainer = await this.InitializeContainerAsync();

            ContainerInternal otherContainer = await this.InitializeContainerAsync();

            IReadOnlyList <FeedRange> tokens = await oneContainer.GetFeedRangesAsync();

            FeedIterator iterator = oneContainer.GetChangeFeedStreamIterator(
                ChangeFeedStartFrom.Beginning(tokens[0]),
                ChangeFeedMode.Incremental);
            ResponseMessage responseMessage = await iterator.ReadNextAsync();

            iterator = otherContainer.GetChangeFeedStreamIterator(
                ChangeFeedStartFrom.ContinuationToken(responseMessage.ContinuationToken),
                ChangeFeedMode.Incremental);
            responseMessage = await iterator.ReadNextAsync();

            Assert.IsNotNull(responseMessage.CosmosException);
            Assert.AreEqual(HttpStatusCode.BadRequest, responseMessage.StatusCode);
        }
        public async Task TestInitialize()
        {
            this.cancellationTokenSource = new CancellationTokenSource();
            this.cancellationToken       = this.cancellationTokenSource.Token;

            this.cosmosClient = TestCommon.CreateCosmosClient();
            this.database     = await this.cosmosClient.CreateDatabaseAsync(Guid.NewGuid().ToString(),
                                                                            cancellationToken : this.cancellationToken);

            this.documentClient = TestCommon.CreateClient(true, defaultConsistencyLevel: Documents.ConsistencyLevel.Session);

            string            PartitionKey = "/partitionKey";
            ContainerResponse response     = await this.database.CreateContainerAsync(
                new ContainerProperties(id : Guid.NewGuid().ToString(), partitionKeyPath : PartitionKey),
                cancellationToken : this.cancellationToken);

            Assert.IsNotNull(response);
            Assert.IsNotNull(response.Container);
            Assert.IsNotNull(response.Resource);
            this.Container = (ContainerInlineCore)response;
        }
        public async Task TestInitialize()
        {
            await base.TestInit();

            string            PartitionKey = "/status";
            ContainerResponse response     = await this.database.CreateContainerAsync(
                new ContainerProperties(id : Guid.NewGuid().ToString(), partitionKeyPath : PartitionKey),
                cancellationToken : this.cancellationToken);

            Assert.IsNotNull(response);
            Assert.IsNotNull(response.Container);
            Assert.IsNotNull(response.Resource);

            ContainerResponse largerContainer = await this.database.CreateContainerAsync(
                new ContainerProperties(id : Guid.NewGuid().ToString(), partitionKeyPath : PartitionKey),
                throughput : 20000,
                cancellationToken : this.cancellationToken);

            this.Container       = (ContainerInlineCore)response;
            this.LargerContainer = (ContainerInlineCore)largerContainer;
        }
        public async Task VerifyPatchItemStreamOperation()
        {
            ResponseMessage    response       = null;
            ItemRequestOptions requestOptions = null;
            Mock <Stream>      mockPayload    = new Mock <Stream>();
            HttpStatusCode     httpStatusCode = HttpStatusCode.OK;
            int         testHandlerHitCount   = 0;
            TestHandler testHandler           = new TestHandler((request, cancellationToken) =>
            {
                Assert.IsTrue(request.RequestUri.OriginalString.StartsWith(@"dbs/testdb/colls/testcontainer/docs/cdbBinaryIdRequest"));
                Assert.AreEqual(Cosmos.PartitionKey.Null.ToJsonString(), request.Headers.PartitionKey);
                Assert.AreEqual(ResourceType.Document, request.ResourceType);
                Assert.AreEqual(OperationType.Patch, request.OperationType);
                Assert.AreEqual(mockPayload.Object, request.Content);
                Assert.AreEqual(requestOptions, request.RequestOptions);
                testHandlerHitCount++;
                response = new ResponseMessage(httpStatusCode, request, errorMessage: null)
                {
                    Content = request.Content
                };
                return(Task.FromResult(response));
            });

            CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(
                (builder) => builder.AddCustomHandlers(testHandler));

            Container container = client.GetDatabase("testdb")
                                  .GetContainer("testcontainer");

            ContainerInternal containerInternal = (ContainerInternal)container;
            ResponseMessage   responseMessage   = await containerInternal.PatchItemStreamAsync(
                id : "cdbBinaryIdRequest",
                partitionKey : Cosmos.PartitionKey.Null,
                streamPayload : mockPayload.Object,
                requestOptions : requestOptions);

            Assert.IsNotNull(responseMessage);
            Assert.AreEqual(httpStatusCode, responseMessage.StatusCode);
            Assert.AreEqual(1, testHandlerHitCount, "The operation did not make it to the handler");
        }
Ejemplo n.º 22
0
            internal CosmosChangeFeedResultSetIteratorCoreMock(
                ContainerInternal container,
                string continuationToken,
                int?maxItemCount,
                StandByFeedIteratorRequestOptions options) : base(
                    clientContext: container.ClientContext,
                    container: container,
                    continuationToken: continuationToken,
                    maxItemCount: maxItemCount,
                    options: options)
            {
                List <CompositeContinuationToken> compositeContinuationTokens = new List <CompositeContinuationToken>()
                {
                    new CompositeContinuationToken()
                    {
                        Token = null,
                        Range = new Documents.Routing.Range <string>("A", "B", true, false)
                    }
                };

                string serialized = JsonConvert.SerializeObject(compositeContinuationTokens);

                this.compositeContinuationToken = StandByFeedContinuationToken.CreateAsync("containerRid", serialized, (string containerRid, Documents.Routing.Range <string> ranges, bool forceRefresh) =>
                {
                    IReadOnlyList <Documents.PartitionKeyRange> filteredRanges = new List <Documents.PartitionKeyRange>()
                    {
                        new Documents.PartitionKeyRange()
                        {
                            MinInclusive = "A", MaxExclusive = "B", Id = "0"
                        }
                    };

                    if (forceRefresh)
                    {
                        this.HasCalledForceRefresh = true;
                    }

                    return(Task.FromResult(filteredRanges));
                }).Result;
            }
Ejemplo n.º 23
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);
Ejemplo n.º 24
0
        public async Task StandByFeedIterator_WithInexistentRange()
        {
            // Add some random range, this will force the failure
            List <CompositeContinuationToken> corruptedTokens = new List <CompositeContinuationToken>
            {
                new CompositeContinuationToken()
                {
                    Range = new Documents.Routing.Range <string>("whatever", "random", true, false),
                    Token = "oops"
                }
            };

            string corruptedTokenSerialized = JsonConvert.SerializeObject(corruptedTokens);

            ContainerInternal itemsCore      = this.Container;
            FeedIterator      setIteratorNew =
                itemsCore.GetStandByFeedIterator(corruptedTokenSerialized);

            ResponseMessage responseMessage = await setIteratorNew.ReadNextAsync(this.cancellationToken);

            Assert.Fail("Should have thrown.");
        }
        internal static async Task <DocumentServiceLeaseStoreManager> InitializeLeaseStoreManagerAsync(
            DocumentServiceLeaseStoreManager documentServiceLeaseStoreManager,
            ContainerInternal leaseContainer,
            string leaseContainerPrefix,
            string instanceName)
        {
            if (documentServiceLeaseStoreManager == null)
            {
                ContainerResponse cosmosContainerResponse = await leaseContainer.ReadContainerAsync().ConfigureAwait(false);

                ContainerProperties containerProperties = cosmosContainerResponse.Resource;

                bool isPartitioned =
                    containerProperties.PartitionKey != null &&
                    containerProperties.PartitionKey.Paths != null &&
                    containerProperties.PartitionKey.Paths.Count > 0;
                bool isMigratedFixed = (containerProperties.PartitionKey?.IsSystemKey == true);
                if (isPartitioned &&
                    !isMigratedFixed &&
                    (containerProperties.PartitionKey.Paths.Count != 1 || containerProperties.PartitionKey.Paths[0] != "/id"))
                {
                    throw new ArgumentException("The lease collection, if partitioned, must have partition key equal to id.");
                }

                RequestOptionsFactory requestOptionsFactory = isPartitioned && !isMigratedFixed ?
                                                              (RequestOptionsFactory) new PartitionedByIdCollectionRequestOptionsFactory() :
                                                              (RequestOptionsFactory) new SinglePartitionRequestOptionsFactory();

                DocumentServiceLeaseStoreManagerBuilder leaseStoreManagerBuilder = new DocumentServiceLeaseStoreManagerBuilder()
                                                                                   .WithLeasePrefix(leaseContainerPrefix)
                                                                                   .WithLeaseContainer(leaseContainer)
                                                                                   .WithRequestOptionsFactory(requestOptionsFactory)
                                                                                   .WithHostName(instanceName);

                documentServiceLeaseStoreManager = await leaseStoreManagerBuilder.BuildAsync().ConfigureAwait(false);
            }

            return(documentServiceLeaseStoreManager);
        }
Ejemplo n.º 26
0
        private ChangeFeedEstimatorIterator(
            string processorName,
            ContainerInternal monitoredContainer,
            ContainerInternal leaseContainer,
            ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions,
            Func <string, string, bool, FeedIterator> monitoredContainerFeedCreator)
        {
            this.processorName      = processorName ?? throw new ArgumentNullException(nameof(processorName));
            this.monitoredContainer = monitoredContainer ?? throw new ArgumentNullException(nameof(monitoredContainer));
            this.leaseContainer     = leaseContainer ?? throw new ArgumentNullException(nameof(leaseContainer));
            this.changeFeedEstimatorRequestOptions = changeFeedEstimatorRequestOptions ?? new ChangeFeedEstimatorRequestOptions();
            if (this.changeFeedEstimatorRequestOptions.MaxItemCount.HasValue &&
                this.changeFeedEstimatorRequestOptions.MaxItemCount.Value <= 0)
            {
                throw new ArgumentOutOfRangeException($"{nameof(this.changeFeedEstimatorRequestOptions.MaxItemCount)} value should be a positive integer.");
            }

            this.lazyLeaseDocuments = new AsyncLazy <TryCatch <IReadOnlyList <DocumentServiceLease> > >(valueFactory: (innerCancellationToken) => this.TryInitializeLeaseDocumentsAsync(innerCancellationToken));
            this.hasMoreResults     = true;

            this.monitoredContainerFeedCreator = monitoredContainerFeedCreator;
        }
Ejemplo n.º 27
0
        public async Task TestInitialize()
        {
            CosmosClientOptions clientOptions = new CosmosClientOptions()
            {
                SendingRequestEventArgs = this.SendingRequestEventHandlerUdfVerifier,
            };

            this.cosmosClient = TestCommon.CreateCosmosClient(clientOptions);
            this.database     = await this.cosmosClient.CreateDatabaseAsync(Guid.NewGuid().ToString(),
                                                                            cancellationToken : this.cancellationToken);

            string            PartitionKey = "/pk";
            ContainerResponse response     = await this.database.CreateContainerAsync(
                new ContainerProperties(id : Guid.NewGuid().ToString(), partitionKeyPath : PartitionKey),
                cancellationToken : this.cancellationToken);

            Assert.IsNotNull(response);
            Assert.IsNotNull(response.Container);
            Assert.IsNotNull(response.Resource);
            this.container = (ContainerInlineCore)response;
            this.scripts   = this.container.Scripts;
        }
Ejemplo n.º 28
0
        private async Task VerifyPartitionKeyDeleteOperation(
            Cosmos.PartitionKey partitionKey,
            string partitionKeySerialized,
            RequestOptions requestOptions = null)
        {
            ResponseMessage response            = null;
            HttpStatusCode  httpStatusCode      = HttpStatusCode.OK;
            int             testHandlerHitCount = 0;
            TestHandler     testHandler         = new TestHandler((request, cancellationToken) =>
            {
                Assert.IsTrue(request.RequestUri.OriginalString.StartsWith(@"dbs/testdb/colls/testcontainer"));
                Assert.AreEqual(requestOptions, request.RequestOptions);
                Assert.AreEqual(ResourceType.PartitionKey, request.ResourceType);
                Assert.IsNotNull(request.Headers.PartitionKey);
                Assert.AreEqual(partitionKeySerialized, request.Headers.PartitionKey);
                testHandlerHitCount++;
                response = new ResponseMessage(httpStatusCode, request, errorMessage: null)
                {
                    Content = request.Content
                };
                return(Task.FromResult(response));
            });

            CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(
                (builder) => builder.AddCustomHandlers(testHandler));

            Container container = client.GetDatabase("testdb")
                                  .GetContainer("testcontainer");

            ContainerInternal containerInternal = (ContainerInternal)container;
            ResponseMessage   responseMessage   = await containerInternal.DeleteAllItemsByPartitionKeyStreamAsync(
                partitionKey : partitionKey,
                requestOptions : requestOptions);

            Assert.IsNotNull(responseMessage);
            Assert.AreEqual(httpStatusCode, responseMessage.StatusCode);
            Assert.AreEqual(1, testHandlerHitCount, "The operation did not make it to the handler");
        }
Ejemplo n.º 29
0
        public async Task StandByFeedIterator_EmptyBeginning()
        {
            int  totalCount        = 0;
            int  expectedDocuments = 5;
            bool createdDocuments  = false;

            ContainerInternal itemsCore    = this.Container;
            FeedIterator      feedIterator = itemsCore.GetStandByFeedIterator();

            while (feedIterator.HasMoreResults)
            {
                using (ResponseMessage responseMessage =
                           await feedIterator.ReadNextAsync(this.cancellationToken))
                {
                    Assert.AreEqual(responseMessage.ContinuationToken, responseMessage.Headers.ContinuationToken);
                    if (responseMessage.IsSuccessStatusCode)
                    {
                        Collection <ToDoActivity> response = TestCommon.SerializerCore.FromStream <CosmosFeedResponseUtil <ToDoActivity> >(responseMessage.Content).Data;
                        totalCount += response.Count;
                    }
                    else
                    {
                        if (!createdDocuments)
                        {
                            await this.CreateRandomItems(this.Container, expectedDocuments, randomPartitionKey : true);

                            createdDocuments = true;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

            Assert.AreEqual(expectedDocuments, totalCount);
        }
        public async Task ChangeFeedIteratorCore_OfT_ReadAll()
        {
            int totalCount    = 0;
            int firstRunTotal = 25;
            int batchSize     = 25;

            await this.CreateRandomItems(this.Container, batchSize, randomPartitionKey : true);

            ContainerInternal           itemsCore    = this.Container;
            FeedIterator <ToDoActivity> feedIterator = itemsCore.GetChangeFeedIterator <ToDoActivity>(ChangeFeedStartFrom.Beginning());
            string continuation = null;

            while (feedIterator.HasMoreResults)
            {
                FeedResponse <ToDoActivity> feedResponse = await feedIterator.ReadNextAsync(this.cancellationToken);

                totalCount  += feedResponse.Count;
                continuation = feedResponse.ContinuationToken;
            }

            Assert.AreEqual(firstRunTotal, totalCount);

            int expectedFinalCount = 50;

            // Insert another batch of 25 and use the last FeedToken from the first cycle
            await this.CreateRandomItems(this.Container, batchSize, randomPartitionKey : true);

            FeedIterator <ToDoActivity> setIteratorNew = itemsCore.GetChangeFeedIterator <ToDoActivity>(ChangeFeedStartFrom.ContinuationToken(continuation));

            while (setIteratorNew.HasMoreResults)
            {
                FeedResponse <ToDoActivity> feedResponse = await setIteratorNew.ReadNextAsync(this.cancellationToken);

                totalCount += feedResponse.Count;
            }

            Assert.AreEqual(expectedFinalCount, totalCount);
        }