public EncryptionTransactionalBatchResponse(
     IReadOnlyList <TransactionalBatchOperationResult> results,
     TransactionalBatchResponse response,
     CosmosSerializer cosmosSerializer,
     CosmosDiagnostics diagnostics)
 {
     this.results          = results;
     this.response         = response;
     this.cosmosSerializer = cosmosSerializer;
     this.diagnostics      = diagnostics;
 }
示例#2
0
        public static async Task CreateHugeMountainBikeOrder()
        {
            Database  database  = client.GetDatabase("database-v4");
            Container container = database.GetContainer("customer");

            //Get the customer
            string customerId = "FFD0DD37-1F0E-4E2E-8FAC-EAF45B0E9447";
            ItemResponse <CustomerV4> response = await container.ReadItemAsync <CustomerV4>(
                id : customerId,
                partitionKey : new PartitionKey(customerId)
                );

            CustomerV4 customer = response.Resource;

            //Increment the salesOrderTotal property
            customer.salesOrderCount++;

            //Create a new order
            string orderId = "f571e271-c98e-44d1-bb6c-47ad353c4ebc";

            SalesOrder salesOrder = new SalesOrder
            {
                id         = orderId,
                type       = "salesOrder",
                customerId = customer.id,
                orderDate  = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"),
                shipDate   = "",
                details    = new List <SalesOrderDetails>
                {
                    new SalesOrderDetails
                    {
                        sku      = "BK-M82S-44",
                        name     = "Mountain-100 Silver, 44",
                        price    = 3399.99,
                        quantity = 170
                    }
                }
            };

            //Submit both as a transactional batch
            TransactionalBatchResponse txBatchResponse = await container.CreateTransactionalBatch(
                new PartitionKey(salesOrder.customerId))
                                                         .CreateItem <SalesOrder>(salesOrder)
                                                         .ReplaceItem <CustomerV4>(customer.id, customer)
                                                         .ExecuteAsync();

            if (txBatchResponse.IsSuccessStatusCode)
            {
                Console.WriteLine("Order created successfully");
            }

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
        public async Task ItemBatchNoResponseTest()
        {
            TransactionalBatchItemRequestOptions requestOptions = new TransactionalBatchItemRequestOptions()
            {
                EnableContentResponseOnWrite = false
            };

            string             pkId  = "TestBatchId";
            TransactionalBatch batch = this.container.CreateTransactionalBatch(new PartitionKey(pkId));

            int noResponseItemCount = 100;

            for (int i = 0; i < noResponseItemCount; i++)
            {
                ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkId);
                batch.CreateItem <ToDoActivity>(item, requestOptions: requestOptions);
            }

            TransactionalBatchResponse response = await batch.ExecuteAsync();

            Assert.AreEqual(100, response.Count);
            this.ValidateResponse(response, noResponseItemCount);

            pkId  = "TestBatchId2";
            batch = this.container.CreateTransactionalBatch(new PartitionKey(pkId));

            noResponseItemCount = 0;
            for (int i = 0; i < 10; i++)
            {
                ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkId);
                batch.CreateItem <ToDoActivity>(item, requestOptions: requestOptions);
                noResponseItemCount++;
                ToDoActivity item2 = ToDoActivity.CreateRandomToDoActivity(pk: pkId);
                item2.id = item.id;
                batch.ReplaceItem <ToDoActivity>(item2.id, item2, requestOptions);
                noResponseItemCount++;
            }

            int withBodyCount = 0;

            for (int i = 0; i < 5; i++)
            {
                ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkId);
                batch.CreateItem <ToDoActivity>(item);
                withBodyCount++;
                batch.ReadItem(item.id);
                withBodyCount++;
            }

            response = await batch.ExecuteAsync();

            Assert.AreEqual(noResponseItemCount + withBodyCount, response.Count);
            this.ValidateResponse(response, noResponseItemCount);
        }
