public async Task BatchItemETagAsync() { Container container = BatchTestBase.JsonContainer; await this.CreateJsonTestDocsAsync(container); { TestDoc testDocToCreate = BatchTestBase.PopulateTestDoc(this.PartitionKey1); TestDoc testDocToReplace = this.GetTestDocCopy(this.TestDocPk1ExistingA); testDocToReplace.Cost++; ItemResponse <TestDoc> readResponse = await BatchTestBase.JsonContainer.ReadItemAsync <TestDoc>( this.TestDocPk1ExistingA.Id, BatchTestBase.GetPartitionKey(this.PartitionKey1)); TransactionalBatchItemRequestOptions firstReplaceOptions = new TransactionalBatchItemRequestOptions() { IfMatchEtag = readResponse.ETag }; TransactionalBatchResponse batchResponse = await new BatchCore((ContainerCore)container, BatchTestBase.GetPartitionKey(this.PartitionKey1)) .CreateItem(testDocToCreate) .ReplaceItem(testDocToReplace.Id, testDocToReplace, requestOptions: firstReplaceOptions) .ExecuteAsync(); BatchSinglePartitionKeyTests.VerifyBatchProcessed(batchResponse, numberOfOperations: 2); Assert.AreEqual(HttpStatusCode.Created, batchResponse[0].StatusCode); Assert.AreEqual(HttpStatusCode.OK, batchResponse[1].StatusCode); await BatchTestBase.VerifyByReadAsync(container, testDocToCreate, eTag : batchResponse[0].ETag); await BatchTestBase.VerifyByReadAsync(container, testDocToReplace, eTag : batchResponse[1].ETag); } { TestDoc testDocToReplace = this.GetTestDocCopy(this.TestDocPk1ExistingB); testDocToReplace.Cost++; TransactionalBatchItemRequestOptions replaceOptions = new TransactionalBatchItemRequestOptions() { IfMatchEtag = BatchTestBase.Random.Next().ToString() }; TransactionalBatchResponse batchResponse = await new BatchCore((ContainerCore)container, BatchTestBase.GetPartitionKey(this.PartitionKey1)) .ReplaceItem(testDocToReplace.Id, testDocToReplace, requestOptions: replaceOptions) .ExecuteAsync(); BatchSinglePartitionKeyTests.VerifyBatchProcessed( batchResponse, numberOfOperations: 1, expectedStatusCode: HttpStatusCode.PreconditionFailed); Assert.AreEqual(HttpStatusCode.PreconditionFailed, batchResponse[0].StatusCode); // ensure the document was not updated await BatchTestBase.VerifyByReadAsync(container, this.TestDocPk1ExistingB); } }
public override TransactionalBatch CreateItemStream( Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions = null) { if (requestOptions is EncryptionTransactionalBatchItemRequestOptions encryptionItemRequestOptions && encryptionItemRequestOptions.EncryptionOptions != null) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("EncryptItemStream")) { streamPayload = EncryptionProcessor.EncryptAsync( streamPayload, this.encryptor, encryptionItemRequestOptions.EncryptionOptions, diagnosticsContext, cancellationToken: default).Result; } } this.transactionalBatch = this.transactionalBatch.CreateItemStream( streamPayload, requestOptions); return(this); }
public async Task NoContentResponseTransactionBatchOverrideTest() { string pkId = "TestBatchId"; TransactionalBatch batch = this.containerWithFlag.CreateTransactionalBatch(new PartitionKey(pkId)); TransactionalBatchItemRequestOptions requestOptions = new TransactionalBatchItemRequestOptions() { EnableContentResponseOnWrite = false }; 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(response.Count, 100); foreach (TransactionalBatchOperationResult itemResponse in response) { Assert.IsTrue(itemResponse.StatusCode == HttpStatusCode.Created); Assert.IsNull(itemResponse.ResourceStream); } }
public override TransactionalBatch DeleteItem(string id, TransactionalBatchItemRequestOptions requestOptions = null) { Guard.AgainstNullAndEmpty(nameof(id), id); operationsHolder.AddOperation(new DeleteItemOperation(id, requestOptions, PartitionKey)); return(this); }
public override TransactionalBatch UpsertItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions = null) { Guard.AgainstNull(nameof(streamPayload), streamPayload); operationsHolder.AddOperation(new UpsertItemStreamOperation(streamPayload, requestOptions, PartitionKey)); return(this); }
public override TransactionalBatch UpsertItem <T>(T item, TransactionalBatchItemRequestOptions requestOptions = null) { Guard.AgainstNull(nameof(item), item); operationsHolder.AddOperation(new UpsertItemOperation <T>(item, requestOptions, PartitionKey)); return(this); }
private bool Equals(TransactionalBatchItemRequestOptions x, TransactionalBatchItemRequestOptions y) { if (x == null && y == null) { return(true); } else if (x != null && y != null) { RequestMessage xMessage = new RequestMessage(); RequestMessage yMessage = new RequestMessage(); x.PopulateRequestOptions(xMessage); y.PopulateRequestOptions(yMessage); foreach (string headerName in xMessage.Headers) { if (xMessage.Headers[headerName] != yMessage.Headers[headerName]) { return(false); } } return(true); } return(false); }
public override TransactionalBatch ReplaceItem <T>(string id, T item, TransactionalBatchItemRequestOptions requestOptions = null) { Guard.AgainstNullAndEmpty(nameof(id), id); Guard.AgainstNull(nameof(item), item); operationsHolder.AddOperation(new ReplaceItemOperation <T>(id, item, requestOptions, PartitionKey)); return(this); }
public override TransactionalBatch CreateItemStream( Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions = null) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("EncryptItemStream")) { EncryptionSettings encryptionSettings = this.encryptionContainer.GetOrUpdateEncryptionSettingsFromCacheAsync(obsoleteEncryptionSettings: null, cancellationToken: default)
public override TransactionalBatch ReadItem( string id, TransactionalBatchItemRequestOptions requestOptions = null) { this.transactionalBatch = this.transactionalBatch.ReadItem( id, requestOptions); return(this); }
private static void Store(OrderShippingInformation orderShippingInformation, IMessageHandlerContext context) { var session = context.SynchronizedStorageSession.CosmosPersistenceSession(); var requestOptions = new TransactionalBatchItemRequestOptions { EnableContentResponseOnWrite = false, }; session.Batch.CreateItem(orderShippingInformation, requestOptions); }
public void FromItemRequestOptions_WithDefaultValues() { ItemRequestOptions itemRequestOptions = new ItemRequestOptions(); TransactionalBatchItemRequestOptions batchItemRequestOptions = TransactionalBatchItemRequestOptions.FromItemRequestOptions(itemRequestOptions); Assert.AreEqual(itemRequestOptions.IfMatchEtag, batchItemRequestOptions.IfMatchEtag); Assert.AreEqual(itemRequestOptions.IfNoneMatchEtag, batchItemRequestOptions.IfNoneMatchEtag); Assert.AreEqual(itemRequestOptions.IndexingDirective, batchItemRequestOptions.IndexingDirective); Assert.AreEqual(itemRequestOptions.Properties, batchItemRequestOptions.Properties); }
public override TransactionalBatch CreateItem <T>( T item, TransactionalBatchItemRequestOptions requestOptions = null) { Stream itemStream = this.cosmosSerializer.ToStream <T>(item); return(this.CreateItemStream( itemStream, requestOptions)); }
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 TransactionalBatchItemRequestOptions GetBatchItemRequestOptions(TestDoc doc, bool isSchematized, bool useEpk = false, int?ttlInSeconds = null) { TransactionalBatchItemRequestOptions requestOptions = new TransactionalBatchItemRequestOptions(); if (PopulateRequestOptions(requestOptions, doc, isSchematized, useEpk, ttlInSeconds)) { return(requestOptions); } return(null); }
public ItemBatchOperation( OperationType operationType, int operationIndex, PartitionKey partitionKey, T resource, string id = null, TransactionalBatchItemRequestOptions requestOptions = null) : base(operationType, operationIndex, partitionKey: partitionKey, id: id, requestOptions: requestOptions) { this.Resource = resource; }
public ItemBatchOperation( OperationType operationType, int operationIndex, T resource, ContainerInternal containerCore, string id = null, TransactionalBatchItemRequestOptions requestOptions = null) : base(operationType, operationIndex, containerCore: containerCore, id: id, requestOptions: requestOptions) { this.Resource = resource; }
public override TransactionalBatch ReplaceItem <T>( string id, T item, TransactionalBatchItemRequestOptions requestOptions = null) { Stream itemStream = this.cosmosSerializer.ToStream <T>(item); return(this.ReplaceItemStream( id, itemStream, requestOptions)); }
public override void Apply(TransactionalBatch transactionalBatch, PartitionKeyPath partitionKeyPath) { var jObject = ToEnrichedJObject(partitionKeyPath); // has to be kept open stream = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jObject))); var options = new TransactionalBatchItemRequestOptions { EnableContentResponseOnWrite = false }; transactionalBatch.CreateItemStream(stream, options); }
private static void VerifyBatchItemRequestOptionsAreEqual(TransactionalBatchItemRequestOptions expected, TransactionalBatchItemRequestOptions actual) { if (expected != null) { Assert.AreEqual(expected.IfMatchEtag, actual.IfMatchEtag); Assert.AreEqual(expected.IfNoneMatchEtag, actual.IfNoneMatchEtag); if (expected.IndexingDirective.HasValue) { Assert.AreEqual(expected.IndexingDirective.Value, actual.IndexingDirective.Value); } else { Assert.IsTrue(!actual.IndexingDirective.HasValue); } if (expected.Properties != null) { Assert.IsNotNull(actual.Properties); if (expected.Properties.TryGetValue(WFConstants.BackendHeaders.BinaryId, out object expectedBinaryIdObj)) { byte[] expectedBinaryId = expectedBinaryIdObj as byte[]; Assert.IsTrue(actual.Properties.TryGetValue(WFConstants.BackendHeaders.BinaryId, out object actualBinaryIdObj)); byte[] actualBinaryId = actualBinaryIdObj as byte[]; CollectionAssert.AreEqual(expectedBinaryId, actualBinaryId); } if (expected.Properties.TryGetValue(WFConstants.BackendHeaders.EffectivePartitionKey, out object expectedEpkObj)) { byte[] expectedEpk = expectedEpkObj as byte[]; Assert.IsTrue(actual.Properties.TryGetValue(WFConstants.BackendHeaders.EffectivePartitionKey, out object actualEpkObj)); byte[] actualEpk = actualEpkObj as byte[]; CollectionAssert.AreEqual(expectedEpk, actualEpk); } if (expected.Properties.TryGetValue(WFConstants.BackendHeaders.TimeToLiveInSeconds, out object expectedTtlObj)) { string expectedTtlStr = expectedTtlObj as string; Assert.IsTrue(actual.Properties.TryGetValue(WFConstants.BackendHeaders.TimeToLiveInSeconds, out object actualTtlObj)); Assert.AreEqual(expectedTtlStr, actualTtlObj as string); } } } else { Assert.IsNull(actual); } }
public void TestWriteOperationWithBinaryIdByteArray() { ISpanResizer <byte> resizer = new MemorySpanResizer <byte>(100); RowBuffer row = new RowBuffer(capacity: 100, resizer: resizer); row.InitLayout(HybridRowVersion.V1, BatchSchemaProvider.BatchOperationLayout, BatchSchemaProvider.BatchLayoutResolver); byte[] testBinaryId = new byte[] { 1, 2, 3, 4, }; ItemRequestOptions requestOptions = new(); requestOptions.Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, testBinaryId }, }; TransactionalBatchItemRequestOptions transactionalBatchItemRequestOptions = TransactionalBatchItemRequestOptions.FromItemRequestOptions(requestOptions); ItemBatchOperation operation = new ItemBatchOperation( operationType: OperationType.Patch, operationIndex: 0, partitionKey: Cosmos.PartitionKey.Null, requestOptions: transactionalBatchItemRequestOptions); int length = operation.GetApproximateSerializedLength(); Assert.AreEqual(testBinaryId.Length, length); Result r = RowWriter.WriteBuffer(ref row, operation, ItemBatchOperation.WriteOperation); if (r != Result.Success) { Assert.Fail(r.ToString()); } bool foundBinaryId = false; RowReader reader = new RowReader(ref row); while (reader.Read()) { if (reader.PathSpan == Utf8String.TranscodeUtf16("binaryId")) { foundBinaryId = true; reader.ReadBinary(out byte[] binaryId); CollectionAssert.AreEqual(testBinaryId, binaryId); } } Assert.IsTrue(foundBinaryId); }
public async Task MakeTransactionalUpdateAsync( string partitionKey, CosmosRegisteredEntity[] entitiesToUpsert, string[] idsToDelete, ILoggerWrapper logger, CancellationToken cancellationToken) { await ExecuteContainerActionAsync(async() => { var batch = Container.CreateTransactionalBatch(new PartitionKey(partitionKey)); foreach (var entity in entitiesToUpsert) { TransactionalBatchItemRequestOptions options = null; if (!string.IsNullOrEmpty(entity.ETag)) { options = new TransactionalBatchItemRequestOptions { IfMatchEtag = entity.ETag, }; } entity.ETag = null; batch.UpsertItem(entity, options); } foreach (var id in idsToDelete) { batch.DeleteItem(id); } using (var batchResponse = await batch.ExecuteAsync(cancellationToken)) { if (!batchResponse.IsSuccessStatusCode) { if (batchResponse.StatusCode == HttpStatusCode.PreconditionFailed) { throw new Exception($"Failed to store batch of entities in {partitionKey} as one or more of the updated entities has been " + $"modified since the last time it was read. This is likely due to a duplicate sync event being received."); } throw new Exception($"Failed to store batch of entities in {partitionKey} " + $"(Response code: {batchResponse.StatusCode}): {batchResponse.ErrorMessage}"); } } }, logger, cancellationToken); }
internal static TransactionalBatchItemRequestOptions FromItemRequestOptions(ItemRequestOptions itemRequestOptions) { if (itemRequestOptions == null) { return(null); } RequestOptions requestOptions = itemRequestOptions as RequestOptions; TransactionalBatchItemRequestOptions batchItemRequestOptions = new TransactionalBatchItemRequestOptions(); batchItemRequestOptions.IndexingDirective = itemRequestOptions.IndexingDirective; batchItemRequestOptions.IfMatchEtag = requestOptions.IfMatchEtag; batchItemRequestOptions.IfNoneMatchEtag = requestOptions.IfNoneMatchEtag; batchItemRequestOptions.Properties = requestOptions.Properties; batchItemRequestOptions.IsEffectivePartitionKeyRouting = requestOptions.IsEffectivePartitionKeyRouting; return(batchItemRequestOptions); }
private static OrderShippingInformation StoreOrderShippingInformation(ShipOrder message, IMessageHandlerContext context) { var transactionalBatch = context.SynchronizedStorageSession.GetSharedTransactionalBatch(); var requestOptions = new TransactionalBatchItemRequestOptions { EnableContentResponseOnWrite = false, }; var orderShippingInformation = new OrderShippingInformation { Id = Guid.NewGuid(), OrderId = message.OrderId, ShippedAt = DateTimeOffset.UtcNow }; transactionalBatch.CreateItem(orderShippingInformation, requestOptions); return(orderShippingInformation); }
public void FromItemRequestOptions_WithCustomValues() { ItemRequestOptions itemRequestOptions = new ItemRequestOptions(); itemRequestOptions.IfMatchEtag = Guid.NewGuid().ToString(); itemRequestOptions.IfNoneMatchEtag = Guid.NewGuid().ToString(); itemRequestOptions.IndexingDirective = Cosmos.IndexingDirective.Exclude; itemRequestOptions.Properties = new Dictionary <string, object>() { { "test", "test" } }; TransactionalBatchItemRequestOptions batchItemRequestOptions = TransactionalBatchItemRequestOptions.FromItemRequestOptions(itemRequestOptions); Assert.AreEqual(itemRequestOptions.IfMatchEtag, batchItemRequestOptions.IfMatchEtag); Assert.AreEqual(itemRequestOptions.IfNoneMatchEtag, batchItemRequestOptions.IfNoneMatchEtag); Assert.AreEqual(itemRequestOptions.IndexingDirective, batchItemRequestOptions.IndexingDirective); Assert.AreEqual(itemRequestOptions.Properties, batchItemRequestOptions.Properties); }
internal static TransactionalBatchItemRequestOptions FromItemRequestOptions(ItemRequestOptions itemRequestOptions) { if (itemRequestOptions == null) { return(null); } RequestOptions requestOptions = itemRequestOptions; TransactionalBatchItemRequestOptions batchItemRequestOptions = new TransactionalBatchItemRequestOptions { IndexingDirective = itemRequestOptions.IndexingDirective, IfMatchEtag = itemRequestOptions.IfMatchEtag, IfNoneMatchEtag = itemRequestOptions.IfNoneMatchEtag, Properties = itemRequestOptions.Properties, EnableContentResponseOnWrite = itemRequestOptions.EnableContentResponseOnWrite, IsEffectivePartitionKeyRouting = itemRequestOptions.IsEffectivePartitionKeyRouting }; return(batchItemRequestOptions); }
public override TransactionalBatch CreateItem <T>( T item, TransactionalBatchItemRequestOptions requestOptions = null) { if (!(requestOptions is EncryptionTransactionalBatchItemRequestOptions encryptionItemRequestOptions) || encryptionItemRequestOptions.EncryptionOptions == null) { this.transactionalBatch = this.transactionalBatch.CreateItem( item, requestOptions); return(this); } Stream itemStream = this.cosmosSerializer.ToStream <T>(item); return(this.CreateItemStream( itemStream, requestOptions)); }
public async Task BatchWithReplaceOfStaleEntityAsync() { Container container = BatchTestBase.JsonContainer; await this.CreateJsonTestDocsAsync(container); TestDoc staleTestDocToReplace = this.GetTestDocCopy(this.TestDocPk1ExistingA); staleTestDocToReplace.Cost++; TransactionalBatchItemRequestOptions staleReplaceOptions = new TransactionalBatchItemRequestOptions() { IfMatchEtag = Guid.NewGuid().ToString() }; await this.RunWithErrorAsync( container, batch => batch.ReplaceItem(staleTestDocToReplace.Id, staleTestDocToReplace, staleReplaceOptions), HttpStatusCode.PreconditionFailed); // make sure the stale doc hasn't changed await BatchTestBase.VerifyByReadAsync(container, this.TestDocPk1ExistingA); }
public override TransactionalBatch ReplaceItemStream( string id, Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions = null) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("EncryptItemStream")) { streamPayload = this.encryptionProcessor.EncryptAsync( streamPayload, diagnosticsContext, default).Result; } this.transactionalBatch = this.transactionalBatch.ReplaceItemStream( id, streamPayload, requestOptions); return(this); }
async Task CreateOrUpdateInBatch(TransactionalBatch batch) { if (etag == null) { batch.CreateItemStream(ToStream(value)); } else { var options = new TransactionalBatchItemRequestOptions { IfMatchEtag = etag }; batch.ReplaceItemStream(TransactionEntityId, ToStream(value), options); } var response = await batch.ExecuteAsync().ConfigureAwait(false); if (!response.IsSuccessStatusCode) { throw new Exception(response.ToString()); } etag = response.Last().ETag; }