diff --git a/Microsoft.Azure.Cosmos/src/Batch/BatchAsyncContainerExecutor.cs b/Microsoft.Azure.Cosmos/src/Batch/BatchAsyncContainerExecutor.cs index 3dfa37876e..550aa90486 100644 --- a/Microsoft.Azure.Cosmos/src/Batch/BatchAsyncContainerExecutor.cs +++ b/Microsoft.Azure.Cosmos/src/Batch/BatchAsyncContainerExecutor.cs @@ -123,6 +123,7 @@ internal virtual async Task ValidateOperationAsync( || itemRequestOptions.PreTriggers != null || itemRequestOptions.PostTriggers != null || itemRequestOptions.SessionToken != null + || itemRequestOptions.Properties != null || itemRequestOptions.DedicatedGatewayRequestOptions?.MaxIntegratedCacheStaleness != null) { throw new InvalidOperationException(ClientResources.UnsupportedBulkRequestOptions); diff --git a/Microsoft.Azure.Cosmos/src/ClientResources.Designer.cs b/Microsoft.Azure.Cosmos/src/ClientResources.Designer.cs index eee1a9ef8c..7ea2672d6c 100644 --- a/Microsoft.Azure.Cosmos/src/ClientResources.Designer.cs +++ b/Microsoft.Azure.Cosmos/src/ClientResources.Designer.cs @@ -315,10 +315,8 @@ internal static string FailedToEvaluateSpatialExpression { /// /// Looks up a localized string similar to Failed to get AAD token from the provided Azure.Core.TokenCredential.. /// - internal static string FailedToGetAadToken - { - get - { + internal static string FailedToGetAadToken { + get { return ResourceManager.GetString("FailedToGetAadToken", resourceCulture); } } @@ -639,7 +637,7 @@ internal static string UnexpectedTokenType { } /// - /// Looks up a localized string similar to Consistency, Session, and Triggers are not allowed when AllowBulkExecution is set to true.. + /// Looks up a localized string similar to Consistency, Session, Properties, and Triggers are not allowed when AllowBulkExecution is set to true.. /// internal static string UnsupportedBulkRequestOptions { get { diff --git a/Microsoft.Azure.Cosmos/src/ClientResources.resx b/Microsoft.Azure.Cosmos/src/ClientResources.resx index becffe27f7..ae00e80a78 100644 --- a/Microsoft.Azure.Cosmos/src/ClientResources.resx +++ b/Microsoft.Azure.Cosmos/src/ClientResources.resx @@ -298,7 +298,7 @@ Instantiation of only value types, anonymous types and spatial types are supported. - Consistency, Session, and Triggers are not allowed when AllowBulkExecution is set to true. + Consistency, Session, Properties, and Triggers are not allowed when AllowBulkExecution is set to true. The client was not configured to allow for encryption. Create the client by using cosmosClientBuilder.WithEncryptor. diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Batch/BatchAsyncContainerExecutorTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Batch/BatchAsyncContainerExecutorTests.cs index 2b4b26cadd..a5a020d030 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Batch/BatchAsyncContainerExecutorTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Batch/BatchAsyncContainerExecutorTests.cs @@ -7,7 +7,6 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests using System; using System.Collections.Generic; using System.Net; - using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Documents; @@ -16,7 +15,7 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests [TestClass] public class BatchAsyncContainerExecutorTests { - private static CosmosSerializer cosmosDefaultJsonSerializer = new CosmosJsonDotNetSerializer(); + private readonly static CosmosSerializer cosmosDefaultJsonSerializer = new CosmosJsonDotNetSerializer(); private CosmosClient cosmosClient; private ContainerInternal cosmosContainer; @@ -79,6 +78,9 @@ public async Task ValidateInvalidRequestOptionsAsync() MyDocument myDocument = new MyDocument() { id = id, Status = id }; await Assert.ThrowsExceptionAsync(() => executor.ValidateOperationAsync(new ItemBatchOperation(OperationType.Replace, 0, new Cosmos.PartitionKey(id), id, cosmosDefaultJsonSerializer.ToStream(myDocument)), new ItemRequestOptions() { SessionToken = "something" })); + await Assert.ThrowsExceptionAsync(() => executor.ValidateOperationAsync( + new ItemBatchOperation(OperationType.Replace, 0, new Cosmos.PartitionKey(id), id, cosmosDefaultJsonSerializer.ToStream(myDocument)), + new ItemRequestOptions() { Properties = new Dictionary() { { "test", "test" } } })); await Assert.ThrowsExceptionAsync(() => executor.ValidateOperationAsync( new ItemBatchOperation(OperationType.Replace, 0, new Cosmos.PartitionKey(id), id, cosmosDefaultJsonSerializer.ToStream(myDocument)), new ItemRequestOptions() { DedicatedGatewayRequestOptions = new DedicatedGatewayRequestOptions { MaxIntegratedCacheStaleness = TimeSpan.FromMinutes(3) } })); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Batch/CosmosItemBulkTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Batch/CosmosItemBulkTests.cs index eaf72c67ce..028b4ad95b 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Batch/CosmosItemBulkTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Batch/CosmosItemBulkTests.cs @@ -15,7 +15,6 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests public class CosmosItemBulkTests { private Container container; - private Container nonBulkContainer; private Database database; [TestInitialize] @@ -26,14 +25,12 @@ public async Task TestInitialize() AllowBulkExecution = true }; CosmosClient client = TestCommon.CreateCosmosClient(clientOptions); - CosmosClient nonBulkClient = TestCommon.CreateCosmosClient(); DatabaseResponse response = await client.CreateDatabaseIfNotExistsAsync(Guid.NewGuid().ToString()); this.database = response.Database; ContainerResponse containerResponse = await this.database.CreateContainerAsync(Guid.NewGuid().ToString(), "/pk", 10000); this.container = containerResponse; - this.nonBulkContainer = nonBulkClient.GetContainer(this.database.Id, this.container.Id); } [TestCleanup] @@ -42,13 +39,47 @@ public async Task Cleanup() await this.database.DeleteAsync(); } + [TestMethod] + public async Task ValidateRequestOptions() + { + async Task ExecuteAndValidateCreateItemAsync(int i) + { + try + { + await CosmosItemBulkTests.ExecuteCreateStreamAsync( + this.container, + CosmosItemBulkTests.CreateItem(i.ToString()), + new ItemRequestOptions() + { + Properties = new Dictionary() { { "test", "test" } }, + DedicatedGatewayRequestOptions = new DedicatedGatewayRequestOptions { MaxIntegratedCacheStaleness = TimeSpan.FromMinutes(3) }, + SessionToken = Guid.NewGuid().ToString(), + PreTriggers = new List() { "preTrigger" }, + PostTriggers = new List() { "postTrigger" } + }); + Assert.Fail("Request should have failed"); + } + catch (InvalidOperationException) + { + } + } + + List tasks = new List(); + for (int i = 0; i < 100; i++) + { + tasks.Add(ExecuteAndValidateCreateItemAsync(i)); + } + + await Task.WhenAll(tasks); + } + [TestMethod] public async Task CreateItemStream_WithBulk() { List> tasks = new List>(); for (int i = 0; i < 100; i++) { - tasks.Add(ExecuteCreateStreamAsync(this.container, CreateItem(i.ToString()))); + tasks.Add(CosmosItemBulkTests.ExecuteCreateStreamAsync(this.container, CosmosItemBulkTests.CreateItem(i.ToString()))); } await Task.WhenAll(tasks); @@ -73,7 +104,7 @@ public async Task CreateItemAsync_WithBulk() List>> tasks = new List>>(); for (int i = 0; i < 100; i++) { - tasks.Add(ExecuteCreateAsync(this.container, CreateItem(i.ToString()))); + tasks.Add(CosmosItemBulkTests.ExecuteCreateAsync(this.container, CosmosItemBulkTests.CreateItem(i.ToString()))); } await Task.WhenAll(tasks); @@ -96,7 +127,7 @@ public async Task CreateItemJObjectWithoutPK_WithBulk() List>> tasks = new List>>(); for (int i = 0; i < 100; i++) { - tasks.Add(this.container.CreateItemAsync(CreateJObjectWithoutPK(i.ToString()))); + tasks.Add(this.container.CreateItemAsync(CosmosItemBulkTests.CreateJObjectWithoutPK(i.ToString()))); } await Task.WhenAll(tasks); @@ -119,7 +150,7 @@ public async Task UpsertItemStream_WithBulk() List> tasks = new List>(); for (int i = 0; i < 100; i++) { - tasks.Add(ExecuteUpsertStreamAsync(this.container, CreateItem(i.ToString()))); + tasks.Add(CosmosItemBulkTests.ExecuteUpsertStreamAsync(this.container, CosmosItemBulkTests.CreateItem(i.ToString()))); } await Task.WhenAll(tasks); @@ -144,7 +175,7 @@ public async Task UpsertItem_WithBulk() List>> tasks = new List>>(); for (int i = 0; i < 100; i++) { - tasks.Add(ExecuteUpsertAsync(this.container, CreateItem(i.ToString()))); + tasks.Add(CosmosItemBulkTests.ExecuteUpsertAsync(this.container, CosmosItemBulkTests.CreateItem(i.ToString()))); } await Task.WhenAll(tasks); @@ -169,9 +200,9 @@ public async Task DeleteItemStream_WithBulk() List> tasks = new List>(); for (int i = 0; i < 100; i++) { - ToDoActivity createdDocument = CreateItem(i.ToString()); + ToDoActivity createdDocument = CosmosItemBulkTests.CreateItem(i.ToString()); createdDocuments.Add(createdDocument); - tasks.Add(ExecuteCreateStreamAsync(this.container, createdDocument)); + tasks.Add(CosmosItemBulkTests.ExecuteCreateStreamAsync(this.container, createdDocument)); } await Task.WhenAll(tasks); @@ -180,7 +211,7 @@ public async Task DeleteItemStream_WithBulk() // Delete the items foreach (ToDoActivity createdDocument in createdDocuments) { - deleteTasks.Add(ExecuteDeleteStreamAsync(this.container, createdDocument)); + deleteTasks.Add(CosmosItemBulkTests.ExecuteDeleteStreamAsync(this.container, createdDocument)); } await Task.WhenAll(deleteTasks); @@ -204,9 +235,9 @@ public async Task DeleteItem_WithBulk() List>> tasks = new List>>(); for (int i = 0; i < 100; i++) { - ToDoActivity createdDocument = CreateItem(i.ToString()); + ToDoActivity createdDocument = CosmosItemBulkTests.CreateItem(i.ToString()); createdDocuments.Add(createdDocument); - tasks.Add(ExecuteCreateAsync(this.container, createdDocument)); + tasks.Add(CosmosItemBulkTests.ExecuteCreateAsync(this.container, createdDocument)); } await Task.WhenAll(tasks); @@ -215,7 +246,7 @@ public async Task DeleteItem_WithBulk() // Delete the items foreach (ToDoActivity createdDocument in createdDocuments) { - deleteTasks.Add(ExecuteDeleteAsync(this.container, createdDocument)); + deleteTasks.Add(CosmosItemBulkTests.ExecuteDeleteAsync(this.container, createdDocument)); } await Task.WhenAll(deleteTasks); @@ -239,9 +270,9 @@ public async Task ReadItemStream_WithBulk() List> tasks = new List>(); for (int i = 0; i < 100; i++) { - ToDoActivity createdDocument = CreateItem(i.ToString()); + ToDoActivity createdDocument = CosmosItemBulkTests.CreateItem(i.ToString()); createdDocuments.Add(createdDocument); - tasks.Add(ExecuteCreateStreamAsync(this.container, createdDocument)); + tasks.Add(CosmosItemBulkTests.ExecuteCreateStreamAsync(this.container, createdDocument)); } await Task.WhenAll(tasks); @@ -250,7 +281,7 @@ public async Task ReadItemStream_WithBulk() // Read the items foreach (ToDoActivity createdDocument in createdDocuments) { - readTasks.Add(ExecuteReadStreamAsync(this.container, createdDocument)); + readTasks.Add(CosmosItemBulkTests.ExecuteReadStreamAsync(this.container, createdDocument)); } await Task.WhenAll(readTasks); @@ -274,9 +305,9 @@ public async Task ReadItem_WithBulk() List>> tasks = new List>>(); for (int i = 0; i < 100; i++) { - ToDoActivity createdDocument = CreateItem(i.ToString()); + ToDoActivity createdDocument = CosmosItemBulkTests.CreateItem(i.ToString()); createdDocuments.Add(createdDocument); - tasks.Add(ExecuteCreateAsync(this.container, createdDocument)); + tasks.Add(CosmosItemBulkTests.ExecuteCreateAsync(this.container, createdDocument)); } await Task.WhenAll(tasks); @@ -285,7 +316,7 @@ public async Task ReadItem_WithBulk() // Read the items foreach (ToDoActivity createdDocument in createdDocuments) { - readTasks.Add(ExecuteReadAsync(this.container, createdDocument)); + readTasks.Add(CosmosItemBulkTests.ExecuteReadAsync(this.container, createdDocument)); } await Task.WhenAll(readTasks); @@ -309,9 +340,9 @@ public async Task ReplaceItemStream_WithBulk() List> tasks = new List>(); for (int i = 0; i < 100; i++) { - ToDoActivity createdDocument = CreateItem(i.ToString()); + ToDoActivity createdDocument = CosmosItemBulkTests.CreateItem(i.ToString()); createdDocuments.Add(createdDocument); - tasks.Add(ExecuteCreateStreamAsync(this.container, createdDocument)); + tasks.Add(CosmosItemBulkTests.ExecuteCreateStreamAsync(this.container, createdDocument)); } await Task.WhenAll(tasks); @@ -320,7 +351,7 @@ public async Task ReplaceItemStream_WithBulk() // Replace the items foreach (ToDoActivity createdDocument in createdDocuments) { - replaceTasks.Add(ExecuteReplaceStreamAsync(this.container, createdDocument)); + replaceTasks.Add(CosmosItemBulkTests.ExecuteReplaceStreamAsync(this.container, createdDocument)); } await Task.WhenAll(replaceTasks); @@ -344,9 +375,9 @@ public async Task ReplaceItem_WithBulk() List>> tasks = new List>>(); for (int i = 0; i < 100; i++) { - ToDoActivity createdDocument = CreateItem(i.ToString()); + ToDoActivity createdDocument = CosmosItemBulkTests.CreateItem(i.ToString()); createdDocuments.Add(createdDocument); - tasks.Add(ExecuteCreateAsync(this.container, createdDocument)); + tasks.Add(CosmosItemBulkTests.ExecuteCreateAsync(this.container, createdDocument)); } await Task.WhenAll(tasks); @@ -355,7 +386,7 @@ public async Task ReplaceItem_WithBulk() // Replace the items foreach (ToDoActivity createdDocument in createdDocuments) { - replaceTasks.Add(ExecuteReplaceAsync(this.container, createdDocument)); + replaceTasks.Add(CosmosItemBulkTests.ExecuteReplaceAsync(this.container, createdDocument)); } await Task.WhenAll(replaceTasks); @@ -379,9 +410,9 @@ public async Task PatchItemStream_WithBulk() List> tasks = new List>(); for (int i = 0; i < 100; i++) { - ToDoActivity createdDocument = CreateItem(i.ToString()); + ToDoActivity createdDocument = CosmosItemBulkTests.CreateItem(i.ToString()); createdDocuments.Add(createdDocument); - tasks.Add(ExecuteCreateStreamAsync(this.container, createdDocument)); + tasks.Add(CosmosItemBulkTests.ExecuteCreateStreamAsync(this.container, createdDocument)); } await Task.WhenAll(tasks); @@ -394,7 +425,7 @@ public async Task PatchItemStream_WithBulk() // Patch the items foreach (ToDoActivity createdDocument in createdDocuments) { - PatchTasks.Add(ExecutePatchStreamAsync((ContainerInternal)this.container, createdDocument, patch)); + PatchTasks.Add(CosmosItemBulkTests.ExecutePatchStreamAsync((ContainerInternal)this.container, createdDocument, patch)); } await Task.WhenAll(PatchTasks); @@ -418,9 +449,9 @@ public async Task PatchItem_WithBulk() List>> tasks = new List>>(); for (int i = 0; i < 100; i++) { - ToDoActivity createdDocument = CreateItem(i.ToString()); + ToDoActivity createdDocument = CosmosItemBulkTests.CreateItem(i.ToString()); createdDocuments.Add(createdDocument); - tasks.Add(ExecuteCreateAsync(this.container, createdDocument)); + tasks.Add(CosmosItemBulkTests.ExecuteCreateAsync(this.container, createdDocument)); } await Task.WhenAll(tasks); @@ -433,7 +464,7 @@ public async Task PatchItem_WithBulk() // Patch the items foreach (ToDoActivity createdDocument in createdDocuments) { - patchTasks.Add(ExecutePatchAsync((ContainerInternal)this.container, createdDocument, patch)); + patchTasks.Add(CosmosItemBulkTests.ExecutePatchAsync((ContainerInternal)this.container, createdDocument, patch)); } await Task.WhenAll(patchTasks); @@ -470,10 +501,10 @@ private async Task CreateLargeItemStreamWithBulk(int appxItemSize) List> tasks = new List>(); for (int i = 0; i < 3; i++) { - ToDoActivity item = CreateItem(i.ToString()); + ToDoActivity item = CosmosItemBulkTests.CreateItem(i.ToString()); if (i == 1) { item.description = new string('x', appxItemSize); } - tasks.Add(ExecuteCreateStreamAsync(this.container, item)); + tasks.Add(CosmosItemBulkTests.ExecuteCreateStreamAsync(this.container, item)); } await Task.WhenAll(tasks); @@ -532,9 +563,9 @@ private static Task> ExecuteReadAsync(Container conta return container.ReadItemAsync(item.id, new PartitionKey(item.pk)); } - private static Task ExecuteCreateStreamAsync(Container container, ToDoActivity item) + private static Task ExecuteCreateStreamAsync(Container container, ToDoActivity item, ItemRequestOptions itemRequestOptions = null) { - return container.CreateItemStreamAsync(TestCommon.SerializerCore.ToStream(item), new PartitionKey(item.pk)); + return container.CreateItemStreamAsync(TestCommon.SerializerCore.ToStream(item), new PartitionKey(item.pk), itemRequestOptions); } private static Task ExecuteUpsertStreamAsync(Container container, ToDoActivity item)