示例#4
0
    internal static IEnumerable <T> GetOperationResultResources <T>(this TransactionalBatchResponse batchResponse)
    {
        if (!batchResponse.IsSuccessStatusCode)
        {
            yield break;
        }

        for (int i = 0; i < batchResponse.Count; i++)
        {
            var operationResult = batchResponse.GetOperationResultAtIndex <T>(i);

            yield return(operationResult.IsSuccessStatusCode ? operationResult.Resource : default);
示例#5
0
        public override async Task <TransactionalBatchResponse> ExecuteAsync(
            CancellationToken cancellationToken = default)
        {
            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(options: null);

            using (diagnosticsContext.CreateScope("TransactionalBatch.ExecuteAsync"))
            {
                TransactionalBatchResponse response = await this.transactionalBatch.ExecuteAsync(cancellationToken);

                return(await this.DecryptTransactionalBatchResponseAsync(
                           response,
                           diagnosticsContext,
                           cancellationToken));
            }
        }
示例#6
0
        public async Task BatchResponseDeserializationAsync()
        {
            using CosmosClient cosmosClient = MockCosmosUtil.CreateMockCosmosClient();
            ContainerInternal containerCore = (ContainerInlineCore)cosmosClient.GetDatabase("db").GetContainer("cont");
            List <TransactionalBatchOperationResult> results = new List <TransactionalBatchOperationResult>
            {
                new TransactionalBatchOperationResult(HttpStatusCode.Conflict),
                new TransactionalBatchOperationResult(HttpStatusCode.OK)
                {
                    ResourceStream = new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true),
                    RequestCharge  = 2.5,
                    ETag           = "1234",
                    RetryAfter     = TimeSpan.FromMilliseconds(360)
                }
            };

            MemoryStream responseContent = await new BatchResponsePayloadWriter(results).GeneratePayloadAsync();

            CosmosSerializer serializer = new CosmosJsonDotNetSerializer();
            SinglePartitionKeyServerBatchRequest batchRequest = await SinglePartitionKeyServerBatchRequest.CreateAsync(
                partitionKey : Cosmos.PartitionKey.None,
                operations : new ArraySegment <ItemBatchOperation>(
                    new ItemBatchOperation[]
            {
                new ItemBatchOperation(OperationType.Read, operationIndex: 0, id: "someId", containerCore: containerCore),
                new ItemBatchOperation(OperationType.Read, operationIndex: 0, id: "someId", containerCore: containerCore)
            }),
                serializerCore : MockCosmosUtil.Serializer,
                trace : NoOpTrace.Singleton,
                cancellationToken : CancellationToken.None);

            TransactionalBatchResponse batchResponse = await TransactionalBatchResponse.FromResponseMessageAsync(
                new ResponseMessage((HttpStatusCode)StatusCodes.MultiStatus) { Content = responseContent },
                batchRequest,
                MockCosmosUtil.Serializer,
                true,
                NoOpTrace.Singleton,
                CancellationToken.None);

            Assert.IsNotNull(batchRequest);
            Assert.AreEqual(HttpStatusCode.Conflict, batchResponse.StatusCode);
            Assert.AreEqual(2, batchResponse.Count);

            CosmosBatchOperationResultEqualityComparer comparer = new CosmosBatchOperationResultEqualityComparer();

            Assert.IsTrue(comparer.Equals(results[0], batchResponse[0]));
            Assert.IsTrue(comparer.Equals(results[1], batchResponse[1]));
        }
        public async Task BatchCustomSerializerUsedForPatchAsync()
        {
            CosmosClientOptions clientOptions = new CosmosClientOptions()
            {
                Serializer = new CosmosJsonDotNetSerializer(
                    new JsonSerializerSettings()
                {
                    DateFormatString = "yyyy--MM--dd hh:mm"
                })
            };

            CosmosClient customSerializationClient    = TestCommon.CreateCosmosClient(clientOptions);
            Container    customSerializationContainer = customSerializationClient.GetContainer(BatchTestBase.Database.Id, BatchTestBase.JsonContainer.Id);

            TestDoc testDoc = BatchTestBase.PopulateTestDoc(this.PartitionKey1);

            DateTime patchDate = new DateTime(2020, 07, 01, 01, 02, 03);
            List <PatchOperation> patchOperations = new List <PatchOperation>()
            {
                PatchOperation.CreateAddOperation("/date", patchDate)
            };

            BatchCore batch = (BatchCore) new BatchCore((ContainerInlineCore)customSerializationContainer, BatchTestBase.GetPartitionKey(this.PartitionKey1))
                              .CreateItem(testDoc);

            batch = (BatchCore)batch.PatchItem(testDoc.Id, patchOperations);

            TransactionalBatchResponse batchResponse = await batch.ExecuteAsync();

            BatchSinglePartitionKeyTests.VerifyBatchProcessed(batchResponse, numberOfOperations: 2);

            Assert.AreEqual(HttpStatusCode.Created, batchResponse[0].StatusCode);
            Assert.AreEqual(HttpStatusCode.OK, batchResponse[1].StatusCode);

            JsonSerializerSettings jsonSettings = new JsonSerializerSettings();

            jsonSettings.DateFormatString = "yyyy--MM--dd hh:mm";
            string dateJson = JsonConvert.SerializeObject(patchDate, jsonSettings);

            // regular container
            ItemResponse <dynamic> response = await BatchTestBase.JsonContainer.ReadItemAsync <dynamic>(
                testDoc.Id,
                BatchTestBase.GetPartitionKey(this.PartitionKey1));

            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
            Assert.IsNotNull(response.Resource);
            Assert.IsTrue(dateJson.Contains(response.Resource["date"].ToString()));
        }
        public async Task BatchWithTooManyOperationsAsync()
        {
            Container container      = BatchTestBase.JsonContainer;
            const int operationCount = Constants.MaxOperationsInDirectModeBatchRequest + 1;

            TransactionalBatch batch = new BatchCore((ContainerCore)container, new Cosmos.PartitionKey(this.PartitionKey1));

            for (int i = 0; i < operationCount; i++)
            {
                batch.ReadItem("someId");
            }

            TransactionalBatchResponse batchResponse = await batch.ExecuteAsync();

            Assert.AreEqual(HttpStatusCode.BadRequest, batchResponse.StatusCode);
        }
        public async Task DiagnosticsAreSetThroughResponseAsync()
        {
            List <TransactionalBatchOperationResult> results = new List <TransactionalBatchOperationResult>();

            ItemBatchOperation[] arrayOperations = new ItemBatchOperation[1];

            ItemBatchOperation operation = new ItemBatchOperation(OperationType.AddComputeGatewayRequestCharges, 0, "0");

            results.Add(
                new TransactionalBatchOperationResult(HttpStatusCode.OK)
            {
                ResourceStream = new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true),
                ETag           = operation.Id
            });

            arrayOperations[0] = operation;

            MemoryStream responseContent = await new BatchResponsePayloadWriter(results).GeneratePayloadAsync();

            SinglePartitionKeyServerBatchRequest batchRequest = await SinglePartitionKeyServerBatchRequest.CreateAsync(
                partitionKey : null,
                operations : new ArraySegment <ItemBatchOperation>(arrayOperations),
                serializerCore : MockCosmosUtil.Serializer,
                cancellationToken : default(CancellationToken));

            CosmosDiagnostics diagnostics = new PointOperationStatistics(
                activityId: Guid.NewGuid().ToString(),
                statusCode: HttpStatusCode.OK,
                subStatusCode: SubStatusCodes.Unknown,
                requestCharge: 0,
                errorMessage: string.Empty,
                method: HttpMethod.Get,
                requestUri: new Uri("http://localhost"),
                requestSessionToken: null,
                responseSessionToken: null,
                clientSideRequestStatistics: new CosmosClientSideRequestStatistics());

            TransactionalBatchResponse batchresponse = await TransactionalBatchResponse.FromResponseMessageAsync(
                new ResponseMessage(HttpStatusCode.OK) { Content = responseContent, Diagnostics = diagnostics },
                batchRequest,
                MockCosmosUtil.Serializer);

            PartitionKeyRangeBatchResponse response = new PartitionKeyRangeBatchResponse(arrayOperations.Length, batchresponse, MockCosmosUtil.Serializer);

            Assert.AreEqual(diagnostics, response.Diagnostics);
        }
