コード例 #1
0
        public void ValidateTransformQuery()
        {
            DocumentClient client = TestCommon.CreateClient(true);

            IQueryable <dynamic> dbQuery = client.CreateDatabaseQuery(@"select * from root r where r.id=""db123""").AsQueryable();

            foreach (CosmosDatabaseSettings db in dbQuery)
            {
                TestCommon.Delete <CosmosDatabaseSettings>(client, db.ResourceId);
            }

            CosmosDatabaseSettings database = client.Create <CosmosDatabaseSettings>(null,
                                                                                     new CosmosDatabaseSettings {
                Id = "db123"
            });

            dbQuery = client.CreateDatabaseQuery(@"select * from root r where r.id=""db123""").AsQueryable();
            foreach (CosmosDatabaseSettings db in dbQuery)
            {
                Assert.AreEqual(db.Id, "db123");
            }
            Assert.AreNotEqual(0, System.Linq.Dynamic.Core.DynamicQueryableExtensions.AsEnumerable(dbQuery).Count());

            IQueryable <dynamic> dbIdQuery = client.CreateDatabaseQuery(@"select r._rid from root r where r.id=""db123""").AsQueryable();

            Assert.AreNotEqual(0, System.Linq.Dynamic.Core.DynamicQueryableExtensions.AsEnumerable(dbIdQuery).Count());

            CosmosContainerSettings collection = new CosmosContainerSettings
            {
                Id = Guid.NewGuid().ToString("N")
            };

            collection.IndexingPolicy.IndexingMode = IndexingMode.Consistent;

            collection = client.Create <CosmosContainerSettings>(database.ResourceId, collection);
            int documentsToCreate = 100;

            for (int i = 0; i < documentsToCreate; i++)
            {
                dynamic myDocument = new Document();
                myDocument.Id        = "doc" + i;
                myDocument.Title     = "MyBook"; //Simple Property.
                myDocument.Languages = new Language[] { new Language {
                                                            Name = "English", Copyright = "London Publication"
                                                        }, new Language {
                                                            Name = "French", Copyright = "Paris Publication"
                                                        } };                                                                                                                                      //Array Property
                myDocument.Author = new Author {
                    Name = "Don", Location = "France"
                };                                                                    //Complex Property
                myDocument.Price = 9.99;
                myDocument       = client.CreateDocumentAsync(collection.DocumentsLink, myDocument).Result;
            }

            //Read response as dynamic.
            IQueryable <dynamic> docQuery = client.CreateDocumentQuery(collection.DocumentsLink, @"select * from root r where r.Title=""MyBook""", null);

            IDocumentQuery <dynamic> DocumentQuery = docQuery.AsDocumentQuery();
            FeedResponse <dynamic>   queryResponse = DocumentQuery.ExecuteNextAsync().Result;

            Assert.IsNotNull(queryResponse.ResponseHeaders, "ResponseHeaders is null");
            Assert.IsNotNull(queryResponse.ActivityId, "ActivityId is null");
            Assert.AreEqual(documentsToCreate, queryResponse.Count);

            foreach (dynamic myBook in queryResponse)
            {
                Assert.AreEqual(myBook.Title, "MyBook");
            }

            client.DeleteDocumentCollectionAsync(collection.SelfLink).Wait();
        }
コード例 #2
0
        /// <inheritdoc/>
        public async Task <List <Instance> > GetInstancesInStateOfInstanceOwner(int instanceOwnerPartyId, string instanceState)
        {
            List <Instance> instances = new List <Instance>();
            string          instanceOwnerPartyIdString = instanceOwnerPartyId.ToString();

            FeedOptions feedOptions = new FeedOptions
            {
                PartitionKey = new PartitionKey(instanceOwnerPartyIdString)
            };

            if (_settings.CollectMetrics)
            {
                feedOptions.PopulateQueryMetrics = true;
            }

            IQueryable <Instance> filter;

            if (instanceState.Equals("active"))
            {
                filter = _client.CreateDocumentQuery <Instance>(_collectionUri, feedOptions)
                         .Where(i => i.InstanceOwner.PartyId == instanceOwnerPartyIdString)
                         .Where(i => (!i.VisibleAfter.HasValue || i.VisibleAfter <= DateTime.UtcNow))
                         .Where(i => !i.Status.IsSoftDeleted)
                         .Where(i => !i.Status.IsHardDeleted)
                         .Where(i => !i.Status.IsArchived);
            }
            else if (instanceState.Equals("deleted"))
            {
                filter = _client.CreateDocumentQuery <Instance>(_collectionUri, feedOptions)
                         .Where(i => i.InstanceOwner.PartyId == instanceOwnerPartyIdString)
                         .Where(i => i.Status.IsSoftDeleted)
                         .Where(i => !i.Status.IsHardDeleted);
            }
            else if (instanceState.Equals("archived"))
            {
                filter = _client.CreateDocumentQuery <Instance>(_collectionUri, feedOptions)
                         .Where(i => i.InstanceOwner.PartyId == instanceOwnerPartyIdString)
                         .Where(i => i.Status.IsArchived)
                         .Where(i => !i.Status.IsSoftDeleted)
                         .Where(i => !i.Status.IsHardDeleted)
                         .OrderByDescending(i => i.Status.Archived);
            }
            else
            {
                // empty list
                return(instances);
            }

            IDocumentQuery <Instance> query = filter.AsDocumentQuery();

            FeedResponse <Instance> feedResponse = await query.ExecuteNextAsync <Instance>();

            if (_settings.CollectMetrics)
            {
                _logger.LogError($"Metrics retrieving {instanceState} instances for {instanceOwnerPartyId}: {JsonConvert.SerializeObject(feedResponse.QueryMetrics)}");
            }

            instances = feedResponse.ToList();

            await PostProcess(instances);

            return(instances);
        }
コード例 #3
0
        private async Task <List <T> > ToListAsync <T>(QueryStream createStreamQuery, Query <T> createQuery, string queryText)
        {
            FeedIterator feedStreamIterator = createStreamQuery(queryText, null, RequestOptions);
            List <T>     streamResults      = new List <T>();

            while (feedStreamIterator.HasMoreResults)
            {
                ResponseMessage response = await feedStreamIterator.ReadNextAsync();

                response.EnsureSuccessStatusCode();

                StreamReader sr     = new StreamReader(response.Content);
                string       result = await sr.ReadToEndAsync();

                ICollection <T> responseResults = JsonConvert.DeserializeObject <CosmosFeedResponseUtil <T> >(result).Data;
                Assert.IsTrue(responseResults.Count <= 1);

                streamResults.AddRange(responseResults);
            }

            string   continuationToken  = null;
            List <T> pagedStreamResults = new List <T>();

            do
            {
                FeedIterator    pagedFeedIterator = createStreamQuery(queryText, continuationToken, RequestOptions);
                ResponseMessage response          = await pagedFeedIterator.ReadNextAsync();

                response.EnsureSuccessStatusCode();

                ICollection <T> responseResults = TestCommon.Serializer.FromStream <CosmosFeedResponseUtil <T> >(response.Content).Data;
                Assert.IsTrue(responseResults.Count <= 1);

                pagedStreamResults.AddRange(responseResults);
                continuationToken = response.Headers.ContinuationToken;
            } while (continuationToken != null);

            Assert.AreEqual(pagedStreamResults.Count, streamResults.Count);

            // Both lists should be the same
            string streamResultString      = JsonConvert.SerializeObject(streamResults);
            string streamPagedResultString = JsonConvert.SerializeObject(pagedStreamResults);

            Assert.AreEqual(streamPagedResultString, streamResultString);

            FeedIterator <T> feedIterator = createQuery(queryText, null, RequestOptions);
            List <T>         results      = new List <T>();

            while (feedIterator.HasMoreResults)
            {
                FeedResponse <T> iterator = await feedIterator.ReadNextAsync();

                Assert.IsTrue(iterator.Count <= 1);
                Assert.IsTrue(iterator.Resource.Count() <= 1);

                results.AddRange(iterator);
            }

            continuationToken = null;
            List <T> pagedResults = new List <T>();

            do
            {
                FeedIterator <T> pagedFeedIterator = createQuery(queryText, continuationToken, RequestOptions);
                FeedResponse <T> iterator          = await pagedFeedIterator.ReadNextAsync();

                Assert.IsTrue(iterator.Count <= 1);
                Assert.IsTrue(iterator.Resource.Count() <= 1);
                pagedResults.AddRange(iterator);
                continuationToken = iterator.ContinuationToken;
            } while (continuationToken != null);

            Assert.AreEqual(pagedResults.Count, results.Count);

            // Both lists should be the same
            string resultString      = JsonConvert.SerializeObject(results);
            string pagedResultString = JsonConvert.SerializeObject(pagedResults);

            Assert.AreEqual(pagedResultString, resultString);

            Assert.AreEqual(streamPagedResultString, resultString);
            return(results);
        }
コード例 #4
0
        public async Task ChangeFeedIteratorCore_PartitionKey_OfT_ReadAll()
        {
            int totalCount    = 0;
            int firstRunTotal = 25;
            int batchSize     = 25;

            string pkToRead = "pkToRead";
            string otherPK  = "otherPK";

            for (int i = 0; i < batchSize; i++)
            {
                await this.Container.CreateItemAsync(this.CreateRandomToDoActivity(pkToRead));
            }

            for (int i = 0; i < batchSize; i++)
            {
                await this.Container.CreateItemAsync(this.CreateRandomToDoActivity(otherPK));
            }

            ContainerCore itemsCore = this.Container;
            FeedIterator <ToDoActivity> feedIterator = itemsCore.GetChangeFeedIterator <ToDoActivity>(new PartitionKey(pkToRead), changeFeedRequestOptions: new ChangeFeedRequestOptions()
            {
                StartTime = DateTime.MinValue.ToUniversalTime()
            });

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

                totalCount += feedResponse.Count;
                foreach (ToDoActivity toDoActivity in feedResponse)
                {
                    Assert.AreEqual(pkToRead, toDoActivity.status);
                }
            }

            Assert.AreEqual(firstRunTotal, totalCount);

            int expectedFinalCount = 50;

            // Insert another batch of 25 and use the last FeedToken from the first cycle
            for (int i = 0; i < batchSize; i++)
            {
                await this.Container.CreateItemAsync(this.CreateRandomToDoActivity(pkToRead));
            }

            FeedIterator <ToDoActivity> setIteratorNew = itemsCore.GetChangeFeedIterator <ToDoActivity>(feedToken: feedIterator.FeedToken, changeFeedRequestOptions: new ChangeFeedRequestOptions()
            {
                StartTime = DateTime.MinValue.ToUniversalTime()
            });

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

                totalCount += feedResponse.Count;
                foreach (ToDoActivity toDoActivity in feedResponse)
                {
                    Assert.AreEqual(pkToRead, toDoActivity.status);
                }
            }

            Assert.AreEqual(expectedFinalCount, totalCount);
        }
