public EncryptionTransactionalBatchResponse( IReadOnlyList <TransactionalBatchOperationResult> results, TransactionalBatchResponse response, CosmosSerializer cosmosSerializer, CosmosDiagnostics diagnostics) { this.results = results; this.response = response; this.cosmosSerializer = cosmosSerializer; this.diagnostics = diagnostics; }
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); }
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);
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)); } }
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); }
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()); }
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); } }
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); }
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); }
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); }
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); } }
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}"); } }
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(); }
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(); }
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()); }