示例#10
0
        public CosmosBatchWriterTests()
        {
            expectedMetadata  = new Fixture().Create <StreamMetadata>();
            expectedETag      = new Fixture().Create <string>();
            operationResponse = Substitute.For <TransactionalBatchOperationResult <StreamMetadata> >();
            operationResponse
            .Resource
            .Returns(expectedMetadata);
            operationResponse
            .ETag
            .Returns(expectedETag);

            expectedTransactionResponse = Substitute.For <TransactionalBatchResponse>();
            expectedTransactionResponse
            .IsSuccessStatusCode
            .Returns(returnThis: true);
            expectedTransactionResponse
            .GetOperationResultAtIndex <StreamMetadata>(default)
        private async Task <bool> ConstainsSplitIsTrueInternal(HttpStatusCode statusCode, SubStatusCodes subStatusCode)
        {
            List <TransactionalBatchOperationResult> results = new List <TransactionalBatchOperationResult>();

            ItemBatchOperation[] arrayOperations = new ItemBatchOperation[1];

            ItemBatchOperation operation = new ItemBatchOperation(OperationType.Read, 0, Cosmos.PartitionKey.Null, "0");

            results.Add(
                new TransactionalBatchOperationResult(HttpStatusCode.OK)
            {
                ResourceStream = new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true),
                ETag           = operation.Id
            });

            arrayOperations[0] = operation;

            MemoryStream responseContent = await new BatchResponsePayloadWriter(results).GeneratePayloadAsync();

            SinglePartitionKeyServerBatchRequest batchRequest = await SinglePartitionKeyServerBatchRequest.CreateAsync(
                partitionKey : null,
                operations : new ArraySegment <ItemBatchOperation>(arrayOperations),
                serializerCore : MockCosmosUtil.Serializer,
                cancellationToken : default(CancellationToken));

            ResponseMessage response = new ResponseMessage(statusCode)
            {
                Content = responseContent
            };

            response.Headers.SubStatusCode = subStatusCode;

            TransactionalBatchResponse batchresponse = await TransactionalBatchResponse.FromResponseMessageAsync(
                response,
                batchRequest,
                MockCosmosUtil.Serializer,
                true,
                false,
                CancellationToken.None);

            PartitionKeyRangeBatchExecutionResult result = new PartitionKeyRangeBatchExecutionResult("0", arrayOperations, batchresponse);

            return(result.IsSplit());
        }
示例#12
0
        private async Task AddItemsToContainerAsync()
        {
            try
            {
                /* Classic Insertion
                 * foreach (var shop in CreateShopList())
                 * {
                 *  var resp = await container.CreateItemAsync<Shop>(shop);
                 *  Console.WriteLine($"Created {shop.Name} Client Time: {resp.Diagnostics.GetClientElapsedTime().TotalSeconds} \n");
                 * }
                 */

                // ACID - Limitations (Transaction only scopes a single partition!)
                // - Payload cannot exceed 2MB as per the Azure Cosmos DB request size limit
                // - Maximum execution time is 5 seconds
                // - Limit of 100 operations per TransactionalBatch to make sure the performance is as expected and within SLAs.
                using (TransactionalBatchResponse batchResponse =
                           await InsertAllDocuments(
                               container.CreateTransactionalBatch(new PartitionKey("Austria")))
                           .ExecuteAsync())
                {
                    if (!batchResponse.IsSuccessStatusCode)
                    {
                        Console.WriteLine("Batch execution failed!\n");
                        // Handle and log exception
                    }
                    else
                    {
                        // Look up interested results - eg. via typed access on operation results
                        Console.WriteLine($"Transactionbatch completed with a charge of {batchResponse.RequestCharge} RUs.");
                        for (int i = 0; i < batchResponse.Count; i++)
                        {
                            TransactionalBatchOperationResult <Shop> opResult = batchResponse.GetOperationResultAtIndex <Shop>(i);
                            Console.WriteLine($"Shop {opResult.Resource.Name} created with {opResult.ETag} ETAG.");
                        }
                    }
                }
            }
            catch (CosmosException ex) when(ex.StatusCode == HttpStatusCode.Conflict)
            {
                Console.WriteLine("Items already existing\n");
            }
        }
        private static void EnsureSuccess(TransactionalBatchResponse response, StreamMetadata metadata)
        {
            if (!response.IsSuccessStatusCode)
            {
                if (response.StatusCode == HttpStatusCode.TooManyRequests)
                {
                    throw new CosmosException(
                              response.ErrorMessage,
                              response.StatusCode,
                              0,
                              response.ActivityId,
                              response.RequestCharge);
                }

                throw new StreamWriteConflictException(
                          metadata.StreamId,
                          metadata.Version);
            }
        }
示例#14
0
        private void ValidateResponse(
            TransactionalBatchResponse response,
            int noResponseItemCount)
        {
            Assert.IsNotNull(response);
            Assert.IsTrue(response.IsSuccessStatusCode);
            Assert.IsTrue(response.RequestCharge > 0);
            Assert.IsNotNull(response.ActivityId);

            int count = 0;

            foreach (TransactionalBatchOperationResult itemResponse in response)
            {
                count++;
                if (count == noResponseItemCount)
                {
                    break;
                }

                Assert.IsTrue(itemResponse.IsSuccessStatusCode);
                Assert.IsTrue(itemResponse.StatusCode == HttpStatusCode.OK || itemResponse.StatusCode == HttpStatusCode.Created);
                Assert.IsNull(itemResponse.ResourceStream);
                Assert.IsTrue(itemResponse.RequestCharge > 0);
            }

            for (int i = 0; i < response.Count && i < noResponseItemCount; i++)
            {
                TransactionalBatchOperationResult <ToDoActivity> itemResponse = response.GetOperationResultAtIndex <ToDoActivity>(i);
                Assert.IsNull(itemResponse.Resource);
                Assert.IsNull(itemResponse.ResourceStream);
                Assert.IsTrue(response.RequestCharge > 0);
                Assert.IsNotNull(response.ActivityId);
            }

            for (int i = noResponseItemCount; i < response.Count; i++)
            {
                TransactionalBatchOperationResult <ToDoActivity> itemResponse = response.GetOperationResultAtIndex <ToDoActivity>(i);
                Assert.IsNotNull(itemResponse.Resource);
                Assert.IsNotNull(itemResponse.ResourceStream);
                Assert.IsTrue(response.RequestCharge > 0);
                Assert.IsNotNull(response.ActivityId);
            }
        }
        public async Task BatchLargerThanServerRequestAsync()
        {
            Container container = BatchTestBase.JsonContainer;

            const int operationCount = 20;
            int       appxDocSize    = Constants.MaxDirectModeBatchRequestBodySizeInBytes / operationCount;

            // Increase the doc size by a bit so all docs won't fit in one server request.
            appxDocSize = (int)(appxDocSize * 1.05);
            TransactionalBatch batch = new BatchCore((ContainerCore)container, new Cosmos.PartitionKey(this.PartitionKey1));

            for (int i = 0; i < operationCount; i++)
            {
                TestDoc doc = BatchTestBase.PopulateTestDoc(this.PartitionKey1, minDesiredSize: appxDocSize);
                batch.CreateItem(doc);
            }

            TransactionalBatchResponse batchResponse = await batch.ExecuteAsync();

            Assert.AreEqual(HttpStatusCode.RequestEntityTooLarge, batchResponse.StatusCode);
        }
        public async Task StatusCodesAreSetThroughResponseAsync()
        {
            List <TransactionalBatchOperationResult> results = new List <TransactionalBatchOperationResult>();

            ItemBatchOperation[] arrayOperations = new ItemBatchOperation[1];

            ItemBatchOperation operation = new ItemBatchOperation(OperationType.Read, 0, Cosmos.PartitionKey.Null, "0");

            results.Add(
                new TransactionalBatchOperationResult(HttpStatusCode.OK)
            {
                ResourceStream = new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true),
                ETag           = operation.Id
            });

            arrayOperations[0] = operation;

            MemoryStream responseContent = await new BatchResponsePayloadWriter(results).GeneratePayloadAsync();

            SinglePartitionKeyServerBatchRequest batchRequest = await SinglePartitionKeyServerBatchRequest.CreateAsync(
                partitionKey : null,
                operations : new ArraySegment <ItemBatchOperation>(arrayOperations),
                serializerCore : MockCosmosUtil.Serializer,
                cancellationToken : default(CancellationToken));

            TransactionalBatchResponse batchresponse = await TransactionalBatchResponse.FromResponseMessageAsync(
                new ResponseMessage(HttpStatusCode.OK) { Content = responseContent },
                batchRequest,
                MockCosmosUtil.Serializer,
                true,
                false,
                CancellationToken.None);

            PartitionKeyRangeBatchResponse response = new PartitionKeyRangeBatchResponse(
                arrayOperations.Length,
                batchresponse,
                MockCosmosUtil.Serializer);

            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
        }