コード例 #5
0
        public async Task ContainerPartitionResourcePermissionTest(ConnectionMode connectionMode)
        {
            CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
            {
                ConnectionMode = connectionMode
            };

            CosmosClient cosmosClient = TestCommon.CreateCosmosClient(cosmosClientOptions);

            Database database = await cosmosClient.CreateDatabaseIfNotExistsAsync("PermissionTest");

            //create user
            string       userId       = Guid.NewGuid().ToString();
            UserResponse userResponse = await database.CreateUserAsync(userId);

            Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode);
            Assert.AreEqual(userId, userResponse.Resource.Id);
            User user = userResponse.User;

            //create resource
            string containerId = Guid.NewGuid().ToString();

            ContainerResponse containerResponse = await database.CreateContainerAsync(
                id : containerId,
                partitionKeyPath : "/id");

            Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode);
            Container container = containerResponse.Container;

            // Create items to read
            ToDoActivity itemAccess   = ToDoActivity.CreateRandomToDoActivity();
            ToDoActivity itemNoAccess = ToDoActivity.CreateRandomToDoActivity();

            await container.CreateItemAsync <ToDoActivity>(
                itemAccess,
                new PartitionKey(itemAccess.id));

            await container.CreateItemAsync <ToDoActivity>(
                itemNoAccess,
                new PartitionKey(itemNoAccess.id));

            //create permission
            string               permissionId         = Guid.NewGuid().ToString();
            PartitionKey         partitionKey         = new PartitionKey(itemAccess.id);
            PermissionProperties permissionProperties = new PermissionProperties(
                permissionId,
                PermissionMode.Read,
                container,
                partitionKey);

            PermissionResponse permissionResponse = await user.CreatePermissionAsync(permissionProperties);

            PermissionProperties permission = permissionResponse.Resource;

            Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode);
            Assert.AreEqual(permissionId, permission.Id);
            Assert.AreEqual(permissionProperties.PermissionMode, permission.PermissionMode);

            using (CosmosClient tokenCosmosClient = TestCommon.CreateCosmosClient(clientOptions: cosmosClientOptions, resourceToken: permission.Token))
            {
                Container tokenContainer = tokenCosmosClient.GetContainer(database.Id, containerId);
                await tokenContainer.ReadItemAsync <ToDoActivity>(itemAccess.id, new PartitionKey(itemAccess.id));

                try
                {
                    await tokenContainer.ReadItemAsync <ToDoActivity>(itemNoAccess.id, new PartitionKey(itemNoAccess.id));

                    Assert.Fail();
                }
                catch (CosmosException ex)
                {
                    Assert.AreEqual(HttpStatusCode.Forbidden, ex.StatusCode);
                }

                QueryRequestOptions queryRequestOptions = new QueryRequestOptions()
                {
                    PartitionKey = new PartitionKey(itemAccess.id)
                };

                FeedIterator <ToDoActivity> feedIterator = tokenContainer.GetItemQueryIterator <ToDoActivity>(
                    queryText: "select * from T",
                    requestOptions: queryRequestOptions);

                List <ToDoActivity> result = new List <ToDoActivity>();
                while (feedIterator.HasMoreResults)
                {
                    FeedResponse <ToDoActivity> toDoActivities = await feedIterator.ReadNextAsync();

                    result.AddRange(toDoActivities);
                }

                Assert.AreEqual(1, result.Count);

                // Test query with no service interop via gateway query plan to replicate x32 app
                ContainerInternal     containerCore = (ContainerInlineCore)tokenContainer;
                MockCosmosQueryClient mock          = new MockCosmosQueryClient(
                    clientContext: containerCore.ClientContext,
                    cosmosContainerCore: containerCore,
                    forceQueryPlanGatewayElseServiceInterop: true);

                Container tokenGatewayQueryPlan = new ContainerInlineCore(
                    containerCore.ClientContext,
                    (DatabaseInternal)containerCore.Database,
                    containerCore.Id,
                    mock);

                FeedIterator <ToDoActivity> feedIteratorGateway = tokenGatewayQueryPlan.GetItemQueryIterator <ToDoActivity>(
                    queryText: "select * from T",
                    requestOptions: queryRequestOptions);

                List <ToDoActivity> resultGateway = new List <ToDoActivity>();
                while (feedIteratorGateway.HasMoreResults)
                {
                    FeedResponse <ToDoActivity> toDoActivities = await feedIteratorGateway.ReadNextAsync();

                    resultGateway.AddRange(toDoActivities);
                }

                Assert.AreEqual(1, resultGateway.Count);
            }
        }
コード例 #6
0
ファイル: ProgramTools.cs プロジェクト: yashints/Az204-demos
        private static async Task RunBulkImport(DocumentClient client, string collectionLink)
        {
            string inputDirectory = @".\Data\";
            string inputFileMask  = "*.json";
            int    maxFiles       = 2000;
            int    maxScriptSize  = 50000;

            // 1. Get the files.
            string[]      fileNames = Directory.GetFiles(inputDirectory, inputFileMask);
            DirectoryInfo di        = new DirectoryInfo(inputDirectory);

            FileInfo[] fileInfos = di.GetFiles(inputFileMask);

            // 2. Prepare for import.
            int currentCount = 0;
            int fileCount    = maxFiles != 0 ? Math.Min(maxFiles, fileNames.Length) : fileNames.Length;

            // 3. Create stored procedure for this script.
            string          body  = File.ReadAllText(@".\JS\BulkImport.js");
            StoredProcedure sproc = new StoredProcedure
            {
                Id   = "BulkImport",
                Body = body
            };

            await TryDeleteStoredProcedure(client, collectionLink, sproc.Id);

            sproc = await client.CreateStoredProcedureAsync(collectionLink, sproc);

            Stopwatch sp = new Stopwatch();

            sp.Start();
            // 4. Create a batch of docs (MAX is limited by request size (2M) and to script for execution.
            // We send batches of documents to create to script.
            // Each batch size is determined by MaxScriptSize.
            // MaxScriptSize should be so that:
            // -- it fits into one request (MAX reqest size is 16Kb).
            // -- it doesn't cause the script to time out.
            // -- it is possible to experiment with MaxScriptSize to get best perf given number of throttles, etc.
            while (currentCount < fileCount)
            {
                // 5. Create args for current batch.
                //    Note that we could send a string with serialized JSON and JSON.parse it on the script side,
                //    but that would cause script to run longer. Since script has timeout, unload the script as much
                //    as we can and do the parsing by client and framework. The script will get JavaScript objects.
                string argsJson = CreateBulkInsertScriptArguments(fileNames, currentCount, fileCount, maxScriptSize);
                var    args     = new dynamic[] { JsonConvert.DeserializeObject <dynamic>(argsJson) };

                // 6. execute the batch.
                StoredProcedureResponse <int> scriptResult = await client.ExecuteStoredProcedureAsync <int>(
                    sproc.SelfLink,
                    args);

                // 7. Prepare for next batch.
                int currentlyInserted = scriptResult.Response;
                currentCount += currentlyInserted;
            }



            // 8. Validate
            int    numDocs      = 0;
            string continuation = string.Empty;

            do
            {
                // Read document feed and count the number of documents.
                FeedResponse <dynamic> response = await client.ReadDocumentFeedAsync(collectionLink, new FeedOptions { RequestContinuation = continuation });

                numDocs += response.Count;

                // Get the continuation so that we know when to stop.
                continuation = response.ResponseContinuation;
            }while (!string.IsNullOrEmpty(continuation));

            Console.WriteLine("Found {0} documents in the collection inserted in {1}ms\r\n", numDocs, sp.Elapsed.Milliseconds);
        }
コード例 #7
0
        protected override async Task <FeedResponse <CosmosElement> > ExecuteInternalAsync(CancellationToken token)
        {
            CollectionCache collectionCache = await this.Client.GetCollectionCacheAsync();

            PartitionKeyRangeCache partitionKeyRangeCache = await this.Client.GetPartitionKeyRangeCache();

            IDocumentClientRetryPolicy retryPolicyInstance = this.Client.ResetSessionTokenRetryPolicy.GetRequestPolicy();

            retryPolicyInstance = new InvalidPartitionExceptionRetryPolicy(collectionCache, retryPolicyInstance);
            if (base.ResourceTypeEnum.IsPartitioned())
            {
                retryPolicyInstance = new PartitionKeyRangeGoneRetryPolicy(
                    collectionCache,
                    partitionKeyRangeCache,
                    PathsHelper.GetCollectionPath(base.ResourceLink),
                    retryPolicyInstance);
            }

            return(await BackoffRetryUtility <FeedResponse <CosmosElement> > .ExecuteAsync(
                       async() =>
            {
                this.fetchExecutionRangeAccumulator.BeginFetchRange();
                ++this.retries;
                FeedResponse <CosmosElement> response = await this.ExecuteOnceAsync(retryPolicyInstance, token);
                if (!string.IsNullOrEmpty(response.ResponseHeaders[HttpConstants.HttpHeaders.QueryMetrics]))
                {
                    this.fetchExecutionRangeAccumulator.EndFetchRange(
                        response.ActivityId,
                        response.Count,
                        this.retries);
                    response = new FeedResponse <CosmosElement>(
                        response,
                        response.Count,
                        response.Headers,
                        response.UseETagAsContinuation,
                        new Dictionary <string, QueryMetrics>
                    {
                        {
                            SinglePartitionKeyId,
                            QueryMetrics.CreateFromDelimitedStringAndClientSideMetrics(
                                response.ResponseHeaders[HttpConstants.HttpHeaders.QueryMetrics],
                                new ClientSideMetrics(
                                    this.retries,
                                    response.RequestCharge,
                                    this.fetchExecutionRangeAccumulator.GetExecutionRanges(),
                                    string.IsNullOrEmpty(response.ResponseContinuation) ? new List <Tuple <string, SchedulingTimeSpan> >()
                            {
                                new Tuple <string, SchedulingTimeSpan>(SinglePartitionKeyId, this.fetchSchedulingMetrics.Elapsed)
                            } : new List <Tuple <string, SchedulingTimeSpan> >()))
                        }
                    },
                        response.RequestStatistics,
                        response.DisallowContinuationTokenMessage,
                        response.ResponseLengthBytes);
                }

                this.retries = -1;
                return response;
            },
                       retryPolicyInstance,
                       token));
        }
コード例 #8
0
        private async Task <List <T> > ToListAsync <T>(
            QueryStream createStreamQuery,
            Query <T> createQuery,
            string queryText,
            QueryRequestOptions requestOptions)
        {
            HttpStatusCode expectedStatus     = HttpStatusCode.OK;
            FeedIterator   feedStreamIterator = createStreamQuery(queryText, null, requestOptions);
            List <T>       streamResults      = new List <T>();

            while (feedStreamIterator.HasMoreResults)
            {
                ResponseMessage response = await feedStreamIterator.ReadNextAsync();

                response.EnsureSuccessStatusCode();
                Assert.AreEqual(expectedStatus, response.StatusCode);

                StreamReader sr     = new StreamReader(response.Content);
                string       result = await sr.ReadToEndAsync();

                ICollection <T> responseResults;
                responseResults = JsonConvert.DeserializeObject <CosmosFeedResponseUtil <T> >(result).Data;

                Assert.IsTrue(responseResults.Count <= 1);

                streamResults.AddRange(responseResults);
            }

            string   continuationToken  = null;
            List <T> pagedStreamResults = new List <T>();

            do
            {
                FeedIterator    pagedFeedIterator = createStreamQuery(queryText, continuationToken, requestOptions);
                ResponseMessage response          = await pagedFeedIterator.ReadNextAsync();

                response.EnsureSuccessStatusCode();
                Assert.AreEqual(expectedStatus, response.StatusCode);

                IEnumerable <T> responseResults = TestCommon.SerializerCore.FromStream <CosmosFeedResponseUtil <T> >(response.Content).Data;
                Assert.IsTrue(responseResults.Count() <= 1);

                pagedStreamResults.AddRange(responseResults);
                continuationToken = response.Headers.ContinuationToken;
                Assert.AreEqual(response.ContinuationToken, response.Headers.ContinuationToken);
            } while (continuationToken != null);

            Assert.AreEqual(pagedStreamResults.Count, streamResults.Count);

            // Both lists should be the same if not PermssionsProperties. PermissionProperties will have a different ResouceToken in the payload when read.
            string streamResultString      = JsonConvert.SerializeObject(streamResults);
            string streamPagedResultString = JsonConvert.SerializeObject(pagedStreamResults);

            if (typeof(T) != typeof(PermissionProperties))
            {
                Assert.AreEqual(streamPagedResultString, streamResultString);
            }

            FeedIterator <T> feedIterator = createQuery(queryText, null, requestOptions);
            List <T>         results      = new List <T>();

            while (feedIterator.HasMoreResults)
            {
                FeedResponse <T> response = await feedIterator.ReadNextAsync();

                Assert.AreEqual(expectedStatus, response.StatusCode);
                Assert.IsTrue(response.Count <= 1);
                Assert.IsTrue(response.Resource.Count() <= 1);

                results.AddRange(response);
            }

            continuationToken = null;
            List <T> pagedResults = new List <T>();

            do
            {
                FeedIterator <T> pagedFeedIterator = createQuery(queryText, continuationToken, requestOptions);
                FeedResponse <T> response          = await pagedFeedIterator.ReadNextAsync();

                Assert.AreEqual(expectedStatus, response.StatusCode);
                Assert.IsTrue(response.Count <= 1);
                Assert.IsTrue(response.Resource.Count() <= 1);
                pagedResults.AddRange(response);
                continuationToken = response.ContinuationToken;
            } while (continuationToken != null);

            Assert.AreEqual(pagedResults.Count, results.Count);

            // Both lists should be the same
            string resultString      = JsonConvert.SerializeObject(results);
            string pagedResultString = JsonConvert.SerializeObject(pagedResults);

            if (typeof(T) != typeof(PermissionProperties))
            {
                Assert.AreEqual(pagedResultString, resultString);
                Assert.AreEqual(streamPagedResultString, resultString);
            }

            return(results);
        }