示例#17
0
        public async Task NoContentResponseTransactionBatchTest()
        {
            string             pkId  = "TestBatchId";
            TransactionalBatch batch = this.containerWithoutFlag.CreateTransactionalBatch(new PartitionKey(pkId));

            int noResponseItemCount = 100;

            for (int i = 0; i < noResponseItemCount; i++)
            {
                ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkId);
                batch.CreateItem <ToDoActivity>(item);
            }

            TransactionalBatchResponse response = await batch.ExecuteAsync();

            Assert.AreEqual(response.Count, 100);
            foreach (TransactionalBatchOperationResult itemResponse in response)
            {
                Assert.IsTrue(itemResponse.StatusCode == HttpStatusCode.Created);
                Assert.IsNull(itemResponse.ResourceStream);
            }
        }
        private static void VerifyBatchProcessed(TransactionalBatchResponse batchResponse, int numberOfOperations, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
        {
            Assert.IsNotNull(batchResponse);
            Assert.AreEqual(
                expectedStatusCode,
                batchResponse.StatusCode,
                string.Format("Batch server response had StatusCode {0} instead of {1} expected and had ErrorMessage {2}",
                              batchResponse.StatusCode,
                              expectedStatusCode,
                              batchResponse.ErrorMessage));

            Assert.AreEqual(numberOfOperations, batchResponse.Count);

            Assert.IsTrue(batchResponse.RequestCharge > 0);

            // Allow a delta since we round both the total charge and the individual operation
            // charges to 2 decimal places.
            Assert.AreEqual(
                batchResponse.RequestCharge,
                batchResponse.Sum(result => result.RequestCharge),
                0.1);
        }
        public async Task BatchReadsOnlyAsync()
        {
            Container container = BatchTestBase.JsonContainer;

            await this.CreateJsonTestDocsAsync(container);

            TransactionalBatchResponse batchResponse = await new BatchCore((ContainerCore)container, BatchTestBase.GetPartitionKey(this.PartitionKey1))
                                                       .ReadItem(this.TestDocPk1ExistingA.Id)
                                                       .ReadItem(this.TestDocPk1ExistingB.Id)
                                                       .ReadItem(this.TestDocPk1ExistingC.Id)
                                                       .ExecuteAsync();

            BatchSinglePartitionKeyTests.VerifyBatchProcessed(batchResponse, numberOfOperations: 3);

            Assert.AreEqual(HttpStatusCode.OK, batchResponse[0].StatusCode);
            Assert.AreEqual(HttpStatusCode.OK, batchResponse[1].StatusCode);
            Assert.AreEqual(HttpStatusCode.OK, batchResponse[2].StatusCode);

            Assert.AreEqual(this.TestDocPk1ExistingA, batchResponse.GetOperationResultAtIndex <TestDoc>(0).Resource);
            Assert.AreEqual(this.TestDocPk1ExistingB, batchResponse.GetOperationResultAtIndex <TestDoc>(1).Resource);
            Assert.AreEqual(this.TestDocPk1ExistingC, batchResponse.GetOperationResultAtIndex <TestDoc>(2).Resource);
        }
        public async Task BatchCreateAndPatchAsync()
        {
            TestDoc testDoc = BatchTestBase.PopulateTestDoc(this.PartitionKey1);
            List <PatchOperation> patchOperations = new List <PatchOperation>()
            {
                PatchOperation.CreateReplaceOperation("/Cost", testDoc.Cost + 1)
            };

            BatchCore batch = (BatchCore) new BatchCore((ContainerInlineCore)BatchTestBase.JsonContainer, BatchTestBase.GetPartitionKey(this.PartitionKey1))
                              .CreateItem(testDoc);

            batch = (BatchCore)batch.PatchItem(testDoc.Id, patchOperations);

            TransactionalBatchResponse batchResponse = await batch.ExecuteAsync();

            BatchSinglePartitionKeyTests.VerifyBatchProcessed(batchResponse, numberOfOperations: 2);

            Assert.AreEqual(HttpStatusCode.Created, batchResponse[0].StatusCode);
            Assert.AreEqual(HttpStatusCode.OK, batchResponse[1].StatusCode);
            testDoc.Cost = testDoc.Cost + 1;
            await BatchTestBase.VerifyByReadAsync(BatchTestBase.JsonContainer, testDoc, isStream : false, isSchematized : false, useEpk : false);
        }
        public async Task BatchOperationDiagnostic()
        {
            string             pkValue = "DiagnosticTestPk";
            TransactionalBatch batch   = this.Container.CreateTransactionalBatch(new PartitionKey(pkValue));

            List <ToDoActivity> createItems = new List <ToDoActivity>();

            for (int i = 0; i < 50; i++)
            {
                ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkValue);
                createItems.Add(item);
                batch.CreateItem <ToDoActivity>(item);
            }

            for (int i = 0; i < 20; i++)
            {
                batch.ReadItem(createItems[i].id);
            }

            TransactionalBatchResponse response = await batch.ExecuteAsync();

            Assert.IsNotNull(response);
            CosmosDiagnosticsTests.VerifyPointDiagnostics(response.Diagnostics);
        }
示例#22
0
        private static async Task DeleteHugeMountainBikeOrder()
        {
            Database  database   = client.GetDatabase("database-v4");
            Container container  = database.GetContainer("customer");
            Container container2 = database.GetContainer("salesByCategory");

            string customerId = "FFD0DD37-1F0E-4E2E-8FAC-EAF45B0E9447";
            string orderId    = "f571e271-c98e-44d1-bb6c-47ad353c4ebc";
            string categoryId = "56400CF3-446D-4C3F-B9B2-68286DA3BB99";

            ItemResponse <CustomerV4> response = await container.ReadItemAsync <CustomerV4>(
                id : customerId,
                partitionKey : new PartitionKey(customerId)
                );

            CustomerV4 customer = response.Resource;

            //Decrement the salesOrderTotal property
            customer.salesOrderCount--;

            //Submit both as a transactional batch
            TransactionalBatchResponse txBatchResponse = await container.CreateTransactionalBatch(
                new PartitionKey(customerId))
                                                         .DeleteItem(orderId)
                                                         .ReplaceItem <CustomerV4>(customer.id, customer)
                                                         .ExecuteAsync();

            //revert category sales to original value (normally this would be done with a soft delete or some other means)
            ItemResponse <CategorySales> response1 = await container2.ReadItemAsync <CategorySales>(categoryId, new PartitionKey(categoryId));

            CategorySales categorySales = response1.Resource;

            categorySales.totalSales = 11788915;

            await container2.ReplaceItemAsync(categorySales, categoryId, new PartitionKey(categoryId));
        }
        public async Task BatchJsonServerResponseAsync()
        {
            TestHandler testHandler = new TestHandler((request, cancellationToken) =>
            {
                HttpStatusCode serverStatusCode = HttpStatusCode.Gone;
                Stream serverContent            = new MemoryStream(Encoding.UTF8.GetBytes("{ \"random\": 1 }"));

                ResponseMessage responseMessage = new ResponseMessage(serverStatusCode, requestMessage: null, errorMessage: null)
                {
                    Content = serverContent
                };

                return(Task.FromResult(responseMessage));
            });

            Container container = BatchUnitTests.GetContainer(testHandler);

            TransactionalBatchResponse batchResponse = await new BatchCore((ContainerInternal)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1))
                                                       .ReadItem("id1")
                                                       .ReadItem("id2")
                                                       .ExecuteAsync();

            Assert.AreEqual(HttpStatusCode.Gone, batchResponse.StatusCode);
        }
示例#24
0
        public async ValueTask DeleteAsBatchAsync(
            IEnumerable <TItem> items,
            CancellationToken cancellationToken = default)
        {
            List <TItem> list = items.ToList();

            string partitionKey = GetPartitionKeyValue(list);

            Container container = await _containerProvider.GetContainerAsync();

            TransactionalBatch batch = container.CreateTransactionalBatch(new PartitionKey(partitionKey));

            foreach (TItem item in list)
            {
                batch.DeleteItem(item.Id);
            }

            using TransactionalBatchResponse response = await batch.ExecuteAsync(cancellationToken);

            if (!response.IsSuccessStatusCode)
            {
                throw new BatchOperationException <TItem>(response);
            }
        }
示例#25
0
        private static async Task RunDemo()
        {
            ToDoActivity activeActivity = new ToDoActivity()
            {
                Id           = Guid.NewGuid().ToString(),
                ActivityId   = Guid.NewGuid().ToString(),
                PartitionKey = "myPartitionKey",
                Status       = "Active"
            };

            ToDoActivity completedActivity = new ToDoActivity()
            {
                Id           = Guid.NewGuid().ToString(),
                ActivityId   = Guid.NewGuid().ToString(),
                PartitionKey = "myPartitionKey",
                Status       = "Completed"
            };

            // Create items that use System.Text.Json serialization attributes
            ItemResponse <ToDoActivity> createActiveActivity = await container.CreateItemAsync(activeActivity, new PartitionKey(activeActivity.PartitionKey));

            Console.WriteLine($"Created Active activity with id {createActiveActivity.Resource.Id} that cost {createActiveActivity.RequestCharge}");

            ItemResponse <ToDoActivity> createCompletedActivity = await container.CreateItemAsync(completedActivity, new PartitionKey(completedActivity.PartitionKey));

            Console.WriteLine($"Created Completed activity with id {createCompletedActivity.Resource.Id} that cost {createCompletedActivity.RequestCharge}");

            // Execute queries materializing responses using System.Text.Json
            using FeedIterator <ToDoActivity> iterator = container.GetItemQueryIterator <ToDoActivity>("select * from c where c.status = 'Completed'");
            while (iterator.HasMoreResults)
            {
                FeedResponse <ToDoActivity> queryResponse = await iterator.ReadNextAsync();

                Console.WriteLine($"Obtained {queryResponse.Count} results on query for {queryResponse.RequestCharge}");
            }

            // Read items materializing responses using System.Text.Json
            ItemResponse <ToDoActivity> readActiveActivity = await container.ReadItemAsync <ToDoActivity>(activeActivity.Id, new PartitionKey(completedActivity.PartitionKey));

            Console.WriteLine($"Read Active activity with id {activeActivity.Id} that cost {readActiveActivity.RequestCharge}");

            // Using TransactionalBatch to atomically create multiple items as a single transaction
            string       batchPartitionKey = "myPartitionKey";
            ToDoActivity newActivity       = new ToDoActivity()
            {
                Id           = Guid.NewGuid().ToString(),
                ActivityId   = Guid.NewGuid().ToString(),
                PartitionKey = batchPartitionKey,
                Status       = "Active"
            };

            ToDoActivity anotherNewActivity = new ToDoActivity()
            {
                Id           = Guid.NewGuid().ToString(),
                ActivityId   = Guid.NewGuid().ToString(),
                PartitionKey = batchPartitionKey,
                Status       = "Active"
            };

            TransactionalBatchResponse batchResponse = await container.CreateTransactionalBatch(new PartitionKey(batchPartitionKey))
                                                       .CreateItem(newActivity)
                                                       .CreateItem(anotherNewActivity)
                                                       .ExecuteAsync();

            if (batchResponse.IsSuccessStatusCode)
            {
                Console.WriteLine($"Completed transactional batch that cost {batchResponse.RequestCharge}");
            }
        }