コード例 #9
0
        public async Task ReadFeedIteratorCore_OfT_ReadNextAsync()
        {
            string          continuation    = "TBD";
            ResponseMessage responseMessage = new ResponseMessage(HttpStatusCode.OK);

            responseMessage.Headers.ContinuationToken = continuation;
            responseMessage.Headers[Documents.HttpConstants.HttpHeaders.ItemCount] = "1";
            responseMessage.Content = new MemoryStream(Encoding.UTF8.GetBytes("{}"));

            Mock <CosmosClientContext> cosmosClientContext = new Mock <CosmosClientContext>();

            cosmosClientContext.Setup(c => c.ClientOptions).Returns(new CosmosClientOptions());
            cosmosClientContext
            .Setup(c => c.ProcessResourceOperationStreamAsync(
                       It.IsAny <string>(),
                       It.Is <Documents.ResourceType>(rt => rt == Documents.ResourceType.Document),
                       It.IsAny <Documents.OperationType>(),
                       It.IsAny <RequestOptions>(),
                       It.IsAny <ContainerInternal>(),
                       It.IsAny <PartitionKey?>(),
                       It.IsAny <Stream>(),
                       It.IsAny <Action <RequestMessage> >(),
                       It.IsAny <CosmosDiagnosticsContext>(),
                       It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(responseMessage));

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

            Mock.Get(containerCore)
            .Setup(c => c.ClientContext)
            .Returns(cosmosClientContext.Object);
            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()));
            Mock.Get(feedToken)
            .Setup(f => f.GetContinuation())
            .Returns(continuation);
            Mock.Get(feedToken)
            .Setup(f => f.IsDone)
            .Returns(true);

            FeedRangeIteratorCore feedTokenIterator = new FeedRangeIteratorCore(containerCore, feedToken, new QueryRequestOptions(), Documents.ResourceType.Document, queryDefinition: null);
            bool creatorCalled = false;
            Func <ResponseMessage, FeedResponse <dynamic> > creator = (ResponseMessage r) =>
            {
                creatorCalled = true;
                return(Mock.Of <FeedResponse <dynamic> >());
            };

            FeedIteratorCore <dynamic> feedTokenIteratorOfT = new FeedIteratorCore <dynamic>(feedTokenIterator, creator);
            FeedResponse <dynamic>     response             = await feedTokenIteratorOfT.ReadNextAsync();

            Assert.IsTrue(creatorCalled, "Response creator not called");
            Mock.Get(feedToken)
            .Verify(f => f.ReplaceContinuation(It.Is <string>(ct => ct == continuation)), Times.Once);

            Mock.Get(feedToken)
            .Verify(f => f.HandleSplitAsync(It.Is <ContainerInternal>(c => c == containerCore), It.IsAny <ResponseMessage>(), It.IsAny <CancellationToken>()), Times.Once);
        }
コード例 #10
0
        public void ReadFromTrace <T>(FeedResponse <T> Response, QueryStatisticsDatumVisitor queryStatisticsDatumVisitor)
        {
            ITrace trace = ((CosmosTraceDiagnostics)Response.Diagnostics).Value;

            //POCO Materialization occurs once per iteration including all the roundtrips
            List <ITrace> retrieveQueryMetricTraces = this.FindQueryMetrics(trace: trace, nodeNameOrKeyName: ClientParseTimeNode, isKeyName: false);

            foreach (ITrace queryMetricTrace in retrieveQueryMetricTraces)
            {
                queryStatisticsDatumVisitor.AddPocoTime(queryMetricTrace.Duration.TotalMilliseconds);
            }

            //Get Cosmos Element Response occurs once per roundtrip for calls with status code 200
            List <ITrace> retrieveCosmosElementTraces = this.FindQueryMetrics(trace: trace, nodeNameOrKeyName: ClientDeserializationTimeNode, isKeyName: false);

            //Query metrics occurs once per roundtrip for calls with status code 200
            List <ITrace> backendMetrics = this.FindQueryMetrics(trace: trace, nodeNameOrKeyName: BackendKeyValue, isKeyName: true);

            //Client metrics occurs once per roundtrip for all status codes
            List <ITrace> transitMetrics = this.FindQueryMetrics(trace: trace, nodeNameOrKeyName: TransportKeyValue, isKeyName: true, currentNodeName: TransportNodeName);
            List <Tuple <ITrace, ITrace, ITrace> > backendAndClientMetrics = new();
            int i = 0;
            int j = 0;
            int k = 0;

            foreach (ITrace node in transitMetrics)
            {
                Debug.Assert(node.Data.Count == 1, "Exactly one transit metric expected");
                KeyValuePair <string, object> kvp = node.Data.Single();
                Assert.IsInstanceOfType(kvp.Value, typeof(ClientSideRequestStatisticsTraceDatum));
                ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum = (ClientSideRequestStatisticsTraceDatum)kvp.Value;
                foreach (ClientSideRequestStatisticsTraceDatum.StoreResponseStatistics storeResponse in clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList)
                {
                    if (storeResponse.StoreResult.StatusCode == StatusCodes.Ok)
                    {
                        backendAndClientMetrics.Add(Tuple.Create(retrieveCosmosElementTraces[k], backendMetrics[j], transitMetrics[i]));
                        j++;
                        k++;
                    }
                    else
                    {
                        //We add null values to the tuple since status codes other than Ok will not have data for 'Query Metrics' and 'Get Cosmos Element Response'
                        backendAndClientMetrics.Add(Tuple.Create <ITrace, ITrace, ITrace>(null, null, transitMetrics[i]));
                    }
                }

                i++;
            }

            Debug.Assert(i == transitMetrics.Count, "All 'transit metrics' must be grouped.");
            Debug.Assert(j == backendMetrics.Count, "All 'backend metrics' must be grouped.");
            Debug.Assert(k == retrieveCosmosElementTraces.Count, "All 'Get Cosmos Element Response' traces must be grouped.");

            int l = 1;

            foreach (Tuple <ITrace, ITrace, ITrace> metrics in backendAndClientMetrics)
            {
                if (metrics.Item2 != null)
                {
                    Debug.Assert(metrics.Item1 == null, "'Get Cosmos Element Response' is null");
                    queryStatisticsDatumVisitor.AddGetCosmosElementResponseTime(metrics.Item1.Duration.TotalMilliseconds);
                    foreach (KeyValuePair <string, object> kvp in metrics.Item2.Data)
                    {
                        switch (kvp.Value)
                        {
                        case TraceDatum traceDatum:
                            traceDatum.Accept(queryStatisticsDatumVisitor);
                            break;

                        default:
                            Debug.Fail("Unexpected type", $"Type not supported {metrics.Item2.GetType()}");
                            break;
                        }
                    }

                    //add metrics to the list except for last roundtrip which is taken care of in ContentSerializationPerformanceTest class
                    if (l != backendMetrics.Count)
                    {
                        queryStatisticsDatumVisitor.PopulateMetrics();
                    }
                    l++;
                }

                foreach (KeyValuePair <string, object> kvp in metrics.Item3.Data)
                {
                    switch (kvp.Value)
                    {
                    case TraceDatum traceDatum:
                        traceDatum.Accept(queryStatisticsDatumVisitor);
                        break;

                    default:
                        Debug.Fail("Unexpected type", $"Type not supported {metrics.Item3.GetType()}");
                        break;
                    }
                }
            }
        }