示例#26
0
 private static void LogFailure(TransactionalBatchResponse batchResponse)
 {
     Console.WriteLine("Unexpected error in executing batch requests in the sample. Please retry the sample.");
     Console.WriteLine("Timestamp: {0}\nDiagnostics: {1}", DateTime.UtcNow, batchResponse.Diagnostics.ToString());
 }
        public async Task EncryptionTransactionBatchCrud()
        {
            string partitionKey = "thePK";
            string dek1         = EncryptionTests.dekId;
            string dek2         = "dek2Forbatch";
            await EncryptionTests.CreateDekAsync(EncryptionTests.dekProvider, dek2);

            TestDoc doc1ToCreate = TestDoc.Create(partitionKey);
            TestDoc doc2ToCreate = TestDoc.Create(partitionKey);
            TestDoc doc3ToCreate = TestDoc.Create(partitionKey);

            ItemResponse <TestDoc> doc1ToReplaceCreateResponse = await EncryptionTests.CreateItemAsync(EncryptionTests.itemContainerCore, dek1, TestDoc.PathsToEncrypt, partitionKey);

            TestDoc doc1ToReplace = doc1ToReplaceCreateResponse.Resource;

            doc1ToReplace.NonSensitive = Guid.NewGuid().ToString();
            doc1ToReplace.Sensitive    = Guid.NewGuid().ToString();

            TestDoc doc2ToReplace = await EncryptionTests.CreateItemAsync(EncryptionTests.itemContainerCore, dek2, TestDoc.PathsToEncrypt, partitionKey);

            doc2ToReplace.NonSensitive = Guid.NewGuid().ToString();
            doc2ToReplace.Sensitive    = Guid.NewGuid().ToString();

            TestDoc doc1ToUpsert = await EncryptionTests.CreateItemAsync(EncryptionTests.itemContainerCore, dek2, TestDoc.PathsToEncrypt, partitionKey);

            doc1ToUpsert.NonSensitive = Guid.NewGuid().ToString();
            doc1ToUpsert.Sensitive    = Guid.NewGuid().ToString();

            TestDoc doc2ToUpsert = await EncryptionTests.CreateItemAsync(EncryptionTests.itemContainerCore, dek1, TestDoc.PathsToEncrypt, partitionKey);

            doc2ToUpsert.NonSensitive = Guid.NewGuid().ToString();
            doc2ToUpsert.Sensitive    = Guid.NewGuid().ToString();

            TestDoc docToDelete = await EncryptionTests.CreateItemAsync(EncryptionTests.itemContainerCore, dek1, TestDoc.PathsToEncrypt, partitionKey);

            TransactionalBatchResponse batchResponse = await EncryptionTests.itemContainer.CreateTransactionalBatch(new Cosmos.PartitionKey(partitionKey))
                                                       .CreateItem(doc1ToCreate, EncryptionTests.GetBatchItemRequestOptions(EncryptionTests.itemContainerCore, dek1, TestDoc.PathsToEncrypt))
                                                       .CreateItemStream(doc2ToCreate.ToStream(), EncryptionTests.GetBatchItemRequestOptions(EncryptionTests.itemContainerCore, dek2, TestDoc.PathsToEncrypt))
                                                       .ReplaceItem(doc1ToReplace.Id, doc1ToReplace, EncryptionTests.GetBatchItemRequestOptions(EncryptionTests.itemContainerCore, dek2, TestDoc.PathsToEncrypt, doc1ToReplaceCreateResponse.ETag))
                                                       .CreateItem(doc3ToCreate)
                                                       .ReplaceItemStream(doc2ToReplace.Id, doc2ToReplace.ToStream(), EncryptionTests.GetBatchItemRequestOptions(EncryptionTests.itemContainerCore, dek2, TestDoc.PathsToEncrypt))
                                                       .UpsertItem(doc1ToUpsert, EncryptionTests.GetBatchItemRequestOptions(EncryptionTests.itemContainerCore, dek1, TestDoc.PathsToEncrypt))
                                                       .DeleteItem(docToDelete.Id)
                                                       .UpsertItemStream(doc2ToUpsert.ToStream(), EncryptionTests.GetBatchItemRequestOptions(EncryptionTests.itemContainerCore, dek2, TestDoc.PathsToEncrypt))
                                                       .ExecuteAsync();

            Assert.AreEqual(HttpStatusCode.OK, batchResponse.StatusCode);

            await EncryptionTests.VerifyItemByReadAsync(EncryptionTests.itemContainerCore, doc1ToCreate);

            await EncryptionTests.VerifyItemByReadAsync(EncryptionTests.itemContainerCore, doc2ToCreate);

            await EncryptionTests.VerifyItemByReadAsync(EncryptionTests.itemContainerCore, doc3ToCreate);

            await EncryptionTests.VerifyItemByReadAsync(EncryptionTests.itemContainerCore, doc1ToReplace);

            await EncryptionTests.VerifyItemByReadAsync(EncryptionTests.itemContainerCore, doc2ToReplace);

            await EncryptionTests.VerifyItemByReadAsync(EncryptionTests.itemContainerCore, doc1ToUpsert);

            await EncryptionTests.VerifyItemByReadAsync(EncryptionTests.itemContainerCore, doc2ToUpsert);

            ResponseMessage readResponseMessage = await EncryptionTests.itemContainer.ReadItemStreamAsync(docToDelete.Id, new PartitionKey(docToDelete.PK));

            Assert.AreEqual(HttpStatusCode.NotFound, readResponseMessage.StatusCode);
        }
        public async Task BatchCrudRequestAsync()
        {
            Random random = new Random();

            TestItem createItem = new TestItem("create");

            byte[] createStreamContent = new byte[20];
            random.NextBytes(createStreamContent);
            byte[] createStreamBinaryId = new byte[20];
            random.NextBytes(createStreamBinaryId);
            int createTtl = 45;
            TransactionalBatchItemRequestOptions createRequestOptions = new TransactionalBatchItemRequestOptions()
            {
                Properties = new Dictionary <string, object>()
                {
                    { WFConstants.BackendHeaders.BinaryId, createStreamBinaryId },
                    { WFConstants.BackendHeaders.TimeToLiveInSeconds, createTtl.ToString() },
                },
                IndexingDirective = Microsoft.Azure.Cosmos.IndexingDirective.Exclude
            };

            string readId = Guid.NewGuid().ToString();

            byte[] readStreamBinaryId = new byte[20];
            random.NextBytes(readStreamBinaryId);
            TransactionalBatchItemRequestOptions readRequestOptions = new TransactionalBatchItemRequestOptions()
            {
                Properties = new Dictionary <string, object>()
                {
                    { WFConstants.BackendHeaders.BinaryId, readStreamBinaryId }
                },
                IfNoneMatchEtag = "readCondition"
            };

            TestItem replaceItem = new TestItem("repl");

            byte[] replaceStreamContent = new byte[20];
            random.NextBytes(replaceStreamContent);
            const string replaceStreamId = "replStream";

            byte[] replaceStreamBinaryId = new byte[20];
            random.NextBytes(replaceStreamBinaryId);
            TransactionalBatchItemRequestOptions replaceRequestOptions = new TransactionalBatchItemRequestOptions()
            {
                Properties = new Dictionary <string, object>()
                {
                    { WFConstants.BackendHeaders.BinaryId, replaceStreamBinaryId }
                },
                IfMatchEtag       = "replCondition",
                IndexingDirective = Microsoft.Azure.Cosmos.IndexingDirective.Exclude
            };

            TestItem upsertItem = new TestItem("upsert");

            byte[] upsertStreamContent = new byte[20];
            random.NextBytes(upsertStreamContent);
            byte[] upsertStreamBinaryId = new byte[20];
            random.NextBytes(upsertStreamBinaryId);
            TransactionalBatchItemRequestOptions upsertRequestOptions = new TransactionalBatchItemRequestOptions()
            {
                Properties = new Dictionary <string, object>()
                {
                    { WFConstants.BackendHeaders.BinaryId, upsertStreamBinaryId }
                },
                IfMatchEtag       = "upsertCondition",
                IndexingDirective = Microsoft.Azure.Cosmos.IndexingDirective.Exclude
            };

            string deleteId = Guid.NewGuid().ToString();

            byte[] deleteStreamBinaryId = new byte[20];
            random.NextBytes(deleteStreamBinaryId);
            TransactionalBatchItemRequestOptions deleteRequestOptions = new TransactionalBatchItemRequestOptions()
            {
                Properties = new Dictionary <string, object>()
                {
                    { WFConstants.BackendHeaders.BinaryId, deleteStreamBinaryId }
                },
                IfNoneMatchEtag = "delCondition"
            };

            CosmosJsonDotNetSerializer jsonSerializer = new CosmosJsonDotNetSerializer();
            BatchTestHandler           testHandler    = new BatchTestHandler((request, operations) =>
            {
                Assert.AreEqual(new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1).ToString(), request.Headers.PartitionKey);
                Assert.AreEqual(bool.TrueString, request.Headers[HttpConstants.HttpHeaders.IsBatchAtomic]);
                Assert.AreEqual(bool.TrueString, request.Headers[HttpConstants.HttpHeaders.IsBatchOrdered]);
                Assert.IsFalse(request.Headers.TryGetValue(HttpConstants.HttpHeaders.ShouldBatchContinueOnError, out string unused));

                Assert.AreEqual(16, operations.Count);

                int operationIndex = 0;

                // run the loop twice, once for operations without item request options, and one for with item request options
                for (int loopCount = 0; loopCount < 2; loopCount++)
                {
                    bool hasItemRequestOptions = loopCount == 1;

                    ItemBatchOperation operation = operations[operationIndex++];
                    Assert.AreEqual(OperationType.Create, operation.OperationType);
                    Assert.IsNull(operation.Id);
                    Assert.AreEqual(createItem, BatchUnitTests.Deserialize(operation.ResourceBody, jsonSerializer));
                    BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? createRequestOptions : null, operation.RequestOptions);

                    operation = operations[operationIndex++];
                    Assert.AreEqual(OperationType.Read, operation.OperationType);
                    Assert.AreEqual(readId, operation.Id);
                    BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? readRequestOptions : null, operation.RequestOptions);

                    operation = operations[operationIndex++];
                    Assert.AreEqual(OperationType.Replace, operation.OperationType);
                    Assert.AreEqual(replaceItem.Id, operation.Id);
                    Assert.AreEqual(replaceItem, BatchUnitTests.Deserialize(operation.ResourceBody, jsonSerializer));
                    BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? replaceRequestOptions : null, operation.RequestOptions);

                    operation = operations[operationIndex++];
                    Assert.AreEqual(OperationType.Upsert, operation.OperationType);
                    Assert.IsNull(operation.Id);
                    Assert.AreEqual(upsertItem, BatchUnitTests.Deserialize(operation.ResourceBody, jsonSerializer));
                    BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? upsertRequestOptions : null, operation.RequestOptions);

                    operation = operations[operationIndex++];
                    Assert.AreEqual(OperationType.Delete, operation.OperationType);
                    Assert.AreEqual(deleteId, operation.Id);
                    BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? deleteRequestOptions : null, operation.RequestOptions);

                    operation = operations[operationIndex++];
                    Assert.AreEqual(OperationType.Create, operation.OperationType);
                    Assert.IsNull(operation.Id);
                    Assert.IsTrue(operation.ResourceBody.Span.SequenceEqual(createStreamContent));
                    BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? createRequestOptions : null, operation.RequestOptions);

                    operation = operations[operationIndex++];
                    Assert.AreEqual(OperationType.Replace, operation.OperationType);
                    Assert.AreEqual(replaceStreamId, operation.Id);
                    Assert.IsTrue(operation.ResourceBody.Span.SequenceEqual(replaceStreamContent));
                    BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? replaceRequestOptions : null, operation.RequestOptions);

                    operation = operations[operationIndex++];
                    Assert.AreEqual(OperationType.Upsert, operation.OperationType);
                    Assert.IsNull(operation.Id);
                    Assert.IsTrue(operation.ResourceBody.Span.SequenceEqual(upsertStreamContent));
                    BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? upsertRequestOptions : null, operation.RequestOptions);
                }

                return(Task.FromResult(new ResponseMessage(HttpStatusCode.OK)));
            });

            Container container = BatchUnitTests.GetContainer(testHandler);

            TransactionalBatchResponse batchResponse = await new BatchCore((ContainerInternal)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1))
                                                       .CreateItem(createItem)
                                                       .ReadItem(readId)
                                                       .ReplaceItem(replaceItem.Id, replaceItem)
                                                       .UpsertItem(upsertItem)
                                                       .DeleteItem(deleteId)

                                                       // stream
                                                       .CreateItemStream(new MemoryStream(createStreamContent))
                                                       .ReplaceItemStream(replaceStreamId, new MemoryStream(replaceStreamContent))
                                                       .UpsertItemStream(new MemoryStream(upsertStreamContent))

                                                       // regular with options
                                                       .CreateItem(createItem, createRequestOptions)
                                                       .ReadItem(readId, readRequestOptions)
                                                       .ReplaceItem(replaceItem.Id, replaceItem, replaceRequestOptions)
                                                       .UpsertItem(upsertItem, upsertRequestOptions)
                                                       .DeleteItem(deleteId, deleteRequestOptions)

                                                       // stream with options
                                                       .CreateItemStream(new MemoryStream(createStreamContent), createRequestOptions)
                                                       .ReplaceItemStream(replaceStreamId, new MemoryStream(replaceStreamContent), replaceRequestOptions)
                                                       .UpsertItemStream(new MemoryStream(upsertStreamContent), upsertRequestOptions)
                                                       .ExecuteAsync();
        }
示例#29
0
        public static async Task CreateNewOrderAndUpdateCustomerOrderTotal()
        {
            Database  database  = client.GetDatabase("database-v4");
            Container container = database.GetContainer("customer");

            //Get the customer
            string customerId = "FFD0DD37-1F0E-4E2E-8FAC-EAF45B0E9447";
            ItemResponse <CustomerV4> response = await container.ReadItemAsync <CustomerV4>(
                id : customerId,
                partitionKey : new PartitionKey(customerId)
                );

            CustomerV4 customer = response.Resource;

            //Increment the salesOrderTotal property
            customer.salesOrderCount++;

            //Create a new order
            string orderId = "5350ce31-ea50-4df9-9a48-faff97675ac5"; //Normally would use Guid.NewGuid().ToString()

            SalesOrder salesOrder = new SalesOrder
            {
                id         = orderId,
                type       = "salesOrder",
                customerId = customer.id,
                orderDate  = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"),
                shipDate   = "",
                details    = new List <SalesOrderDetails>
                {
                    new SalesOrderDetails
                    {
                        sku      = "FR-M94B-38",
                        name     = "HL Mountain Frame - Black, 38",
                        price    = 1349.6,
                        quantity = 1
                    },
                    new SalesOrderDetails
                    {
                        sku      = "SO-R809-M",
                        name     = "Racing Socks, M",
                        price    = 8.99,
                        quantity = 2
                    }
                }
            };

            //Submit both as a transactional batch
            TransactionalBatchResponse txBatchResponse = await container.CreateTransactionalBatch(
                new PartitionKey(salesOrder.customerId))
                                                         .CreateItem <SalesOrder>(salesOrder)
                                                         .ReplaceItem <CustomerV4>(customer.id, customer)
                                                         .ExecuteAsync();

            if (txBatchResponse.IsSuccessStatusCode)
            {
                Console.WriteLine("Order created successfully");
            }

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
示例#30
0
        public async Task DiagnosticsAreSetThroughResponseAsync()
        {
            List <TransactionalBatchOperationResult> results = new List <TransactionalBatchOperationResult>();

            ItemBatchOperation[] arrayOperations = new ItemBatchOperation[1];

            ItemBatchOperation operation = new ItemBatchOperation(OperationType.Read, 0, Cosmos.PartitionKey.Null, "0");

            results.Add(
                new TransactionalBatchOperationResult(HttpStatusCode.OK)
            {
                ResourceStream = new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true),
                ETag           = operation.Id
            });

            arrayOperations[0] = operation;

            MemoryStream responseContent = await new BatchResponsePayloadWriter(results).GeneratePayloadAsync();

            SinglePartitionKeyServerBatchRequest batchRequest = await SinglePartitionKeyServerBatchRequest.CreateAsync(
                partitionKey : null,
                operations : new ArraySegment <ItemBatchOperation>(arrayOperations),
                serializerCore : MockCosmosUtil.Serializer,
                trace : NoOpTrace.Singleton,
                cancellationToken : default(CancellationToken));

            ResponseMessage responseMessage = new ResponseMessage(HttpStatusCode.OK)
            {
                Content = responseContent,
            };

            PointOperationStatisticsTraceDatum diagnostics = new PointOperationStatisticsTraceDatum(
                activityId: Guid.NewGuid().ToString(),
                statusCode: HttpStatusCode.OK,
                subStatusCode: SubStatusCodes.Unknown,
                responseTimeUtc: DateTime.UtcNow,
                requestCharge: 0,
                errorMessage: string.Empty,
                method: HttpMethod.Get,
                requestUri: "http://localhost",
                requestSessionToken: null,
                responseSessionToken: null);

            TransactionalBatchResponse batchresponse;

            using (responseMessage.Trace = Trace.GetRootTrace("test trace"))
            {
                responseMessage.Trace.AddDatum("Point Operation Statistics", diagnostics);

                batchresponse = await TransactionalBatchResponse.FromResponseMessageAsync(
                    responseMessage,
                    batchRequest,
                    MockCosmosUtil.Serializer,
                    true,
                    responseMessage.Trace,
                    CancellationToken.None);
            }

            PartitionKeyRangeBatchResponse response = new PartitionKeyRangeBatchResponse(arrayOperations.Length, batchresponse, MockCosmosUtil.Serializer);

            if (!(response.Diagnostics is CosmosTraceDiagnostics cosmosTraceDiagnostics))
            {
                Assert.Fail();
                throw new Exception();
            }

            Assert.AreEqual(diagnostics, cosmosTraceDiagnostics.Value.Data.Values.First());
        }