コード例 #11
0
        public async Task QueryRequestRateTest(bool directMode)
        {
            string firstItemIdAndPk = "BasicQueryItem" + Guid.NewGuid();

            // Prevent the test from changing the static client
            {
                CosmosClient client    = directMode ? DirectCosmosClient : GatewayCosmosClient;
                Container    container = client.GetContainer(DatabaseId, ContainerId);

                List <string> createdIds = new List <string>()
                {
                    firstItemIdAndPk,
                    "BasicQueryItem2" + Guid.NewGuid(),
                    "BasicQueryItem3" + Guid.NewGuid()
                };

                foreach (string id in createdIds)
                {
                    dynamic item = new
                    {
                        id = id,
                        pk = id,
                    };

                    await container.CreateItemAsync <dynamic>(item : item);
                }
            }

            CosmosClient clientWithThrottle;

            if (directMode)
            {
                clientWithThrottle = TestCommon.CreateCosmosClient();
            }
            else
            {
                clientWithThrottle = TestCommon.CreateCosmosClient((builder) => builder.WithConnectionModeGateway());
            }

            Container containerWithThrottle = clientWithThrottle.GetContainer(DatabaseId, ContainerId);

            // Do a read to warm up all the caches to prevent them from getting the throttle errors
            using (await containerWithThrottle.ReadItemStreamAsync(firstItemIdAndPk, new PartitionKey(firstItemIdAndPk))) { }

            Documents.IStoreModel        storeModel = clientWithThrottle.ClientContext.DocumentClient.StoreModel;
            Mock <Documents.IStoreModel> mockStore  = new Mock <Documents.IStoreModel>();

            clientWithThrottle.ClientContext.DocumentClient.StoreModel = mockStore.Object;

            // Cause 429 after the first call
            int    callCount    = 0;
            string activityId   = null;
            string errorMessage = "QueryRequestRateTest Resource Not Found";

            mockStore.Setup(x => x.ProcessMessageAsync(It.IsAny <Documents.DocumentServiceRequest>(), It.IsAny <CancellationToken>()))
            .Returns <Documents.DocumentServiceRequest, CancellationToken>((dsr, token) =>
            {
                callCount++;

                if (callCount > 1)
                {
                    INameValueCollection headers = new DictionaryNameValueCollection();
                    headers.Add(Documents.HttpConstants.HttpHeaders.RetryAfterInMilliseconds, "42");
                    activityId = Guid.NewGuid().ToString();
                    headers.Add(Documents.HttpConstants.HttpHeaders.ActivityId, activityId);
                    Documents.DocumentServiceResponse response = new Documents.DocumentServiceResponse(
                        body: TestCommon.GenerateStreamFromString(@"{""Errors"":[""" + errorMessage + @"""]}"),
                        headers: headers,
                        statusCode: (HttpStatusCode)429,
                        clientSideRequestStatistics: dsr.RequestContext.ClientRequestStatistics);

                    return(Task.FromResult(response));
                }

                return(storeModel.ProcessMessageAsync(dsr, token));
            });

            List <dynamic> results = new List <dynamic>();

            try
            {
                FeedIterator <dynamic> feedIterator = containerWithThrottle.GetItemQueryIterator <dynamic>(
                    "select * from T where STARTSWITH(T.id, \"BasicQueryItem\")",
                    requestOptions: new QueryRequestOptions()
                {
                    MaxItemCount   = 1,
                    MaxConcurrency = 1
                });

                while (feedIterator.HasMoreResults)
                {
                    FeedResponse <dynamic> response = await feedIterator.ReadNextAsync();

                    Assert.IsTrue(response.Count <= 1);
                    Assert.IsTrue(response.Resource.Count() <= 1);

                    results.AddRange(response);
                }
                Assert.Fail("Should throw 429 exception after the first page.");
            }
            catch (CosmosException ce)
            {
                Assert.IsTrue(ce.RetryAfter.HasValue);
                Assert.AreEqual(42, ce.RetryAfter.Value.TotalMilliseconds);
                Assert.AreEqual(activityId, ce.ActivityId);
                Assert.IsNotNull(ce.DiagnosticsContext);
                Assert.IsTrue(ce.Message.Contains(errorMessage));
            }

            callCount = 0;
            FeedIterator streamIterator = containerWithThrottle.GetItemQueryStreamIterator(
                "select * from T where STARTSWITH(T.id, \"BasicQueryItem\")",
                requestOptions: new QueryRequestOptions()
            {
                MaxItemCount   = 1,
                MaxConcurrency = 1
            });

            // First request should be a success
            using (ResponseMessage response = await streamIterator.ReadNextAsync())
            {
                response.EnsureSuccessStatusCode();
                Assert.IsNotNull(response.Content);
            }

            // Second page should be a failure
            using (ResponseMessage response = await streamIterator.ReadNextAsync())
            {
                Assert.AreEqual(429, (int)response.StatusCode);
                Assert.AreEqual("42", response.Headers.RetryAfterLiteral);
                Assert.AreEqual(activityId, response.Headers.ActivityId);
                Assert.IsNotNull(response.DiagnosticsContext);
                Assert.IsTrue(response.ErrorMessage.Contains(errorMessage));
            }
        }
 private FeedResponse <T> ProcessResponse <T>(FeedResponse <T> response)
 {
     AddSessionTokenToResponseHeaders(response.SessionToken);
     return(response);
 }
コード例 #13
0
        internal virtual async Task <int> QueryAndVerifyDocuments(DocumentClient client, string collectionLink, IEnumerable <Query> queries, int pageSize = 1000, int retries = 0, bool allowScan = false)
        {
            // First we make sure that all the queries are inserted
            {
                List <dynamic>            queriedDocuments = new List <dynamic>();
                IDocumentQuery <Document> selectAllQuery   = client.CreateDocumentQuery(collectionLink, feedOptions: new FeedOptions {
                    MaxItemCount = pageSize, EnableScanInQuery = allowScan, EnableCrossPartitionQuery = true
                }).AsDocumentQuery();
                while (selectAllQuery.HasMoreResults)
                {
                    FeedResponse <dynamic> queryResultsPage = await selectAllQuery.ExecuteNextAsync();

                    System.Diagnostics.Trace.TraceInformation("ReadFeed continuation token: {0}, SessionToken: {1}", queryResultsPage.ResponseContinuation, queryResultsPage.SessionToken);
                    queriedDocuments.AddRange(queryResultsPage);
                }

                List <dynamic> expected = new List <dynamic>(documents.Count());
                for (int i = 0; i < documents.Count(); ++i)
                {
                    expected.Add(JsonConvert.DeserializeObject(String.Format(CultureInfo.InvariantCulture, DocumentFormat, i + 1, String.Empty)));
                }

                queriedDocuments.Sort((doc1, doc2) => int.Parse(doc1.id).CompareTo(int.Parse(doc2.id)));

                var expectedIds = expected.Select(doc => doc.id.ToString());

                var actualIds = queriedDocuments.Select(doc => doc.id.ToString());

                if (!expectedIds.SequenceEqual(actualIds))
                {
                    System.Diagnostics.Trace.TraceInformation("Failed to insert all the documents, queried documents are:" + Environment.NewLine + String.Join(Environment.NewLine, queriedDocuments));
                    return(-1);
                }

                System.Diagnostics.Trace.TraceInformation("All the documents are inserted");
            }

            // Query and verify
            TimeSpan totalQueryLatencyAllPages = TimeSpan.FromSeconds(0);
            uint     numberOfQueries           = 0;
            var      failedQueries             = new List <Query>();

            List <Query> query_list = queries as List <Query> ?? queries.ToList();

            foreach (var query in query_list)
            {
                var           queriedDocuments         = new List <string>();
                List <string> activityIDsAllQueryPages = new List <string>();

                if (numberOfQueries > 0 && numberOfQueries % 100 == 0)
                {
                    System.Diagnostics.Trace.TraceInformation(DateTime.Now.ToString("HH:mm:ss.ffff") + @": Executing query {0} of {1}",
                                                              (numberOfQueries + 1), query_list.Count());
                    System.Diagnostics.Trace.TraceInformation(@"    Query latency per query (avg ms) {0} after {1} queries",
                                                              totalQueryLatencyAllPages.TotalMilliseconds / numberOfQueries, numberOfQueries);
                }

                IDocumentQuery <dynamic> docQuery = client.CreateDocumentQuery(collectionLink, query.ToString(), feedOptions: new FeedOptions {
                    MaxItemCount = pageSize, EnableScanInQuery = allowScan, EnableCrossPartitionQuery = true
                }).AsDocumentQuery();
                while (docQuery.HasMoreResults)
                {
                    DateTime startTime = DateTime.Now;
                    FeedResponse <dynamic> queryResultsPage = await QueryWithRetry(docQuery, query.ToString());

                    activityIDsAllQueryPages.Add(queryResultsPage.ActivityId);
                    totalQueryLatencyAllPages += (DateTime.Now - startTime);
                    foreach (JObject result in queryResultsPage)
                    {
                        queriedDocuments.Add(result.ToString(Formatting.None));
                    }
                }
                numberOfQueries++;

                bool valid;
                var  expected = Validate(queriedDocuments, query, out valid);
                if (!valid)
                {
                    System.Diagnostics.Trace.TraceInformation(
                        DateTime.Now.ToString("HH:mm:ss.ffff")
                        + @": Query {0} did not retrieve expected documents, query all pages activitiIDs: ({1})"
                        + Environment.NewLine
                        + "Expected:"
                        + Environment.NewLine
                        + "{2}"
                        + Environment.NewLine
                        + "Actual:"
                        + Environment.NewLine
                        + "{3}"
                        + Environment.NewLine,
                        query.ToString(),
                        String.Join(",", activityIDsAllQueryPages),
                        String.Join(",", expected),
                        String.Join(",", queriedDocuments));

                    failedQueries.Add(query);
                }
            }

            if (failedQueries.Count() == 0)
            {
                System.Diagnostics.Trace.TraceInformation(@"*** TEST PASSED ***");
                return(0);
            }
            else
            {
                System.Diagnostics.Trace.TraceInformation(@"*** TEST FAILED with seed {0}***", seed);
                int result = -1;
                //In case of a failure, retry only failed queries after sleeping for couple of minutes.
                if (retries > 0)
                {
                    System.Diagnostics.Trace.TraceInformation(@"*** Retrying Failed queries, {0} retries left ***", --retries);
                    Task.Delay(120 * 1000).Wait();
                    result = await QueryAndVerifyDocuments(client, collectionLink, failedQueries, pageSize, retries, allowScan);
                }

                return(result);
            }
        }
コード例 #14
0
        public async Task TestDistinct_ExecuteNextAsync()
        {
            async Task ImplementationAsync(Container container, IReadOnlyList <CosmosObject> documents)
            {
                #region Queries
                // To verify distint queries you can run it once without the distinct clause and run it through a hash set
                // then compare to the query with the distinct clause.
                List <(string, bool)> queries = new List <(string, bool)>()
                {
                    // basic distinct queries
                    ("SELECT {0} VALUE null", true),

                    // number value distinct queries
                    ("SELECT {0} VALUE c.income from c", true),

                    // string value distinct queries
                    ("SELECT {0} VALUE c.name from c", true),

                    // array value distinct queries
                    ("SELECT {0} VALUE c.children from c", true),

                    // object value distinct queries
                    ("SELECT {0} VALUE c.pet from c", true),

                    // scalar expressions distinct query
                    ("SELECT {0} VALUE c.age % 2 FROM c", true),

                    // distinct queries with order by
                    ("SELECT {0} VALUE c.age FROM c ORDER BY c.age", false),

                    // distinct queries with top and no matching order by
                    ("SELECT {0} TOP 2147483647 VALUE c.age FROM c", false),

                    // distinct queries with top and  matching order by
                    ("SELECT {0} TOP 2147483647 VALUE c.age FROM c ORDER BY c.age", false),

                    // distinct queries with aggregates
                    ("SELECT {0} VALUE MAX(c.age) FROM c", false),

                    // distinct queries with joins
                    ("SELECT {0} VALUE c.age FROM p JOIN c IN p.children", true),

                    // distinct queries in subqueries
                    ("SELECT {0} r.age, s FROM r JOIN (SELECT DISTINCT VALUE c FROM (SELECT 1 a) c) s WHERE r.age > 25", false),

                    // distinct queries in scalar subqeries
                    ("SELECT {0} p.name, (SELECT DISTINCT VALUE p.age) AS Age FROM p", true),

                    // select *
                    ("SELECT {0} * FROM c", true)
                };
                #endregion
                #region ExecuteNextAsync API
                // run the query with distinct and without + MockDistinctMap
                // Should receive same results
                // PageSize = 1 guarantees that the backend will return some duplicates.
                foreach ((string query, bool allowDCount) in queries)
                {
                    string queryWithoutDistinct = string.Format(query, "");

                    QueryRequestOptions requestOptions = new QueryRequestOptions()
                    {
                        MaxItemCount = 100, MaxConcurrency = 100
                    };
                    FeedIterator <CosmosElement> documentQueryWithoutDistinct = container.GetItemQueryIterator <CosmosElement>(
                        queryWithoutDistinct,
                        requestOptions: requestOptions);

                    MockDistinctMap      documentsSeen = new MockDistinctMap();
                    List <CosmosElement> documentsFromWithoutDistinct = new List <CosmosElement>();
                    while (documentQueryWithoutDistinct.HasMoreResults)
                    {
                        FeedResponse <CosmosElement> cosmosQueryResponse = await documentQueryWithoutDistinct.ReadNextAsync();

                        foreach (CosmosElement document in cosmosQueryResponse)
                        {
                            if (documentsSeen.Add(document, out UInt128 hash))
                            {
                                documentsFromWithoutDistinct.Add(document);
                            }
                            else
                            {
                                // No Op for debugging purposes.
                            }
                        }
                    }

                    foreach (int pageSize in new int[] { 1, 10, 100 })
                    {
                        string queryWithDistinct = string.Format(query, "DISTINCT");
                        List <CosmosElement>         documentsFromWithDistinct = new List <CosmosElement>();
                        FeedIterator <CosmosElement> documentQueryWithDistinct = container.GetItemQueryIterator <CosmosElement>(
                            queryWithDistinct,
                            requestOptions: requestOptions);

                        while (documentQueryWithDistinct.HasMoreResults)
                        {
                            FeedResponse <CosmosElement> cosmosQueryResponse = await documentQueryWithDistinct.ReadNextAsync();

                            documentsFromWithDistinct.AddRange(cosmosQueryResponse);
                        }

                        Assert.AreEqual(documentsFromWithDistinct.Count, documentsFromWithoutDistinct.Count);
                        for (int i = 0; i < documentsFromWithDistinct.Count; i++)
                        {
                            CosmosElement documentFromWithDistinct    = documentsFromWithDistinct.ElementAt(i);
                            CosmosElement documentFromWithoutDistinct = documentsFromWithoutDistinct.ElementAt(i);
                            Assert.AreEqual(
                                expected: documentFromWithoutDistinct,
                                actual: documentFromWithDistinct,
                                message: $"{documentFromWithDistinct} did not match {documentFromWithoutDistinct} at index {i} for {queryWithDistinct}, with page size: {pageSize} on a container");
                        }

                        if (allowDCount)
                        {
                            string queryWithDCount = $"SELECT VALUE COUNT(1) FROM({queryWithDistinct})";

                            List <CosmosElement>         documentsWithDCount     = new List <CosmosElement>();
                            FeedIterator <CosmosElement> documentQueryWithDCount = container.GetItemQueryIterator <CosmosElement>(
                                queryWithDCount,
                                requestOptions: requestOptions);

                            while (documentQueryWithDCount.HasMoreResults)
                            {
                                FeedResponse <CosmosElement> cosmosQueryResponse = await documentQueryWithDCount.ReadNextAsync();

                                documentsWithDCount.AddRange(cosmosQueryResponse);
                            }

                            Assert.AreEqual(1, documentsWithDCount.Count);
                            long dcount = Number64.ToLong((documentsWithDCount.First() as CosmosNumber).Value);
                            Assert.AreEqual(documentsFromWithoutDistinct.Count, dcount);
                        }
                    }
                }
                #endregion
            }

            await this.TestQueryDistinctBaseAsync(ImplementationAsync);
        }
        public void ValidateResponseFactoryJsonSerializer()
        {
            ResponseMessage databaseResponse  = this.CreateResponse();
            ResponseMessage containerResponse = this.CreateResponse();
            ResponseMessage storedProcedureExecuteResponse = this.CreateResponse();
            ResponseMessage storedProcedureResponse        = this.CreateResponse();
            ResponseMessage triggerResponse = this.CreateResponse();
            ResponseMessage udfResponse     = this.CreateResponse();
            ResponseMessage itemResponse    = this.CreateResponse();


            Mock <CosmosSerializer>       mockUserJsonSerializer = new Mock <CosmosSerializer>();
            CosmosSerializerCore          serializerCore         = new CosmosSerializerCore(mockUserJsonSerializer.Object);
            CosmosResponseFactoryInternal cosmosResponseFactory  = new CosmosResponseFactoryCore(
                serializerCore);

            // Test the user specified response
            mockUserJsonSerializer.Setup(x => x.FromStream <ToDoActivity>(itemResponse.Content)).Callback <Stream>(input => input.Dispose()).Returns(new ToDoActivity());
            mockUserJsonSerializer.Setup(x => x.FromStream <ToDoActivity>(storedProcedureExecuteResponse.Content)).Callback <Stream>(input => input.Dispose()).Returns(new ToDoActivity());

            // Verify all the user types use the user specified version
            cosmosResponseFactory.CreateItemResponse <ToDoActivity>(itemResponse);
            cosmosResponseFactory.CreateStoredProcedureExecuteResponse <ToDoActivity>(storedProcedureExecuteResponse);

            // Throw if the setups were not called
            mockUserJsonSerializer.VerifyAll();

            // Test read feed scenario
            ResponseMessage readFeedResponse = this.CreateReadFeedResponse();

            mockUserJsonSerializer.Setup(x => x.FromStream <ToDoActivity[]>(It.IsAny <Stream>()))
            .Callback <Stream>(input => input.Dispose())
            .Returns(new ToDoActivity[] { new ToDoActivity() });
            FeedResponse <ToDoActivity> feedResponse = cosmosResponseFactory.CreateItemFeedResponse <ToDoActivity>(readFeedResponse);

            foreach (ToDoActivity toDoActivity in feedResponse)
            {
                Assert.IsNotNull(toDoActivity);
            }

            mockUserJsonSerializer.VerifyAll();

            ResponseMessage changeFeedResponseMessage = this.CreateChangeFeedNotModifiedResponse();

            try
            {
                cosmosResponseFactory.CreateItemFeedResponse <ToDoActivity>(changeFeedResponseMessage);
                Assert.Fail();
            }
            catch (CosmosException cosmosException)
            {
                Assert.AreEqual(HttpStatusCode.NotModified, cosmosException.StatusCode);
            }

            ResponseMessage queryResponse = this.CreateReadFeedResponse();

            mockUserJsonSerializer.Setup(x => x.FromStream <ToDoActivity[]>(It.IsAny <Stream>())).Callback <Stream>(input => input.Dispose()).Returns(new ToDoActivity[] { new ToDoActivity() });
            FeedResponse <ToDoActivity> queryFeedResponse = cosmosResponseFactory.CreateItemFeedResponse <ToDoActivity>(queryResponse);

            foreach (ToDoActivity toDoActivity in queryFeedResponse)
            {
                Assert.IsNotNull(toDoActivity);
            }

            mockUserJsonSerializer.VerifyAll();

            // Test the system specified response
            ContainerProperties containerSettings = new ContainerProperties("mockId", "/pk");
            DatabaseProperties  databaseSettings  = new DatabaseProperties()
            {
                Id = "mock"
            };

            StoredProcedureProperties cosmosStoredProcedureSettings = new StoredProcedureProperties()
            {
                Id = "mock"
            };

            TriggerProperties cosmosTriggerSettings = new TriggerProperties()
            {
                Id = "mock"
            };

            UserDefinedFunctionProperties cosmosUserDefinedFunctionSettings = new UserDefinedFunctionProperties()
            {
                Id = "mock"
            };

            Mock <Container> mockContainer = new Mock <Container>();
            Mock <Database>  mockDatabase  = new Mock <Database>();

            // Verify all the system types that should always use default
            cosmosResponseFactory.CreateContainerResponse(mockContainer.Object, containerResponse);
            cosmosResponseFactory.CreateDatabaseResponse(mockDatabase.Object, databaseResponse);
            cosmosResponseFactory.CreateStoredProcedureResponse(storedProcedureResponse);
            cosmosResponseFactory.CreateTriggerResponse(triggerResponse);
            cosmosResponseFactory.CreateUserDefinedFunctionResponse(udfResponse);
        }
コード例 #16
0
        //Helper method to run query
        static async Task RunQuery(string sqlQueryText, int maxItemCountPerPage = 100, int maxConcurrency = -1, bool useQueryOptions = false)
        {
            Console.BackgroundColor = ConsoleColor.Blue;

            Console.WriteLine($"Running query: \"{sqlQueryText}\" against container {ContainerName}\n");
            Console.WriteLine("");

            if (useQueryOptions)
            {
                Console.WriteLine($"Using MaxConcurrency: {maxConcurrency}");
                Console.WriteLine($"Using MaxItemCountPerPage: {maxItemCountPerPage}");
            }
            Console.ResetColor();

            double          totalRequestCharge = 0;
            QueryDefinition queryDefinition    = new QueryDefinition(sqlQueryText);

            // Run query against Cosmos DB
            var container = cosmosClient.GetDatabase(DatabaseName).GetContainer(ContainerName);

            QueryRequestOptions requestOptions;

            if (useQueryOptions)
            {
                requestOptions = new QueryRequestOptions()
                {
                    MaxItemCount   = maxItemCountPerPage,
                    MaxConcurrency = maxConcurrency,
                };
            }
            else
            {
                requestOptions = new QueryRequestOptions(); //use all default query options
            }

            // Time the query
            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();

            FeedIterator <dynamic> queryResultSetIterator = container.GetItemQueryIterator <dynamic>(queryDefinition, requestOptions: requestOptions);
            List <dynamic>         reviews = new List <dynamic>();

            while (queryResultSetIterator.HasMoreResults)
            {
                FeedResponse <dynamic> currentResultSet = await queryResultSetIterator.ReadNextAsync();

                totalRequestCharge += currentResultSet.RequestCharge;
                //Console.WriteLine("another page");
                foreach (var item in currentResultSet)
                {
                    reviews.Add(item);
                    Console.WriteLine(item);
                }
                if (useQueryOptions)
                {
                    Console.WriteLine($"Result count: {reviews.Count}");
                }
            }

            stopWatch.Stop();
            TimeSpan ts = stopWatch.Elapsed;

            //Print results
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                               ts.Hours, ts.Minutes, ts.Seconds,
                                               ts.Milliseconds / 10);

            Console.ForegroundColor = ConsoleColor.Green;

            Console.WriteLine($"\tQuery returned {reviews.Count} results");
            Console.WriteLine($"\tTotal time: {elapsedTime}");
            Console.WriteLine($"\tTotal Request Units consumed: {totalRequestCharge}\n");
            Console.WriteLine("\n\n\n");
            Console.ResetColor();
        }
コード例 #17
0
        private async Task <long> ExecuteQueryAndReturnOutputDocumentCount(
            string queryText,
            int expectedItemCount,
            bool disableDiagnostics)
        {
            QueryDefinition sql = null;

            if (queryText != null)
            {
                sql = new QueryDefinition(queryText);
            }

            QueryRequestOptions requestOptions = new QueryRequestOptions()
            {
                MaxItemCount   = 1,
                MaxConcurrency = 1,
            };

            if (disableDiagnostics)
            {
                requestOptions.DiagnosticContextFactory = () => EmptyCosmosDiagnosticsContext.Singleton;
            }
            ;

            // Verify the typed query iterator
            FeedIterator <ToDoActivity> feedIterator = this.Container.GetItemQueryIterator <ToDoActivity>(
                sql,
                requestOptions: requestOptions);

            List <ToDoActivity> results = new List <ToDoActivity>();
            long totalOutDocumentCount  = 0;
            bool isFirst = true;

            while (feedIterator.HasMoreResults)
            {
                FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync();

                results.AddRange(response);
                if (queryText == null)
                {
                    CosmosDiagnosticsTests.VerifyPointDiagnostics(
                        response.Diagnostics,
                        disableDiagnostics);
                }
                else
                {
                    VerifyQueryDiagnostics(
                        response.Diagnostics,
                        isFirst,
                        disableDiagnostics);
                }

                isFirst = false;
            }

            Assert.AreEqual(expectedItemCount, results.Count);

            // Verify the stream query iterator
            FeedIterator streamIterator = this.Container.GetItemQueryStreamIterator(
                sql,
                requestOptions: requestOptions);

            List <ToDoActivity> streamResults = new List <ToDoActivity>();
            long streamTotalOutDocumentCount  = 0;

            isFirst = true;
            while (streamIterator.HasMoreResults)
            {
                ResponseMessage response = await streamIterator.ReadNextAsync();

                Collection <ToDoActivity> result = TestCommon.SerializerCore.FromStream <CosmosFeedResponseUtil <ToDoActivity> >(response.Content).Data;
                streamResults.AddRange(result);
                if (queryText == null)
                {
                    CosmosDiagnosticsTests.VerifyPointDiagnostics(
                        response.Diagnostics,
                        disableDiagnostics);
                }
                else
                {
                    VerifyQueryDiagnostics(
                        response.Diagnostics,
                        isFirst,
                        disableDiagnostics);
                }

                isFirst = false;
            }

            Assert.AreEqual(expectedItemCount, streamResults.Count);
            Assert.AreEqual(totalOutDocumentCount, streamTotalOutDocumentCount);

            return(results.Count);
        }
コード例 #18
0
        private async Task DataUpdateStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var orderData = await _orderDataAccessor.GetAsync(stepContext.Context, () => new OrderData(), cancellationToken);

            CosmosClient client = new CosmosClient(Startup.CosmosDbEndpoint, Startup.AuthKey);

            database = await client.CreateDatabaseIfNotExistsAsync(databaseId);

            ContainerProperties containerProperties = new ContainerProperties(containerId, partitionKeyPath: Startup.PartitionKey);

            // Create with a throughput of 1000 RU/s
            container = await database.CreateContainerIfNotExistsAsync(
                containerProperties,
                throughput : 1000);

            //orderNum 가져오기
            try
            {
                FeedIterator <DBdata> feedIterator = container.GetItemQueryIterator <DBdata>("SELECT top 1 * FROM c order by c._ts desc");
                {
                    while (feedIterator.HasMoreResults)
                    {
                        FeedResponse <DBdata> result = await feedIterator.ReadNextAsync();

                        foreach (var item in result)
                        {
                            orderData.OrderNum = Int32.Parse(item.id);
                        }
                    }
                }
            }
            catch (System.Exception e)
            {
                orderData.OrderNum = 0;
            }

            //ip
            IPHostEntry host   = Dns.GetHostEntry(Dns.GetHostName());
            string      ipAddr = string.Empty;

            for (int i = 0; i < host.AddressList.Length; i++)
            {
                if (host.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
                {
                    ipAddr = host.AddressList[i].ToString();
                }
            }

            //Order 데이터 삽입
            foreach (Sandwich tempSand in orderData.Sandwiches)
            {
                string sJson = JsonConvert.SerializeObject(tempSand);

                var dbData = new DBdata {
                    id = $"{++orderData.OrderNum}", Contents = tempSand, ETag = "x", AccountNumber = ipAddr
                };

                await container.CreateItemAsync <DBdata>(dbData, new PartitionKey(dbData.AccountNumber));
            }

            //container 변경
            containerProperties = new ContainerProperties(countContainerId, partitionKeyPath: "/AccountNumber");
            // Create with a throughput of 1000 RU/s
            container = await database.CreateContainerIfNotExistsAsync(
                containerProperties,
                throughput : 1000);

            //Count 데이터 삽입
            foreach (Sandwich tempSand in orderData.Sandwiches)
            {
                var    CountId = 0;
                string sauce   = "";
                tempSand.Sauce.Sort();
                foreach (string temp in tempSand.Sauce)
                {
                    sauce += temp + " ";
                }

                //CountId 찾기
                try
                {
                    FeedIterator <DBcount> feedIterator = container.GetItemQueryIterator <DBcount>("SELECT top 1 * FROM c order by c._ts desc");
                    {
                        while (feedIterator.HasMoreResults)
                        {
                            FeedResponse <DBcount> result = await feedIterator.ReadNextAsync();

                            foreach (var item in result)
                            {
                                CountId = Int32.Parse(item.id) + 1;
                            }
                        }
                    }
                }
                catch (System.Exception e)
                {
                    CountId = 0;
                }

                try {
                    FeedIterator <DBcount> feedIterator = container.GetItemQueryIterator <DBcount>("SELECT * FROM c WHERE c.Sauce='" + sauce + "' and c.Bread ='" + tempSand.Bread + "' and c.Menu ='" + tempSand.Menu + "'");
                    {
                        if (feedIterator.HasMoreResults)
                        {
                            FeedResponse <DBcount> result = await feedIterator.ReadNextAsync();

                            DBcount res                 = result.First();
                            var     count               = res.Count + 1;
                            DBcount countData           = new DBcount(); countData.id = res.id; countData.Count = count; countData.Sauce = sauce; countData.Menu = tempSand.Menu; countData.ETag = "x"; countData.AccountNumber = "0"; countData.Bread = tempSand.Bread;
                            ItemResponse <DBcount> item = await container.DeleteItemAsync <DBcount>(partitionKey : new PartitionKey("0"), id : res.id);

                            await container.CreateItemAsync(countData, new PartitionKey("0"));
                        }
                    }
                }
                catch (System.Exception e)
                {
                    var countData = new DBcount {
                        id = $"{CountId}", Count = 1, Bread = $"{tempSand.Bread}", Sauce = sauce, Menu = $"{tempSand.Menu}", ETag = "x", AccountNumber = "0"
                    };
                    await container.CreateItemAsync <DBcount>(countData, new PartitionKey("0"));
                }
            }
        }
コード例 #19
0
        private async Task <FeedResponse <CosmosElement> > ExecuteOnceAsync(IDocumentClientRetryPolicy retryPolicyInstance, CancellationToken cancellationToken)
        {
            // Don't reuse request, as the rest of client SDK doesn't reuse requests between retries.
            // The code leaves some temporary garbage in request (in RequestContext etc.),
            // which shold be erased during retries.
            using (DocumentServiceRequest request = await this.CreateRequestAsync())
            {
                if (!string.IsNullOrEmpty(request.Headers[HttpConstants.HttpHeaders.PartitionKey]) ||
                    !request.ResourceType.IsPartitioned())
                {
                    return(await this.ExecuteRequestAsync(request, cancellationToken));
                }

                CollectionCache collectionCache = await this.Client.GetCollectionCacheAsync();

                CosmosContainerSettings collection =
                    await collectionCache.ResolveCollectionAsync(request, CancellationToken.None);

                if (!string.IsNullOrEmpty(base.PartitionKeyRangeId))
                {
                    request.RouteTo(new PartitionKeyRangeIdentity(collection.ResourceId, base.PartitionKeyRangeId));
                    return(await this.ExecuteRequestAsync(request, cancellationToken));
                }

                // For non-Windows platforms(like Linux and OSX) in .NET Core SDK, we cannot use ServiceInterop for parsing the query,
                // so forcing the request through Gateway. We are also now by-passing this for 32-bit host process in NETFX on Windows
                // as the ServiceInterop dll is only available in 64-bit.
                if (CustomTypeExtensions.ByPassQueryParsing())
                {
                    request.UseGatewayMode = true;
                    return(await this.ExecuteRequestAsync(request, cancellationToken));
                }

                QueryPartitionProvider queryPartitionProvider = await this.Client.GetQueryPartitionProviderAsync(cancellationToken);

                IRoutingMapProvider routingMapProvider = await this.Client.GetRoutingMapProviderAsync();

                List <CompositeContinuationToken> suppliedTokens;
                Range <string> rangeFromContinuationToken =
                    this.partitionRoutingHelper.ExtractPartitionKeyRangeFromContinuationToken(request.Headers, out suppliedTokens);
                Tuple <PartitionRoutingHelper.ResolvedRangeInfo, IReadOnlyList <Range <string> > > queryRoutingInfo =
                    await this.TryGetTargetPartitionKeyRangeAsync(
                        request,
                        collection,
                        queryPartitionProvider,
                        routingMapProvider,
                        rangeFromContinuationToken,
                        suppliedTokens);

                if (request.IsNameBased && queryRoutingInfo == null)
                {
                    request.ForceNameCacheRefresh = true;
                    collection = await collectionCache.ResolveCollectionAsync(request, CancellationToken.None);

                    queryRoutingInfo = await this.TryGetTargetPartitionKeyRangeAsync(
                        request,
                        collection,
                        queryPartitionProvider,
                        routingMapProvider,
                        rangeFromContinuationToken,
                        suppliedTokens);
                }

                if (queryRoutingInfo == null)
                {
                    throw new NotFoundException($"{DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)}: Was not able to get queryRoutingInfo even after resolve collection async with force name cache refresh to the following collectionRid: {collection.ResourceId} with the supplied tokens: {JsonConvert.SerializeObject(suppliedTokens)}");
                }

                request.RouteTo(new PartitionKeyRangeIdentity(collection.ResourceId, queryRoutingInfo.Item1.ResolvedRange.Id));

                FeedResponse <CosmosElement> response = await this.ExecuteRequestLazyAsync(request, cancellationToken);

                if (!await this.partitionRoutingHelper.TryAddPartitionKeyRangeToContinuationTokenAsync(
                        response.Headers,
                        providedPartitionKeyRanges: queryRoutingInfo.Item2,
                        routingMapProvider: routingMapProvider,
                        collectionRid: collection.ResourceId,
                        resolvedRangeInfo: queryRoutingInfo.Item1))
                {
                    // Collection to which this request was resolved doesn't exist.
                    // Retry policy will refresh the cache and return NotFound.
                    throw new NotFoundException($"{DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)}: Call to TryAddPartitionKeyRangeToContinuationTokenAsync failed to the following collectionRid: {collection.ResourceId} with the supplied tokens: {JsonConvert.SerializeObject(suppliedTokens)}");
                }

                return(response);
            }
        }
コード例 #20
0
        /// <summary>
        /// Exposing progress with the Estimator with the detailed iterator.
        /// </summary>
        /// <remarks>
        /// The Estimator uses the same processorName and the same lease configuration as the existing processor to measure progress.
        /// The iterator exposes detailed, per-lease, information on estimation and ownership.
        /// </remarks>
        public static async Task RunEstimatorPullChangeFeed(
            string databaseId,
            CosmosClient client)
        {
            await Program.InitializeAsync(databaseId, client);

            // <StartProcessorEstimatorDetailed>
            Container           leaseContainer      = client.GetContainer(databaseId, Program.leasesContainer);
            Container           monitoredContainer  = client.GetContainer(databaseId, Program.monitoredContainer);
            ChangeFeedProcessor changeFeedProcessor = monitoredContainer
                                                      .GetChangeFeedProcessorBuilder <ToDoItem>("changeFeedEstimator", Program.HandleChangesAsync)
                                                      .WithInstanceName("consoleHost")
                                                      .WithLeaseContainer(leaseContainer)
                                                      .Build();

            // </StartProcessorEstimatorDetailed>

            Console.WriteLine($"Starting Change Feed Processor...");
            await changeFeedProcessor.StartAsync();

            Console.WriteLine("Change Feed Processor started.");

            // Wait some seconds for instances to acquire leases
            await Task.Delay(5000);

            Console.WriteLine("Generating 10 items that will be picked up by the delegate...");
            await Program.GenerateItems(10, client.GetContainer(databaseId, Program.monitoredContainer));

            // Wait random time for the delegate to output all messages after initialization is done
            await Task.Delay(5000);

            // <StartEstimatorDetailed>
            ChangeFeedEstimator changeFeedEstimator = monitoredContainer
                                                      .GetChangeFeedEstimator("changeFeedEstimator", leaseContainer);

            // </StartEstimatorDetailed>

            // <GetIteratorEstimatorDetailed>
            Console.WriteLine("Checking estimation...");
            using FeedIterator <ChangeFeedProcessorState> estimatorIterator = changeFeedEstimator.GetCurrentStateIterator();
            while (estimatorIterator.HasMoreResults)
            {
                FeedResponse <ChangeFeedProcessorState> states = await estimatorIterator.ReadNextAsync();

                foreach (ChangeFeedProcessorState leaseState in states)
                {
                    string host = leaseState.InstanceName == null ? $"not owned by any host currently" : $"owned by host {leaseState.InstanceName}";
                    Console.WriteLine($"Lease [{leaseState.LeaseToken}] {host} reports {leaseState.EstimatedLag} as estimated lag.");
                }
            }
            // </GetIteratorEstimatorDetailed>

            Console.WriteLine("Stopping processor to show how the lag increases if no processing is happening.");
            await changeFeedProcessor.StopAsync();

            // Wait for processor to shutdown completely so the next items generate lag
            await Task.Delay(5000);

            Console.WriteLine("Generating 10 items that will be seen by the Estimator...");
            await Program.GenerateItems(10, client.GetContainer(databaseId, Program.monitoredContainer));

            Console.WriteLine("Checking estimation...");
            using FeedIterator <ChangeFeedProcessorState> estimatorIteratorAfter = changeFeedEstimator.GetCurrentStateIterator();
            while (estimatorIteratorAfter.HasMoreResults)
            {
                FeedResponse <ChangeFeedProcessorState> states = await estimatorIteratorAfter.ReadNextAsync();

                foreach (ChangeFeedProcessorState leaseState in states)
                {
                    // Host ownership should be empty as we have already stopped the estimator
                    string host = leaseState.InstanceName == null ? $"not owned by any host currently" : $"owned by host {leaseState.InstanceName}";
                    Console.WriteLine($"Lease [{leaseState.LeaseToken}] {host} reports {leaseState.EstimatedLag} as estimated lag.");
                }
            }



            Console.WriteLine("Press any key to continue with the next demo...");
            Console.ReadKey();
        }
コード例 #21
0
        // </RunSimpleScript>

        /// <summary>
        /// Import many documents using stored procedure.
        /// </summary>
        // <RunBulkImport>
        private static async Task RunBulkImport(Container container)
        {
            string inputDirectory = @".\Data\";
            string inputFileMask  = "*.json";
            int    maxFiles       = 2000;
            int    maxScriptSize  = 50000;

            // 1. Get the files.
            string[]      fileNames = Directory.GetFiles(inputDirectory, inputFileMask);
            DirectoryInfo di        = new DirectoryInfo(inputDirectory);

            FileInfo[] fileInfos = di.GetFiles(inputFileMask);

            // 2. Prepare for import.
            int currentCount = 0;
            int fileCount    = maxFiles != 0 ? Math.Min(maxFiles, fileNames.Length) : fileNames.Length;

            // 3. Create stored procedure for this script.
            string scriptId = "BulkImport";
            string body     = File.ReadAllText(@".\JS\BulkImport.js");

            await TryDeleteStoredProcedure(container, scriptId);

            Scripts cosmosScripts         = container.Scripts;
            StoredProcedureResponse sproc = await cosmosScripts.CreateStoredProcedureAsync(new StoredProcedureProperties(scriptId, body));

            // 4. Create a batch of docs (MAX is limited by request size (2M) and to script for execution.
            // We send batches of documents to create to script.
            // Each batch size is determined by MaxScriptSize.
            // MaxScriptSize should be so that:
            // -- it fits into one request (MAX request size is 16Kb).
            // -- it doesn't cause the script to time out.
            // -- it is possible to experiment with MaxScriptSize to get best performance given number of throttles, etc.
            while (currentCount < fileCount)
            {
                // 5. Create args for current batch.
                //    Note that we could send a string with serialized JSON and JSON.parse it on the script side,
                //    but that would cause script to run longer. Since script has timeout, unload the script as much
                //    as we can and do the parsing by client and framework. The script will get JavaScript objects.
                string    argsJson = CreateBulkInsertScriptArguments(fileNames, currentCount, fileCount, maxScriptSize);
                dynamic[] args     = new dynamic[] { JsonConvert.DeserializeObject <dynamic>(argsJson) };

                // 6. execute the batch.
                StoredProcedureExecuteResponse <int> scriptResult = await cosmosScripts.ExecuteStoredProcedureAsync <dynamic, int>(new PartitionKey("Andersen"), scriptId, args);

                // 7. Prepare for next batch.
                int currentlyInserted = scriptResult.Resource;
                currentCount += currentlyInserted;
            }

            // 8. Validate
            int numDocs = 0;

            FeedIterator <dynamic> setIterator = container.GetItemIterator <dynamic>();

            while (setIterator.HasMoreResults)
            {
                FeedResponse <dynamic> response = await setIterator.ReadNextAsync();

                numDocs += response.Count();
            }

            Console.WriteLine("Found {0} documents in the collection. There were originally {1} files in the Data directory\r\n", numDocs, fileCount);
        }
コード例 #22
0
        public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, TraceWriter log)

        {
            _subscriptionId       = GetEnvironmentVariable("subscriptionId");
            _tenantId             = GetEnvironmentVariable("tenantId");
            _applicationId        = GetEnvironmentVariable("applicationId");
            _applicationPwd       = GetEnvironmentVariable("applicationPwd");
            _resourceGroupName    = GetEnvironmentVariable("resourceGroupName");
            _accountName          = GetEnvironmentVariable("accountName");
            _accountUri           = GetEnvironmentVariable("accountUri");
            _accountKey           = GetEnvironmentVariable("authKey");
            _dbName               = GetEnvironmentVariable("dbName");
            _collName             = GetEnvironmentVariable("collName");
            _maxAllowedThroughput = GetEnvironmentVariable("maxAllowedThroughput");
            _minAllowedThroughput = GetEnvironmentVariable("minAllowedThroughput");
            _throughputStep       = GetEnvironmentVariable("throughputStep");
            //Console.WriteLine("accountUri: " + _accountUri);

            log.Info($"Timer trigger function executed at: {DateTime.Now}");

            docDbClient = new DocumentClient(
                new Uri(_accountUri),
                _accountKey,
                new ConnectionPolicy
            {
                ConnectionMode     = ConnectionMode.Direct,
                ConnectionProtocol = Protocol.Tcp
            });

            DocumentCollection collection = GetCollection(_dbName, _collName);

            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(_dbName, collection.Id);
            FeedResponse <PartitionKeyRange> pkRanges = docDbClient.ReadPartitionKeyRangeFeedAsync(
                collectionUri).Result;
            int partitionCount = pkRanges.Count;

            log.Info($"The number of partitions in the collection is {partitionCount}");

            int provisionedThroughput = GetOfferThroughput(collection.SelfLink);

            log.Info($"Provisioned throughtput is {provisionedThroughput}");
            int partitionThroughput = provisionedThroughput / partitionCount;


            MetricCollection metricList = ReadMetricValues(collection.SelfLink, GetAccessToken());

            int throughputIncrease = 0;

            bool isCollectionBusy            = false;
            bool isCollectionOverProvisioned = true;

            foreach (var metric in metricList.Value)
            {
                foreach (var metricValue in metric.MetricValues)
                {
                    log.Info($"Max RUs Per Second is {metricValue.Maximum}. Throughtput per partition is {partitionThroughput}");

                    if (metricValue.Maximum > partitionThroughput)
                    {
                        isCollectionBusy            = true;
                        isCollectionOverProvisioned = false;
                        log.Info($"Partition throughput increased more than provisioned at {metricValue.Maximum} - {metricValue.Timestamp}");
                        throughputIncrease = (int)metricValue.Maximum * partitionCount;
                        break;
                    }
                    else if (partitionThroughput > metricValue.Maximum)
                    {
                        isCollectionOverProvisioned = true;
                    }
                }
            }

            if (isCollectionBusy)
            {
                if (throughputIncrease > Int32.Parse(_maxAllowedThroughput))
                {
                    log.Info($"Max throughput limit reached - {_maxAllowedThroughput}. Cannot scale up further");
                    ScaleOffer(_dbName, _collName, Int32.Parse(_maxAllowedThroughput));
                    return;
                }
                log.Info($"Scaling up collection {_collName} throughput to {throughputIncrease}");
                ScaleOffer(_dbName, _collName, throughputIncrease);
            }
            if (isCollectionOverProvisioned)
            {
                throughputIncrease = partitionThroughput - Int32.Parse(_throughputStep);
                if (Int32.Parse(_minAllowedThroughput) > throughputIncrease)
                {
                    log.Info($"Min throughput limit reached - {_minAllowedThroughput}. Cannot scale down further");
                    ScaleOffer(_dbName, _collName, Int32.Parse(_minAllowedThroughput));
                    return;
                }
                log.Info($"Scaling down collection {_collName} throughput to {throughputIncrease}");
                ScaleOffer(_dbName, _collName, throughputIncrease);
            }
            log.Info($"Completed execution at: {DateTime.Now}");
        }
コード例 #23
0
        public async Task RunAsync(
            CTLConfig config,
            CosmosClient cosmosClient,
            ILogger logger,
            IMetrics metrics,
            string loggingContextIdentifier,
            CancellationToken cancellationToken)
        {
            logger.LogInformation("Initializing counters and metrics.");
            CounterOptions documentCounter = new CounterOptions {
                Name = "#Documents received", Context = loggingContextIdentifier
            };
            GaugeOptions leaseGauge = new GaugeOptions {
                Name = "#Leases created", Context = loggingContextIdentifier
            };

            string    leaseContainerId = Guid.NewGuid().ToString();
            Container leaseContainer   = await cosmosClient.GetDatabase(config.Database).CreateContainerAsync(leaseContainerId, "/id");

            logger.LogInformation("Created lease container {0}", leaseContainerId);

            try
            {
                object lockObject    = new object();
                long   documentTotal = 0;
                ChangeFeedProcessor changeFeedProcessor = cosmosClient.GetContainer(config.Database, config.Collection)
                                                          .GetChangeFeedProcessorBuilder <SimpleItem>("ctlProcessor",
                                                                                                      (IReadOnlyCollection <SimpleItem> docs, CancellationToken token) =>
                {
                    lock (lockObject)
                    {
                        documentTotal += docs.Count;
                    }

                    metrics.Measure.Counter.Increment(documentCounter, docs.Count);
                    return(Task.CompletedTask);
                })
                                                          .WithLeaseContainer(leaseContainer)
                                                          .WithInstanceName(Guid.NewGuid().ToString())
                                                          .WithErrorNotification((string leaseToken, Exception ex) =>
                {
                    Utils.LogError(logger, loggingContextIdentifier, ex);
                    return(Task.CompletedTask);
                })
                                                          .WithStartTime(DateTime.MinValue.ToUniversalTime())
                                                          .Build();

                await changeFeedProcessor.StartAsync();

                logger.LogInformation("Started change feed processor");

                await Task.Delay(config.RunningTimeDurationAsTimespan, cancellationToken);

                logger.LogInformation("Stopping change feed processor");
                await changeFeedProcessor.StopAsync();

                // List leases
                using FeedIterator <LeaseSchema> leaseIterator = leaseContainer.GetItemQueryIterator <LeaseSchema>();
                int leaseTotal          = 0;
                List <FeedRange> ranges = new List <FeedRange>();
                while (leaseIterator.HasMoreResults)
                {
                    FeedResponse <LeaseSchema> response = await leaseIterator.ReadNextAsync();

                    foreach (LeaseSchema lease in response)
                    {
                        if (lease.LeaseToken != null)
                        {
                            logger.LogInformation($"Lease for range {lease.LeaseToken} - {lease.FeedRange.EffectiveRange.Min} - {lease.FeedRange.EffectiveRange.Max}");
                            ranges.Add(lease.FeedRange.EffectiveRange);
                            leaseTotal++;
                        }
                    }
                }

                logger.LogInformation($"Total count of leases {leaseTotal}.");
                metrics.Measure.Gauge.SetValue(leaseGauge, leaseTotal);

                string previousMin = "";
                foreach (FeedRange sortedRange in ranges.OrderBy(range => range.Min))
                {
                    if (previousMin != sortedRange.Min)
                    {
                        Utils.LogError(logger, loggingContextIdentifier,
                                       $"Expected a sorted range with Min <{previousMin}> but encountered range <{sortedRange.Min}>:<{sortedRange.Max}>");
                    }

                    previousMin = sortedRange.Max;
                }

                if (config.PreCreatedDocuments > 0)
                {
                    if (this.initializationResult.InsertedDocuments != documentTotal)
                    {
                        Utils.LogError(logger, loggingContextIdentifier, $"Expected to receive {this.initializationResult.InsertedDocuments} documents and got {documentTotal}");
                    }
                }
            }
            catch (Exception ex)
            {
                Utils.LogError(logger, loggingContextIdentifier, ex);
            }
            finally
            {
                await leaseContainer.DeleteContainerAsync();

                if (this.initializationResult.CreatedDatabase)
                {
                    await cosmosClient.GetDatabase(config.Database).DeleteAsync();
                }

                if (this.initializationResult.CreatedContainer)
                {
                    await cosmosClient.GetContainer(config.Database, config.Collection).DeleteContainerAsync();
                }
            }
        }
コード例 #24
0
        public async Task ChangeFeedIteratorCore_PartitionKey_OfT_ReadAll()
        {
            int totalCount    = 0;
            int firstRunTotal = 25;
            int batchSize     = 25;

            string pkToRead = "pkToRead";
            string otherPK  = "otherPK";

            for (int i = 0; i < batchSize; i++)
            {
                await this.Container.CreateItemAsync(this.CreateRandomToDoActivity(pkToRead));
            }

            for (int i = 0; i < batchSize; i++)
            {
                await this.Container.CreateItemAsync(this.CreateRandomToDoActivity(otherPK));
            }

            ContainerInternal           itemsCore    = this.Container;
            FeedIterator <ToDoActivity> feedIterator = itemsCore.GetChangeFeedIterator <ToDoActivity>(
                ChangeFeedStartFrom.Beginning(
                    new FeedRangePartitionKey(
                        new PartitionKey(pkToRead))),
                new ChangeFeedRequestOptions()
            {
                PageSizeHint = 1,
            });
            string continuation = null;

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

                totalCount += feedResponse.Count;
                foreach (ToDoActivity toDoActivity in feedResponse)
                {
                    Assert.AreEqual(pkToRead, toDoActivity.status);
                }

                continuation = feedResponse.ContinuationToken;
            }

            Assert.AreEqual(firstRunTotal, totalCount);

            int expectedFinalCount = 50;

            // Insert another batch of 25 and use the last FeedToken from the first cycle
            for (int i = 0; i < batchSize; i++)
            {
                await this.Container.CreateItemAsync(this.CreateRandomToDoActivity(pkToRead));
            }

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

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

                totalCount += feedResponse.Count;
                foreach (ToDoActivity toDoActivity in feedResponse)
                {
                    Assert.AreEqual(pkToRead, toDoActivity.status);
                }
            }

            Assert.AreEqual(expectedFinalCount, totalCount);
        }
コード例 #25
0
        public async Task ItemResourcePermissionTest()
        {
            //create user
            string       userId       = Guid.NewGuid().ToString();
            UserResponse userResponse = await this.cosmosDatabase.CreateUserAsync(userId);

            Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode);
            Assert.AreEqual(userId, userResponse.Resource.Id);
            User user = userResponse.User;

            //create resource
            string            containerId       = Guid.NewGuid().ToString();
            ContainerResponse containerResponse = await this.cosmosDatabase.CreateContainerAsync(containerId, "/id");

            Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode);
            Container              container    = containerResponse.Container;
            string                 itemId       = Guid.NewGuid().ToString();
            PartitionKey           partitionKey = new PartitionKey(itemId);
            ItemResponse <dynamic> itemRespnose = await container.CreateItemAsync <dynamic>(new { id = itemId }, partitionKey);

            Assert.AreEqual(HttpStatusCode.Created, itemRespnose.StatusCode);

            //create permission
            string permissionId = Guid.NewGuid().ToString();
            PermissionProperties permissionProperties = new PermissionProperties(permissionId, PermissionMode.Read, container, partitionKey, itemId);
            PermissionResponse   permissionResponse   = await user.CreatePermissionAsync(permissionProperties);

            PermissionProperties permission = permissionResponse.Resource;

            Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode);
            Assert.AreEqual(permissionId, permission.Id);
            Assert.AreEqual(permissionProperties.PermissionMode, permission.PermissionMode);

            //delete resource with PermissionMode.Read
            using (CosmosClient tokenCosmosClient = TestCommon.CreateCosmosClient(clientOptions: null, resourceToken: permission.Token))
            {
                Container tokenContainer = tokenCosmosClient.GetContainer(this.cosmosDatabase.Id, containerId);
                ItemResponse <dynamic> readPermissionItem = await tokenContainer.ReadItemAsync <dynamic>(itemId, partitionKey);

                Assert.AreEqual(itemId, readPermissionItem.Resource.id.ToString());

                try
                {
                    ItemResponse <dynamic> response = await tokenContainer.DeleteItemAsync <dynamic>(
                        itemId,
                        partitionKey);

                    Assert.Fail();
                }
                catch (CosmosException ex)
                {
                    Assert.AreEqual(HttpStatusCode.Forbidden, ex.StatusCode);
                }
            }

            //update permission to PermissionMode.All
            permissionProperties = new PermissionProperties(permissionId, PermissionMode.All, container);
            permissionResponse   = await user.GetPermission(permissionId).ReplaceAsync(permissionProperties);

            permission = permissionResponse.Resource;

            //delete resource with PermissionMode.All
            using (CosmosClient tokenCosmosClient = TestCommon.CreateCosmosClient(clientOptions: null, resourceToken: permission.Token))
            {
                FeedIterator <dynamic> feed = tokenCosmosClient
                                              .GetDatabase(this.cosmosDatabase.Id)
                                              .GetContainer(containerId)
                                              .GetItemQueryIterator <dynamic>(new QueryDefinition("select * from t"));

                while (feed.HasMoreResults)
                {
                    FeedResponse <dynamic> response = await feed.ReadNextAsync();

                    Assert.IsNotNull(response);
                }
            }
        }
コード例 #26
0
ファイル: Program.cs プロジェクト: morcodou/az-204-exam-ref
        private async Task StartDemo()
        {
            Console.WriteLine("Starting Cosmos DB SQL API Demo!");

            //Create a new demo database
            string databaseName = "demoDB_" + Guid.NewGuid().ToString().Substring(0, 5);

            this.SendMessageToConsoleAndWait($"Creating database {databaseName}...");

            this.client   = new CosmosClient(EndpointUri, Key);
            this.database = await this.client.CreateDatabaseIfNotExistsAsync(databaseName);

            //Create a new demo collection inside the demo database.
            //This creates a collection with a reserved throughput. You can customize the options using a ContainerProperties object
            //This operation has pricing implications.
            string containerName = "collection_" + Guid.NewGuid().ToString().Substring(0, 5);


            this.SendMessageToConsoleAndWait($"Creating collection demo{containerName}...");

            this.container = await this.database.CreateContainerIfNotExistsAsync(containerName, "/LastName");

            //Create some documents in the collection
            Person person1 = new Person
            {
                Id        = "Person.1",
                FirstName = "Santiago",
                LastName  = "Fernandez",
                Devices   = new Device[]
                {
                    new Device {
                        OperatingSystem = "iOS", CameraMegaPixels = 7,
                        Ram             = 16, Usage = "Personal"
                    },
                    new Device {
                        OperatingSystem = "Android", CameraMegaPixels = 12,
                        Ram             = 64, Usage = "Work"
                    }
                },
                Gender  = "Male",
                Address = new Address

                {
                    City       = "Seville",
                    Country    = "Spain",
                    PostalCode = "28973",
                    Street     = "Diagonal",
                    State      = "Andalucia"
                },
                IsRegistered = true
            };


            await this.CreateDocumentIfNotExistsAsync(databaseName, containerName, person1);

            Person person2 = new Person
            {
                Id        = "Person.2",
                FirstName = "Agatha",
                LastName  = "Smith",
                Devices   = new Device[]
                {
                    new Device {
                        OperatingSystem = "iOS", CameraMegaPixels = 12,
                        Ram             = 32, Usage = "Work"
                    },
                    new Device {
                        OperatingSystem = "Windows", CameraMegaPixels = 12,
                        Ram             = 64, Usage = "Personal"
                    }
                },
                Gender  = "Female",
                Address = new Address
                {
                    City       = "Laguna Beach",
                    Country    = "United States",
                    PostalCode = "12345",
                    Street     = "Main",
                    State      = "CA"
                },
                IsRegistered = true
            };


            await this.CreateDocumentIfNotExistsAsync(databaseName, containerName, person2);

            //Make some queries to the collection
            this.SendMessageToConsoleAndWait($"Getting documents from the collection{containerName}...");

            //Find documents using LINQ

            IQueryable <Person> queryablePeople = this.container.GetItemLinqQueryable <Person>(true)
                                                  .Where(p => p.Gender == "Male");

            System.Console.WriteLine("Running LINQ query for finding men...");
            foreach (Person foundPerson in queryablePeople)
            {
                System.Console.WriteLine($"\tPerson: {foundPerson}");
            }

            //Find documents using SQL

            var sqlQuery = "SELECT * FROM Person WHERE Person.Gender = 'Female'";

            QueryDefinition       queryDefinition         = new QueryDefinition(sqlQuery);
            FeedIterator <Person> peopleResultSetIterator = this.container.GetItemQueryIterator <Person>(queryDefinition);

            System.Console.WriteLine("Running SQL query for finding women...");
            while (peopleResultSetIterator.HasMoreResults)
            {
                FeedResponse <Person> currentResultSet = await peopleResultSetIterator.ReadNextAsync();

                foreach (Person foundPerson in currentResultSet)
                {
                    System.Console.WriteLine($"\tPerson: {foundPerson}");
                }
            }

            Console.WriteLine("Press any key to continue...");

            Console.ReadKey();

            //Update documents in a collection
            this.SendMessageToConsoleAndWait($"Updating documents in the collection { containerName}...");
            person2.FirstName = "Mathew";
            person2.Gender    = "Male";

            await this.container.UpsertItemAsync(person2);

            this.SendMessageToConsoleAndWait($"Document modified {person2}");

            //Delete a single document from the collection
            this.SendMessageToConsoleAndWait($"Deleting documents from the collection { containerName}...");

            PartitionKey partitionKey = new PartitionKey(person1.LastName);

            await this.container.DeleteItemAsync <Person>(person1.Id, partitionKey);

            this.SendMessageToConsoleAndWait($"Document deleted {person1}");

            //Delete created demo database and all its children elements
            this.SendMessageToConsoleAndWait("Cleaning-up your Cosmos DB account...");
            await this.database.DeleteAsync();
        }
コード例 #27
0
        /// <inheritdoc/>
        public async Task <InstanceQueryResponse> GetInstancesFromQuery(
            Dictionary <string, StringValues> queryParams,
            string continuationToken,
            int size)
        {
            InstanceQueryResponse queryResponse = new InstanceQueryResponse
            {
                Count     = 0,
                Instances = new List <Instance>()
            };

            while (queryResponse.Count < size)
            {
                FeedOptions feedOptions = new FeedOptions
                {
                    EnableCrossPartitionQuery = true,
                    MaxItemCount = size - queryResponse.Count,
                    ResponseContinuationTokenLimitInKb = 7
                };

                if (!string.IsNullOrEmpty(continuationToken))
                {
                    feedOptions.RequestContinuation = continuationToken;
                }

                IQueryable <Instance> queryBuilder = _client.CreateDocumentQuery <Instance>(_collectionUri, feedOptions);

                try
                {
                    queryBuilder = BuildQueryFromParameters(queryParams, queryBuilder)
                                   .Where(i => !i.Status.IsHardDeleted);
                }
                catch (Exception e)
                {
                    queryResponse.Exception = e.Message;
                    return(queryResponse);
                }

                try
                {
                    IDocumentQuery <Instance> documentQuery = queryBuilder.AsDocumentQuery();

                    FeedResponse <Instance> feedResponse = await documentQuery.ExecuteNextAsync <Instance>();

                    if (feedResponse.Count == 0 && !documentQuery.HasMoreResults)
                    {
                        queryResponse.ContinuationToken = string.Empty;
                        break;
                    }

                    List <Instance> instances = feedResponse.ToList();
                    await PostProcess(instances);

                    queryResponse.Instances.AddRange(instances);
                    queryResponse.Count += instances.Count;

                    if (string.IsNullOrEmpty(feedResponse.ResponseContinuation))
                    {
                        queryResponse.ContinuationToken = string.Empty;
                        break;
                    }

                    queryResponse.ContinuationToken = feedResponse.ResponseContinuation;
                    continuationToken = feedResponse.ResponseContinuation;
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Exception querying CosmosDB for instances");
                    queryResponse.Exception = e.Message;
                    break;
                }
            }

            return(queryResponse);
        }
コード例 #28
0
        public async Task ParallelizeQueryThroughTokens_OfT()
        {
            ContainerInternal container = null;

            try
            {
                // Create a container large enough to have at least 2 partitions
                ContainerResponse containerResponse = await this.database.CreateContainerAsync(
                    id : Guid.NewGuid().ToString(),
                    partitionKeyPath : "/id",
                    throughput : 15000);

                container = (ContainerInlineCore)containerResponse;

                List <string> generatedIds = Enumerable.Range(0, 1000).Select(n => $"BasicItem{n}").ToList();
                foreach (string id in generatedIds)
                {
                    string item = $@"
                    {{    
                        ""id"": ""{id}""
                    }}";

                    using (ResponseMessage createResponse = await container.CreateItemStreamAsync(
                               QueryFeedRangeTests.GenerateStreamFromString(item),
                               new Cosmos.PartitionKey(id)))
                    {
                        Assert.IsTrue(createResponse.IsSuccessStatusCode);
                    }
                }

                IReadOnlyList <FeedRange> feedTokens = await container.GetFeedRangesAsync();

                Assert.IsTrue(feedTokens.Count > 1, " RUs of the container needs to be increased to ensure at least 2 partitions.");

                List <Task <List <string> > > tasks = feedTokens.Select(async feedToken =>
                {
                    List <string> results = new List <string>();
                    FeedIterator <ToDoActivity> feedIterator = container.GetItemQueryIterator <ToDoActivity>(queryDefinition: new QueryDefinition("select * from T where STARTSWITH(T.id, \"BasicItem\")"), feedRange: feedToken, requestOptions: new QueryRequestOptions()
                    {
                        MaxItemCount = 10
                    });
                    string continuation = null;
                    while (feedIterator.HasMoreResults)
                    {
                        FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync();
                        foreach (ToDoActivity toDoActivity in response)
                        {
                            results.Add(toDoActivity.id);
                        }

                        continuation = response.ContinuationToken;
                        break;
                    }

                    feedIterator = container.GetItemQueryIterator <ToDoActivity>(queryDefinition: new QueryDefinition("select * from T where STARTSWITH(T.id, \"BasicItem\")"), feedRange: feedToken, continuationToken: continuation, requestOptions: new QueryRequestOptions()
                    {
                        MaxItemCount = 10
                    });
                    while (feedIterator.HasMoreResults)
                    {
                        FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync();
                        foreach (ToDoActivity toDoActivity in response)
                        {
                            results.Add(toDoActivity.id);
                        }
                    }

                    return(results);
                }).ToList();

                await Task.WhenAll(tasks);

                CollectionAssert.AreEquivalent(generatedIds, tasks.SelectMany(t => t.Result).ToList());
            }
            finally
            {
                await container?.DeleteContainerAsync();
            }
        }
コード例 #29
0
        public static async void Run([CosmosDBTrigger(
                                          databaseName: "contoso",
                                          collectionName: "orders-aggregate",
                                          ConnectionStringSetting = "CosmosConnectionString",
                                          LeaseCollectionName = "leases")] IReadOnlyList <Microsoft.Azure.Documents.Document> input, ILogger log)
        {
            if (input != null && input.Count > 0)
            {
                log.LogInformation("Documents modified " + input.Count);
                log.LogInformation("First document Id " + input[0].Id);

                string       connStr               = Environment.GetEnvironmentVariable("CosmosConnectionString");
                CosmosClient cosmosClient          = new CosmosClient(connStr);
                Microsoft.Azure.Cosmos.Database db = cosmosClient.GetDatabase("contoso");
                Container container = db.GetContainer("orders-for-hour");

                // custQuery is an IEnumerable<IGrouping<string, Customer>>
                var dateQuery =
                    from o in input
                    group o by o.GetPropertyValue <string>("OrderDateHour") into orderDateGroup
                    select orderDateGroup;

                log.LogInformation(dateQuery.Count().ToString());

                foreach (var dq in dateQuery)
                {
                    log.LogInformation("DateQuery: " + dq.Key);

                    var sqlQueryText = $"SELECT * FROM c WHERE c.id = '{dq.Key}'";

                    log.LogInformation("Running query: {0}\n", sqlQueryText);

                    QueryDefinition           queryDefinition        = new QueryDefinition(sqlQueryText);
                    FeedIterator <OrderEvent> queryResultSetIterator = container.GetItemQueryIterator <OrderEvent>(queryDefinition);

                    List <OrderEvent> orders = new List <OrderEvent>();

                    while (queryResultSetIterator.HasMoreResults)
                    {
                        log.LogInformation("In loop");
                        FeedResponse <OrderEvent> currentResultSet = await queryResultSetIterator.ReadNextAsync();

                        foreach (OrderEvent order in currentResultSet)
                        {
                            orders.Add(order);
                            log.LogInformation("\tRead {0}\n", order);
                        }
                    }

                    log.LogInformation("Orders Count: " + orders.Count);

                    OrderEvent currentOrder = new OrderEvent()
                    {
                        id = dq.Key, Count = dq.Count(), Total = dq.Sum(x => x.GetPropertyValue <decimal>("Total"))
                    };

                    if (orders.Count == 0)
                    {
                        log.LogInformation("Addin entry");
                        try
                        {
                            ItemResponse <OrderEvent> orderResponse = await container.CreateItemAsync <OrderEvent>(currentOrder);
                        }
                        catch (Exception ex)
                        {
                            log.LogInformation("Exception: " + ex.Message);
                        }
                    }
                    else
                    {
                        ItemResponse <OrderEvent> orderResponse = await container.ReadItemAsync <OrderEvent>(dq.Key, new PartitionKey(dq.Key));

                        int     currentCount = orderResponse.Resource.Count;
                        decimal currentTotal = orderResponse.Resource.Total;

                        OrderEvent newOrder = new OrderEvent()
                        {
                            id = dq.Key, Count = currentCount + currentOrder.Count, Total = currentTotal + currentOrder.Total
                        };
                        orderResponse = await container.ReplaceItemAsync <OrderEvent>(newOrder, newOrder.id);
                    }
                }
            }
        }
コード例 #30
0
        private async Task ValidateServerSideQueryEvalWithPaginationScenario()
        {
            DocumentClient client = TestCommon.CreateClient(false, defaultConsistencyLevel: ConsistencyLevel.Session);

            CosmosDatabaseSettings  database   = TestCommon.CreateOrGetDatabase(client);
            CosmosContainerSettings collection = new CosmosContainerSettings
            {
                Id = "ConsistentCollection"
            };

            collection.IndexingPolicy.IndexingMode = IndexingMode.Consistent;

            collection = client.Create <CosmosContainerSettings>(
                database.ResourceId,
                collection);

            //Do script post to insert as many document as we could in a tight loop.
            string script = @"function() {
                var output = 0;
                var client = getContext().getCollection();
                function callback(err, docCreated) {
                    if(err) throw 'Error while creating document';
                    output++;
                    getContext().getResponse().setBody(output);
                    if(output < 50) 
                        client.createDocument(client.getSelfLink(), { id: 'testDoc' + output, title : 'My Book'}, {}, callback);                       
                };
                client.createDocument(client.getSelfLink(), { id: 'testDoc' + output, title : 'My Book'}, {}, callback); }";


            StoredProcedureResponse <int> scriptResponse = null;
            int totalNumberOfDocuments = GatewayTests.CreateExecuteAndDeleteProcedure(client, collection, script, out scriptResponse);

            int pageSize = 5;
            int totalHit = 0;
            IDocumentQuery <Book> documentQuery =
                (from book in client.CreateDocumentQuery <Book>(
                     collection.SelfLink, new FeedOptions {
                MaxItemCount = pageSize
            })
                 where book.Title == "My Book"
                 select book).AsDocumentQuery();

            while (documentQuery.HasMoreResults)
            {
                FeedResponse <dynamic> pagedResult = await documentQuery.ExecuteNextAsync();

                string isUnfiltered = pagedResult.ResponseHeaders[HttpConstants.HttpHeaders.IsFeedUnfiltered];
                Assert.IsTrue(string.IsNullOrEmpty(isUnfiltered), "Query is evaulated in client");
                Assert.IsTrue(pagedResult.Count <= pageSize, "Page size is not honored in client site eval");

                if (totalHit != 0 && documentQuery.HasMoreResults)
                {
                    //Except first page and last page we should have seen client continuation token.
                    Assert.IsFalse(pagedResult.ResponseHeaders[HttpConstants.HttpHeaders.Continuation].Contains(HttpConstants.Delimiters.ClientContinuationDelimiter),
                                   "Client continuation is missing from the response continuation");
                }
                totalHit += pagedResult.Count;
            }
            Assert.AreEqual(totalHit, totalNumberOfDocuments, "Didnt get all the documents");

            //Do with default pagination.
            documentQuery =
                (from book in client.CreateDocumentQuery <Book>(
                     collection.SelfLink)
                 where book.Title == "My Book"
                 select book).AsDocumentQuery();

            totalHit = 0;

            while (documentQuery.HasMoreResults)
            {
                FeedResponse <dynamic> pagedResult = await documentQuery.ExecuteNextAsync();

                string isUnfiltered = pagedResult.ResponseHeaders[HttpConstants.HttpHeaders.IsFeedUnfiltered];
                Assert.IsTrue(string.IsNullOrEmpty(isUnfiltered), "Query is evaulated in client");
                Assert.IsTrue(pagedResult.Count == totalNumberOfDocuments, "Page size is not honored in client site eval");
                totalHit += pagedResult.Count;
            }
            Assert.AreEqual(totalHit, totalNumberOfDocuments, "Didnt get all the documents");
        }