diff --git a/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/AsynReadWithMultipleClients.java b/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/AsynReadWithMultipleClients.java index b7d1250c6cfa0..dd9c0ad47baf2 100644 --- a/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/AsynReadWithMultipleClients.java +++ b/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/AsynReadWithMultipleClients.java @@ -226,6 +226,7 @@ private void createClients() { .connectionPolicy(configuration.getConnectionPolicy()) .consistencyLevel(configuration.getConsistencyLevel()) .connectionReuseAcrossClientsEnabled(true) + .contentResponseOnWriteEnabled(Boolean.parseBoolean(configuration.isContentResponseOnWriteEnabled())) .buildAsyncClient(); List docsToRead = new ArrayList<>(); CosmosAsyncDatabase cosmosAsyncDatabase = null; diff --git a/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/AsyncBenchmark.java b/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/AsyncBenchmark.java index b1530abb1a30f..7324fcfcf5e18 100644 --- a/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/AsyncBenchmark.java +++ b/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/AsyncBenchmark.java @@ -66,6 +66,7 @@ abstract class AsyncBenchmark { .key(cfg.getMasterKey()) .connectionPolicy(cfg.getConnectionPolicy()) .consistencyLevel(cfg.getConsistencyLevel()) + .contentResponseOnWriteEnabled(Boolean.parseBoolean(cfg.isContentResponseOnWriteEnabled())) .buildAsyncClient(); configuration = cfg; logger = LoggerFactory.getLogger(this.getClass()); diff --git a/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/Configuration.java b/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/Configuration.java index 377e3c5f18c97..9a7d35eabbb47 100644 --- a/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/Configuration.java +++ b/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/Configuration.java @@ -130,6 +130,9 @@ public Duration convert(String value) { @Parameter(names = "-useSync", description = "Uses Sync API") private boolean useSync = false; + @Parameter(names = "-contentResponseOnWriteEnabled", description = "if set to false, does not returns content response on document write operations") + private String contentResponseOnWriteEnabled = String.valueOf(true); + @Parameter(names = {"-h", "-help", "--help"}, description = "Help", help = true) private boolean help = false; @@ -264,6 +267,10 @@ ConsistencyLevel getConsistencyLevel() { return consistencyLevel; } + String isContentResponseOnWriteEnabled() { + return contentResponseOnWriteEnabled; + } + String getDatabaseId() { return databaseId; } diff --git a/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/Main.java b/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/Main.java index 26c7fdd3c285b..d2b4295a8d742 100644 --- a/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/Main.java +++ b/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/Main.java @@ -27,6 +27,8 @@ public static void main(String[] args) throws Exception { return; } + validateConfiguration(cfg); + if (cfg.isSync()) { syncBenchmark(cfg); } else { @@ -44,6 +46,19 @@ public static void main(String[] args) throws Exception { } } + private static void validateConfiguration(Configuration cfg) { + switch (cfg.getOperationType()) { + case WriteLatency: + case WriteThroughput: + break; + default: + if (!Boolean.parseBoolean(cfg.isContentResponseOnWriteEnabled())) { + throw new IllegalArgumentException("contentResponseOnWriteEnabled parameter can only be set to false " + + "for write latency and write throughput operations"); + } + } + } + private static void syncBenchmark(Configuration cfg) throws Exception { LOGGER.info("Sync benchmark ..."); SyncBenchmark benchmark = null; diff --git a/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/SyncBenchmark.java b/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/SyncBenchmark.java index e27f7939db8fe..ddd4420301cd5 100644 --- a/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/SyncBenchmark.java +++ b/sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/SyncBenchmark.java @@ -105,6 +105,7 @@ public T apply(T o, Throwable throwable) { .key(cfg.getMasterKey()) .connectionPolicy(cfg.getConnectionPolicy()) .consistencyLevel(cfg.getConsistencyLevel()) + .contentResponseOnWriteEnabled(Boolean.parseBoolean(cfg.isContentResponseOnWriteEnabled())) .buildClient(); try { diff --git a/sdk/cosmos/azure-cosmos-benchmark/src/test/java/com/azure/cosmos/benchmark/Utils.java b/sdk/cosmos/azure-cosmos-benchmark/src/test/java/com/azure/cosmos/benchmark/Utils.java index bdbca32cdbed5..e55098ca94802 100644 --- a/sdk/cosmos/azure-cosmos-benchmark/src/test/java/com/azure/cosmos/benchmark/Utils.java +++ b/sdk/cosmos/azure-cosmos-benchmark/src/test/java/com/azure/cosmos/benchmark/Utils.java @@ -26,9 +26,10 @@ public static AsyncDocumentClient housekeepingClient() { options.setMaxRetryWaitTime(Duration.ofSeconds(60)); connectionPolicy.setThrottlingRetryOptions(options); return new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) - .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) - .withConnectionPolicy(connectionPolicy) - .build(); + .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) + .withConnectionPolicy(connectionPolicy) + .withContentResponseOnWriteEnabled(true) + .build(); } public static String getCollectionLink(Database db, DocumentCollection collection) { diff --git a/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/examples/ChangeFeed/SampleChangeFeedProcessor.java b/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/examples/ChangeFeed/SampleChangeFeedProcessor.java index 3200aba9020ae..439f510ed9f77 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/examples/ChangeFeed/SampleChangeFeedProcessor.java +++ b/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/examples/ChangeFeed/SampleChangeFeedProcessor.java @@ -121,6 +121,7 @@ public static CosmosAsyncClient getCosmosClient() { .key(SampleConfigurations.MASTER_KEY) .connectionPolicy(ConnectionPolicy.getDefaultPolicy()) .consistencyLevel(ConsistencyLevel.EVENTUAL) + .contentResponseOnWriteEnabled(true) .buildAsyncClient(); } diff --git a/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/rx/examples/multimaster/samples/MultiMasterScenario.java b/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/rx/examples/multimaster/samples/MultiMasterScenario.java index a6707b2e8391f..5b15fbd2a274e 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/rx/examples/multimaster/samples/MultiMasterScenario.java +++ b/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/rx/examples/multimaster/samples/MultiMasterScenario.java @@ -59,7 +59,9 @@ public MultiMasterScenario() { .withMasterKeyOrResourceToken(this.accountKey) .withServiceEndpoint(this.accountEndpoint) .withConsistencyLevel(ConsistencyLevel.EVENTUAL) - .withConnectionPolicy(policy).build(); + .withConnectionPolicy(policy) + .withContentResponseOnWriteEnabled(true) + .build(); workers.add(new Worker(client, databaseName, basicCollectionName)); diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/CollectionCRUDAsyncAPITest.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/CollectionCRUDAsyncAPITest.java index 6e572f6febe47..04a10a6d4fffa 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/CollectionCRUDAsyncAPITest.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/CollectionCRUDAsyncAPITest.java @@ -81,7 +81,8 @@ public void before_CollectionCRUDAsyncAPITest() { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true); this.client = this.clientBuilder().build(); diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/ConflictAPITest.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/ConflictAPITest.java index 9c6d260382237..3271607d60efb 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/ConflictAPITest.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/ConflictAPITest.java @@ -59,7 +59,8 @@ public void before_ConflictAPITest() { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true); this.client = this.clientBuilder().build(); diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/CosmosAuthorizationTokenResolverTest.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/CosmosAuthorizationTokenResolverTest.java index bc051fe7596a3..380a27b0dd2ae 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/CosmosAuthorizationTokenResolverTest.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/CosmosAuthorizationTokenResolverTest.java @@ -69,7 +69,8 @@ public void before_TokenResolverTest() { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true); this.client = this.clientBuilder().build(); @@ -145,6 +146,7 @@ public void readDocumentThroughTokenResolver() throws Exception { .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.SESSION) .withTokenResolver(getTokenResolverForRead()) + .withContentResponseOnWriteEnabled(true) .build(); List> capturedResponse = Collections .synchronizedList(new ArrayList<>()); @@ -183,6 +185,7 @@ public void deleteDocumentThroughTokenResolver() throws Exception { .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.SESSION) .withTokenResolver(getTokenResolverForReadWrite()) + .withContentResponseOnWriteEnabled(true) .build(); List> capturedResponse = Collections .synchronizedList(new ArrayList<>()); @@ -225,6 +228,7 @@ public void blockListUserThroughTokenResolver() throws Exception { .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.SESSION) .withTokenResolver(getTokenResolverWithBlockList(blockListedUserId, errorMessage)) + .withContentResponseOnWriteEnabled(true) .build(); // READ a document using a block listed user, passing the 'userId' in the item. diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DatabaseCRUDAsyncAPITest.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DatabaseCRUDAsyncAPITest.java index 62da255a422df..5e76d3df1931c 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DatabaseCRUDAsyncAPITest.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DatabaseCRUDAsyncAPITest.java @@ -65,7 +65,8 @@ public void before_DatabaseCRUDAsyncAPITest() { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true); this.client = this.clientBuilder().build(); } diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DocumentCRUDAsyncAPITest.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DocumentCRUDAsyncAPITest.java index 4db2b93f169e2..04cca82d59e10 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DocumentCRUDAsyncAPITest.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DocumentCRUDAsyncAPITest.java @@ -89,7 +89,8 @@ public void before_DocumentCRUDAsyncAPITest() { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true); this.client = this.clientBuilder().build(); diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DocumentQueryAsyncAPITest.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DocumentQueryAsyncAPITest.java index b32b68fb54f15..5c9d999137f21 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DocumentQueryAsyncAPITest.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/DocumentQueryAsyncAPITest.java @@ -85,7 +85,8 @@ public void before_DocumentQueryAsyncAPITest() { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true); this.client = this.clientBuilder().build(); diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/InMemoryGroupbyTest.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/InMemoryGroupbyTest.java index c24d34f7d5d31..b6a2008bb378e 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/InMemoryGroupbyTest.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/InMemoryGroupbyTest.java @@ -46,7 +46,8 @@ public void before_InMemoryGroupbyTest() throws Exception { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true); this.client = this.clientBuilder().build(); diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/OfferCRUDAsyncAPITest.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/OfferCRUDAsyncAPITest.java index e19ed9deba1a6..1cea3438e29b6 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/OfferCRUDAsyncAPITest.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/OfferCRUDAsyncAPITest.java @@ -50,7 +50,8 @@ public void before_OfferCRUDAsyncAPITest() { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true); this.client = this.clientBuilder().build(); diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/StoredProcedureAsyncAPITest.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/StoredProcedureAsyncAPITest.java index 5af4fe79426d3..a02fa03358aaa 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/StoredProcedureAsyncAPITest.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/StoredProcedureAsyncAPITest.java @@ -56,7 +56,8 @@ public void before_StoredProcedureAsyncAPITest() { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true); this.client = this.clientBuilder().build(); diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/UniqueIndexAsyncAPITest.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/UniqueIndexAsyncAPITest.java index f4c0f9bd4d755..924561d43a40e 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/UniqueIndexAsyncAPITest.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/UniqueIndexAsyncAPITest.java @@ -91,7 +91,8 @@ public void before_UniqueIndexAsyncAPITest() { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true); this.client = this.clientBuilder().build(); diff --git a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/Utils.java b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/Utils.java index eeec67601ac58..1972f39c53a47 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/Utils.java +++ b/sdk/cosmos/azure-cosmos-examples/src/test/java/com/azure/cosmos/rx/examples/Utils.java @@ -28,7 +28,7 @@ public void cleanupStaleDatabase() { connectionPolicy.setThrottlingRetryOptions(options); AsyncDocumentClient client = new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) - .withConnectionPolicy(connectionPolicy) + .withConnectionPolicy(connectionPolicy).withContentResponseOnWriteEnabled(true) .build(); safeCleanDatabases(client); client.close(); diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosAsyncClient.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosAsyncClient.java index e30ff232cd61a..2e2aaf51d213e 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosAsyncClient.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosAsyncClient.java @@ -49,6 +49,7 @@ public final class CosmosAsyncClient implements Closeable { private final CosmosKeyCredential cosmosKeyCredential; private final boolean sessionCapturingOverride; private final boolean enableTransportClientSharing; + private final boolean contentResponseOnWriteEnabled; CosmosAsyncClient(CosmosClientBuilder builder) { this.configs = builder.configs(); @@ -61,6 +62,7 @@ public final class CosmosAsyncClient implements Closeable { this.cosmosKeyCredential = builder.getKeyCredential(); this.sessionCapturingOverride = builder.isSessionCapturingOverrideEnabled(); this.enableTransportClientSharing = builder.isConnectionReuseAcrossClientsEnabled(); + this.contentResponseOnWriteEnabled = builder.isContentResponseOnWriteEnabled(); this.asyncDocumentClient = new AsyncDocumentClient.Builder() .withServiceEndpoint(this.serviceEndpoint) .withMasterKeyOrResourceToken(this.keyOrResourceToken) @@ -71,6 +73,7 @@ public final class CosmosAsyncClient implements Closeable { .withTokenResolver(this.cosmosAuthorizationTokenResolver) .withCosmosKeyCredential(this.cosmosKeyCredential) .withTransportClientSharing(this.enableTransportClientSharing) + .withContentResponseOnWriteEnabled(this.contentResponseOnWriteEnabled) .build(); } @@ -163,6 +166,22 @@ CosmosKeyCredential cosmosKeyCredential() { return cosmosKeyCredential; } + /** + * Gets the boolean which indicates whether to only return the headers and status code in Cosmos DB response + * in case of Create, Update and Delete operations on CosmosItem. + * + * If set to false (which is by default), this removes the resource from response. It reduces networking + * and CPU load by not sending the resource back over the network and serializing it + * on the client. + * + * By-default, this is false. + * + * @return a boolean indicating whether resource will be included in the response or not + */ + boolean isContentResponseOnWriteEnabled() { + return contentResponseOnWriteEnabled; + } + /** * CREATE a Database if it does not already exist on the service *

diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosBridgeInternal.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosBridgeInternal.java index 937a452ddc833..932e3fc69e320 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosBridgeInternal.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosBridgeInternal.java @@ -4,8 +4,6 @@ package com.azure.cosmos; import com.azure.cosmos.implementation.AsyncDocumentClient; -import com.azure.cosmos.implementation.DocumentCollection; -import com.azure.cosmos.models.CosmosContainerProperties; /** * DO NOT USE. For internal use only by the SDK. These methods might break at any time. No support will be provided. @@ -66,7 +64,8 @@ public static CosmosClientBuilder cloneCosmosClientBuilder(CosmosClientBuilder b .keyCredential(builder.getKeyCredential()) .permissions(builder.getPermissions()) .authorizationTokenResolver(builder.getAuthorizationTokenResolver()) - .resourceToken(builder.getResourceToken()); + .resourceToken(builder.getResourceToken()) + .contentResponseOnWriteEnabled(builder.isContentResponseOnWriteEnabled()); return copy; } diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosClientBuilder.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosClientBuilder.java index fa42fcdda5df5..0435020dc3e8b 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosClientBuilder.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosClientBuilder.java @@ -39,6 +39,7 @@ public class CosmosClientBuilder { private CosmosKeyCredential cosmosKeyCredential; private boolean sessionCapturingOverrideEnabled; private boolean connectionReuseAcrossClientsEnabled; + private boolean contentResponseOnWriteEnabled; /** * Instantiates a new Cosmos client builder. @@ -291,6 +292,41 @@ public CosmosClientBuilder keyCredential(CosmosKeyCredential cosmosKeyCredential return this; } + /** + * Gets the boolean which indicates whether to only return the headers and status code in Cosmos DB response + * in case of Create, Update and Delete operations on CosmosItem. + * + * If set to false (which is by default), this removes the resource from response. It reduces networking + * and CPU load by not sending the resource back over the network and serializing it + * on the client. + * + * By-default, this is false. + * + * @return a boolean indicating whether resource will be included in the response or not + */ + boolean isContentResponseOnWriteEnabled() { + return contentResponseOnWriteEnabled; + } + + /** + * Sets the boolean to only return the headers and status code in Cosmos DB response + * in case of Create, Update and Delete operations on CosmosItem. + * + * If set to false (which is by default), this removes the resource from response. It reduces networking + * and CPU load by not sending the resource back over the network and serializing it on the client. + * + * This feature does not impact RU usage for read or write operations. + * + * By-default, this is false. + * + * @param contentResponseOnWriteEnabled a boolean indicating whether resource will be included in the response or not + * @return current cosmosClientBuilder + */ + public CosmosClientBuilder contentResponseOnWriteEnabled(boolean contentResponseOnWriteEnabled) { + this.contentResponseOnWriteEnabled = contentResponseOnWriteEnabled; + return this; + } + /** * Builds a cosmos configuration object with the provided properties * diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/AsyncDocumentClient.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/AsyncDocumentClient.java index 3bcec82662021..f0751fba79f1b 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/AsyncDocumentClient.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/AsyncDocumentClient.java @@ -77,6 +77,7 @@ class Builder { CosmosKeyCredential cosmosKeyCredential; boolean sessionCapturingOverride; boolean transportClientSharing; + boolean contentResponseOnWriteEnabled; public Builder withServiceEndpoint(String serviceEndpoint) { try { @@ -158,6 +159,11 @@ public Builder withCosmosKeyCredential(CosmosKeyCredential cosmosKeyCredential) return this; } + public Builder withContentResponseOnWriteEnabled(boolean contentResponseOnWriteEnabled) { + this.contentResponseOnWriteEnabled = contentResponseOnWriteEnabled; + return this; + } + /** * This method will accept functional interface TokenResolver which helps in generation authorization * token per request. AsyncDocumentClient can be successfully initialized with this API without passing any MasterKey, ResourceToken or PermissionFeed. @@ -187,15 +193,16 @@ public AsyncDocumentClient build() { "cannot buildAsyncClient client without key credential"); RxDocumentClientImpl client = new RxDocumentClientImpl(serviceEndpoint, - masterKeyOrResourceToken, - permissionFeed, - connectionPolicy, - desiredConsistencyLevel, - configs, - cosmosAuthorizationTokenResolver, - cosmosKeyCredential, - sessionCapturingOverride, - transportClientSharing); + masterKeyOrResourceToken, + permissionFeed, + connectionPolicy, + desiredConsistencyLevel, + configs, + cosmosAuthorizationTokenResolver, + cosmosKeyCredential, + sessionCapturingOverride, + transportClientSharing, + contentResponseOnWriteEnabled); client.init(); return client; } diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java index 6b85e9cfc80d1..b6ba29c7f9828 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java @@ -306,6 +306,7 @@ public static class SubStatusCodes { } public static class HeaderValues { - public static final String NoCache = "no-cache"; + public static final String NO_CACHE = "no-cache"; + public static final String PREFER_RETURN_MINIMAL = "return=minimal"; } } diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ResourceResponse.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ResourceResponse.java index ba1453d4017c2..a20fa6aeae7ba 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ResourceResponse.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ResourceResponse.java @@ -358,6 +358,17 @@ public String getCosmosResponseDiagnosticString() { return cosmosResponseRequestDiagnosticStatistics.toString(); } + /** + * Gets the ETag from the response headers. + * + * Null in case of delete operation. + * + * @return ETag + */ + public String getETag() { + return this.response.getResponseHeaders().get(HttpConstants.HttpHeaders.E_TAG); + } + long getCurrentQuotaHeader(String headerName) { if (this.usageHeaders.size() == 0 && !StringUtils.isEmpty(this.getMaxResourceQuota()) && diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java index 9f3f52ffffbed..93c44e39cc1dd 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java @@ -77,6 +77,8 @@ * This is meant to be internally used only by our sdk. */ public class RxDocumentClientImpl implements AsyncDocumentClient, IAuthorizationTokenProvider { + + private static final char PREFER_HEADER_SEPERATOR = ';'; private final static ObjectMapper mapper = Utils.getSimpleObjectMapper(); private final Logger logger = LoggerFactory.getLogger(RxDocumentClientImpl.class); private final String masterKeyOrResourceToken; @@ -98,6 +100,7 @@ public class RxDocumentClientImpl implements AsyncDocumentClient, IAuthorization private GlobalAddressResolver addressResolver; private RxPartitionKeyRangeCache partitionKeyRangeCache; private Map> resourceTokensMap; + private final boolean contentResponseOnWriteEnabled; // RetryPolicy retries a request when it encounters session unavailable (see ClientRetryPolicy). // Once it exhausts all write regions it clears the session container, then it uses RxClientCollectionCache @@ -131,8 +134,10 @@ public RxDocumentClientImpl(URI serviceEndpoint, CosmosAuthorizationTokenResolver cosmosAuthorizationTokenResolver, CosmosKeyCredential cosmosKeyCredential, boolean sessionCapturingOverride, - boolean connectionSharingAcrossClientsEnabled) { - this(serviceEndpoint, masterKeyOrResourceToken, permissionFeed, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential, sessionCapturingOverride, connectionSharingAcrossClientsEnabled); + boolean connectionSharingAcrossClientsEnabled, + boolean contentResponseOnWriteEnabled) { + this(serviceEndpoint, masterKeyOrResourceToken, permissionFeed, connectionPolicy, consistencyLevel, configs, + cosmosKeyCredential, sessionCapturingOverride, connectionSharingAcrossClientsEnabled, contentResponseOnWriteEnabled); this.cosmosAuthorizationTokenResolver = cosmosAuthorizationTokenResolver; } @@ -144,8 +149,10 @@ private RxDocumentClientImpl(URI serviceEndpoint, Configs configs, CosmosKeyCredential cosmosKeyCredential, boolean sessionCapturingOverrideEnabled, - boolean connectionSharingAcrossClientsEnabled) { - this(serviceEndpoint, masterKeyOrResourceToken, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential, sessionCapturingOverrideEnabled, connectionSharingAcrossClientsEnabled); + boolean connectionSharingAcrossClientsEnabled, + boolean contentResponseOnWriteEnabled) { + this(serviceEndpoint, masterKeyOrResourceToken, connectionPolicy, consistencyLevel, configs, + cosmosKeyCredential, sessionCapturingOverrideEnabled, connectionSharingAcrossClientsEnabled, contentResponseOnWriteEnabled); if (permissionFeed != null && permissionFeed.size() > 0) { this.resourceTokensMap = new HashMap<>(); for (Permission permission : permissionFeed) { @@ -195,7 +202,8 @@ private RxDocumentClientImpl(URI serviceEndpoint, Configs configs, CosmosKeyCredential cosmosKeyCredential, boolean sessionCapturingOverrideEnabled, - boolean connectionSharingAcrossClientsEnabled) { + boolean connectionSharingAcrossClientsEnabled, + boolean contentResponseOnWriteEnabled) { logger.info( "Initializing DocumentClient with" @@ -207,6 +215,7 @@ private RxDocumentClientImpl(URI serviceEndpoint, this.masterKeyOrResourceToken = masterKeyOrResourceToken; this.serviceEndpoint = serviceEndpoint; this.cosmosKeyCredential = cosmosKeyCredential; + this.contentResponseOnWriteEnabled = contentResponseOnWriteEnabled; if (this.cosmosKeyCredential != null) { hasAuthKeyResourceToken = false; @@ -416,7 +425,7 @@ private Mono> createDatabaseInternal(Database databas logger.debug("Creating a Database. id: [{}]", database.getId()); validateResource(database); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.Database, OperationType.Create); ZonedDateTime serializationStartTimeUTC = ZonedDateTime.now(ZoneOffset.UTC); ByteBuffer byteBuffer = ModelBridgeInternal.serializeJsonToByteBuffer(database); ZonedDateTime serializationEndTimeUTC = ZonedDateTime.now(ZoneOffset.UTC); @@ -458,7 +467,7 @@ private Mono> deleteDatabaseInternal(String databaseL logger.debug("Deleting a Database. databaseLink: [{}]", databaseLink); String path = Utils.joinPath(databaseLink, null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.Database, OperationType.Delete); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Delete, ResourceType.Database, path, requestHeaders, options); @@ -487,7 +496,7 @@ private Mono> readDatabaseInternal(String databaseLin logger.debug("Reading a Database. databaseLink: [{}]", databaseLink); String path = Utils.joinPath(databaseLink, null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.Database, OperationType.Read); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Read, ResourceType.Database, path, requestHeaders, options); @@ -593,7 +602,7 @@ private Mono> createCollectionInternal(Stri validateResource(collection); String path = Utils.joinPath(databaseLink, Paths.COLLECTIONS_PATH_SEGMENT); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.DocumentCollection, OperationType.Create); ZonedDateTime serializationStartTimeUTC = ZonedDateTime.now(ZoneOffset.UTC); ByteBuffer byteBuffer = ModelBridgeInternal.serializeJsonToByteBuffer(collection); @@ -645,7 +654,7 @@ private Mono> replaceCollectionInternal(Doc validateResource(collection); String path = Utils.joinPath(collection.getSelfLink(), null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.DocumentCollection, OperationType.Replace); ZonedDateTime serializationStartTimeUTC = ZonedDateTime.now(ZoneOffset.UTC); ByteBuffer byteBuffer = ModelBridgeInternal.serializeJsonToByteBuffer(collection); ZonedDateTime serializationEndTimeUTC = ZonedDateTime.now(ZoneOffset.UTC); @@ -699,7 +708,7 @@ private Mono> deleteCollectionInternal(Stri logger.debug("Deleting a Collection. collectionLink: [{}]", collectionLink); String path = Utils.joinPath(collectionLink, null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.DocumentCollection, OperationType.Delete); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Delete, ResourceType.DocumentCollection, path, requestHeaders, options); @@ -771,7 +780,7 @@ private Mono> readCollectionInternal(String logger.debug("Reading a Collection. collectionLink: [{}]", collectionLink); String path = Utils.joinPath(collectionLink, null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.DocumentCollection, OperationType.Read); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Read, ResourceType.DocumentCollection, path, requestHeaders, options); @@ -843,7 +852,7 @@ private static void validateResource(Resource resource) { } } - private Map getRequestHeaders(RequestOptions options) { + private Map getRequestHeaders(RequestOptions options, ResourceType resourceType, OperationType operationType) { Map headers = new HashMap<>(); if (this.useMultipleWriteLocations) { @@ -854,6 +863,11 @@ private Map getRequestHeaders(RequestOptions options) { headers.put(HttpConstants.HttpHeaders.CONSISTENCY_LEVEL, consistencyLevel.toString()); } + // If content response on write is not enabled, and operation is document write - then add minimal prefer header + if (resourceType.equals(ResourceType.Document) && operationType.isWriteOperation() && !this.contentResponseOnWriteEnabled) { + headers.put(HttpConstants.HttpHeaders.PREFER, HttpConstants.HeaderValues.PREFER_RETURN_MINIMAL); + } + if (options == null) { return headers; } @@ -1031,7 +1045,7 @@ private Mono getCreateDocumentRequest(DocumentClientRe SerializationDiagnosticsContext.SerializationType.ITEM_SERIALIZATION); String path = Utils.joinPath(documentCollectionLink, Paths.DOCUMENTS_PATH_SEGMENT); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.Document, operationType); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(operationType, ResourceType.Document, path, requestHeaders, options, content); @@ -1292,7 +1306,7 @@ private Mono> replaceDocumentInternal(String document logger.debug("Replacing a Document. documentLink: [{}]", documentLink); final String path = Utils.joinPath(documentLink, null); - final Map requestHeaders = getRequestHeaders(options); + final Map requestHeaders = getRequestHeaders(options, ResourceType.Document, OperationType.Replace); ZonedDateTime serializationStartTimeUTC = ZonedDateTime.now(ZoneOffset.UTC); ByteBuffer content = serializeJsonToByteBuffer(document); ZonedDateTime serializationEndTime = ZonedDateTime.now(ZoneOffset.UTC); @@ -1335,7 +1349,7 @@ private Mono> deleteDocumentInternal(String documentL logger.debug("Deleting a Document. documentLink: [{}]", documentLink); String path = Utils.joinPath(documentLink, null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.Document, OperationType.Delete); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Delete, ResourceType.Document, path, requestHeaders, options); if (retryPolicyInstance != null) { @@ -1371,7 +1385,7 @@ private Mono> readDocumentInternal(String documentLin logger.debug("Reading a Document. documentLink: [{}]", documentLink); String path = Utils.joinPath(documentLink, null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.Document, OperationType.Read); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Read, ResourceType.Document, path, requestHeaders, options); if (retryPolicyInstance != null) { @@ -1736,7 +1750,7 @@ private RxDocumentServiceRequest getStoredProcedureRequest(String collectionLink validateResource(storedProcedure); String path = Utils.joinPath(collectionLink, Paths.STORED_PROCEDURES_PATH_SEGMENT); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.StoredProcedure, operationType); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(operationType, ResourceType.StoredProcedure, path, storedProcedure, requestHeaders, options); @@ -1755,7 +1769,7 @@ private RxDocumentServiceRequest getUserDefinedFunctionRequest(String collection validateResource(udf); String path = Utils.joinPath(collectionLink, Paths.USER_DEFINED_FUNCTIONS_PATH_SEGMENT); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.UserDefinedFunction, operationType); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(operationType, ResourceType.UserDefinedFunction, path, udf, requestHeaders, options); @@ -1845,7 +1859,7 @@ private Mono> replaceStoredProcedureInternal(S RxDocumentClientImpl.validateResource(storedProcedure); String path = Utils.joinPath(storedProcedure.getSelfLink(), null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.StoredProcedure, OperationType.Replace); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Replace, ResourceType.StoredProcedure, path, storedProcedure, requestHeaders, options); @@ -1882,7 +1896,7 @@ private Mono> deleteStoredProcedureInternal(St logger.debug("Deleting a StoredProcedure. storedProcedureLink [{}]", storedProcedureLink); String path = Utils.joinPath(storedProcedureLink, null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.StoredProcedure, OperationType.Delete); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Delete, ResourceType.StoredProcedure, path, requestHeaders, options); @@ -1921,7 +1935,7 @@ private Mono> readStoredProcedureInternal(Stri logger.debug("Reading a StoredProcedure. storedProcedureLink [{}]", storedProcedureLink); String path = Utils.joinPath(storedProcedureLink, null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.StoredProcedure, OperationType.Read); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Read, ResourceType.StoredProcedure, path, requestHeaders, options); @@ -1982,7 +1996,7 @@ private Mono executeStoredProcedureInternal(String stor logger.debug("Executing a StoredProcedure. storedProcedureLink [{}]", storedProcedureLink); String path = Utils.joinPath(storedProcedureLink, null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.StoredProcedure, OperationType.ExecuteJavaScript); requestHeaders.put(HttpConstants.HttpHeaders.ACCEPT, RuntimeConstants.MediaTypes.JSON); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.ExecuteJavaScript, @@ -2069,7 +2083,7 @@ private RxDocumentServiceRequest getTriggerRequest(String collectionLink, Trigge RxDocumentClientImpl.validateResource(trigger); String path = Utils.joinPath(collectionLink, Paths.TRIGGERS_PATH_SEGMENT); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.Trigger, operationType); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(operationType, ResourceType.Trigger, path, trigger, requestHeaders, options); @@ -2094,7 +2108,7 @@ private Mono> replaceTriggerInternal(Trigger trigger, RxDocumentClientImpl.validateResource(trigger); String path = Utils.joinPath(trigger.getSelfLink(), null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.Trigger, OperationType.Replace); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Replace, ResourceType.Trigger, path, trigger, requestHeaders, options); @@ -2124,7 +2138,7 @@ private Mono> deleteTriggerInternal(String triggerLink logger.debug("Deleting a Trigger. triggerLink [{}]", triggerLink); String path = Utils.joinPath(triggerLink, null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.Trigger, OperationType.Delete); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Delete, ResourceType.Trigger, path, requestHeaders, options); @@ -2155,7 +2169,7 @@ private Mono> readTriggerInternal(String triggerLink, logger.debug("Reading a Trigger. triggerLink [{}]", triggerLink); String path = Utils.joinPath(triggerLink, null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.Trigger, OperationType.Read); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Read, ResourceType.Trigger, path, requestHeaders, options); @@ -2278,7 +2292,7 @@ private Mono> replaceUserDefinedFunctionIn validateResource(udf); String path = Utils.joinPath(udf.getSelfLink(), null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.UserDefinedFunction, OperationType.Replace); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Replace, ResourceType.UserDefinedFunction, path, udf, requestHeaders, options); @@ -2315,7 +2329,7 @@ private Mono> deleteUserDefinedFunctionInt logger.debug("Deleting a UserDefinedFunction. udfLink [{}]", udfLink); String path = Utils.joinPath(udfLink, null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.UserDefinedFunction, OperationType.Delete); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Delete, ResourceType.UserDefinedFunction, path, requestHeaders, options); @@ -2352,7 +2366,7 @@ private Mono> readUserDefinedFunctionInter logger.debug("Reading a UserDefinedFunction. udfLink [{}]", udfLink); String path = Utils.joinPath(udfLink, null); - Map requestHeaders = this.getRequestHeaders(options); + Map requestHeaders = this.getRequestHeaders(options, ResourceType.UserDefinedFunction, OperationType.Read); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Read, ResourceType.UserDefinedFunction, path, requestHeaders, options); @@ -2408,7 +2422,7 @@ private Mono> readConflictInternal(String conflictLin logger.debug("Reading a Conflict. conflictLink [{}]", conflictLink); String path = Utils.joinPath(conflictLink, null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.Conflict, OperationType.Read); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Read, ResourceType.Conflict, path, requestHeaders, options); @@ -2466,7 +2480,7 @@ private Mono> deleteConflictInternal(String conflictL logger.debug("Deleting a Conflict. conflictLink [{}]", conflictLink); String path = Utils.joinPath(conflictLink, null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.Conflict, OperationType.Delete); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Delete, ResourceType.Conflict, path, requestHeaders, options); @@ -2538,7 +2552,7 @@ private RxDocumentServiceRequest getUserRequest(String databaseLink, User user, RxDocumentClientImpl.validateResource(user); String path = Utils.joinPath(databaseLink, Paths.USERS_PATH_SEGMENT); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.User, operationType); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(operationType, ResourceType.User, path, user, requestHeaders, options); @@ -2560,7 +2574,7 @@ private Mono> replaceUserInternal(User user, RequestOptio RxDocumentClientImpl.validateResource(user); String path = Utils.joinPath(user.getSelfLink(), null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.User, OperationType.Replace); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Replace, ResourceType.User, path, user, requestHeaders, options); if (retryPolicyInstance != null) { @@ -2590,7 +2604,7 @@ private Mono> deleteUserInternal(String userLink, Request } logger.debug("Deleting a User. userLink [{}]", userLink); String path = Utils.joinPath(userLink, null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.User, OperationType.Delete); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Delete, ResourceType.User, path, requestHeaders, options); @@ -2618,7 +2632,7 @@ private Mono> readUserInternal(String userLink, RequestOp } logger.debug("Reading a User. userLink [{}]", userLink); String path = Utils.joinPath(userLink, null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.User, OperationType.Read); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Read, ResourceType.User, path, requestHeaders, options); @@ -2715,7 +2729,7 @@ private RxDocumentServiceRequest getPermissionRequest(String userLink, Permissio RxDocumentClientImpl.validateResource(permission); String path = Utils.joinPath(userLink, Paths.PERMISSIONS_PATH_SEGMENT); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.Permission, operationType); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(operationType, ResourceType.Permission, path, permission, requestHeaders, options); @@ -2737,7 +2751,7 @@ private Mono> replacePermissionInternal(Permission RxDocumentClientImpl.validateResource(permission); String path = Utils.joinPath(permission.getSelfLink(), null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.Permission, OperationType.Replace); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Replace, ResourceType.Permission, path, permission, requestHeaders, options); @@ -2768,7 +2782,7 @@ private Mono> deletePermissionInternal(String permi } logger.debug("Deleting a Permission. permissionLink [{}]", permissionLink); String path = Utils.joinPath(permissionLink, null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.Permission, OperationType.Delete); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Delete, ResourceType.Permission, path, requestHeaders, options); @@ -2797,7 +2811,7 @@ private Mono> readPermissionInternal(String permiss } logger.debug("Reading a Permission. permissionLink [{}]", permissionLink); String path = Utils.joinPath(permissionLink, null); - Map requestHeaders = getRequestHeaders(options); + Map requestHeaders = getRequestHeaders(options, ResourceType.Permission, OperationType.Read); RxDocumentServiceRequest request = RxDocumentServiceRequest.create(OperationType.Read, ResourceType.Permission, path, requestHeaders, options); diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentServiceRequest.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentServiceRequest.java index f5287a9b82a37..24ae1acca4b18 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentServiceRequest.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentServiceRequest.java @@ -26,8 +26,6 @@ * This is core Transport/Connection agnostic request to the Azure Cosmos DB database service. */ public class RxDocumentServiceRequest implements Cloneable { - private static final char PREFER_HEADER_SEPERATOR = ';'; - private static final String PREFER_HEADER_VALUE_FORMAT = "%s=%s"; public volatile boolean forcePartitionKeyRangeRefresh; public volatile boolean forceCollectionRoutingMapRefresh; @@ -969,17 +967,6 @@ public boolean isValidAddress(ResourceType resourceType) { } } - public void addPreferHeader(String preferHeaderName, String preferHeaderValue) { - String headerToAdd = String.format(PREFER_HEADER_VALUE_FORMAT, preferHeaderName, preferHeaderValue); - String preferHeader = this.headers.get(HttpConstants.HttpHeaders.PREFER); - if(StringUtils.isNotEmpty(preferHeader)) { - preferHeader += PREFER_HEADER_SEPERATOR + headerToAdd; - } else { - preferHeader = headerToAdd; - } - this.headers.put(HttpConstants.HttpHeaders.PREFER, preferHeader); - } - public static RxDocumentServiceRequest createFromResource(RxDocumentServiceRequest request, Resource modifiedResource) { RxDocumentServiceRequest modifiedRequest; if (!request.getIsNameBased()) { diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/HttpTransportClient.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/HttpTransportClient.java index 04bb13d98a68d..9ec2da929bd3d 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/HttpTransportClient.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/HttpTransportClient.java @@ -84,7 +84,7 @@ public HttpTransportClient(Configs configs, Duration requestTimeout, UserAgentCo // Set requested API version header for version enforcement. this.defaultHeaders.put(HttpConstants.HttpHeaders.VERSION, HttpConstants.Versions.CURRENT_VERSION); - this.defaultHeaders.put(HttpConstants.HttpHeaders.CACHE_CONTROL, HttpConstants.HeaderValues.NoCache); + this.defaultHeaders.put(HttpConstants.HttpHeaders.CACHE_CONTROL, HttpConstants.HeaderValues.NO_CACHE); if (userAgent == null) { userAgent = new UserAgentContainer(); diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdConstants.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdConstants.java index 86849db8c6daf..951747ddd83ac 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdConstants.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdConstants.java @@ -572,7 +572,8 @@ public enum RntbdRequestHeader implements RntbdHeader { ContentSerializationFormat((short) 0x0065, RntbdTokenType.Byte, false), AllowTentativeWrites((short) 0x0066, RntbdTokenType.Byte, false), IsUserRequest((short) 0x0067, RntbdTokenType.Byte, false), - SharedOfferThroughput((short) 0x0068, RntbdTokenType.ULong, false); + SharedOfferThroughput((short) 0x0068, RntbdTokenType.ULong, false), + ReturnPreference((short) 0x0082, RntbdTokenType.Byte, false); public static final ImmutableMap map; public static final ImmutableSet set = Sets.immutableEnumSet(EnumSet.allOf(RntbdRequestHeader.class)); diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdRequestHeaders.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdRequestHeaders.java index ccf5a8b6b64f7..ccadaf602b041 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdRequestHeaders.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdRequestHeaders.java @@ -17,7 +17,6 @@ import com.azure.cosmos.implementation.RemoteStorageType; import com.azure.cosmos.implementation.ResourceId; import com.azure.cosmos.implementation.RxDocumentServiceRequest; -import com.azure.cosmos.models.IndexingDirective; import com.fasterxml.jackson.annotation.JsonFilter; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; @@ -29,6 +28,7 @@ import java.util.function.Supplier; import static com.azure.cosmos.implementation.HttpConstants.HttpHeaders; +import static com.azure.cosmos.implementation.HttpConstants.HeaderValues; import static com.azure.cosmos.implementation.directconnectivity.WFConstants.BackendHeaders; import static com.azure.cosmos.implementation.directconnectivity.rntbd.RntbdConstants.RntbdConsistencyLevel; import static com.azure.cosmos.implementation.directconnectivity.rntbd.RntbdConstants.RntbdContentSerializationFormat; @@ -112,6 +112,7 @@ final class RntbdRequestHeaders extends RntbdTokenStream { this.addStartAndEndKeys(headers); this.addSupportSpatialLegacyCoordinates(headers); this.addUsePolygonsSmallerThanAHemisphere(headers); + this.addReturnPreference(headers); // Normal headers (Strings, Ints, Longs, etc.) @@ -279,6 +280,10 @@ private RntbdToken getEffectivePartitionKey() { return this.get(RntbdRequestHeader.EffectivePartitionKey); } + private RntbdToken getReturnPreference() { + return this.get(RntbdRequestHeader.ReturnPreference); + } + private RntbdToken getEmitVerboseTracesInQuery() { return this.get(RntbdRequestHeader.EmitVerboseTracesInQuery); } @@ -1159,6 +1164,13 @@ private void addUsePolygonsSmallerThanAHemisphere(final Map head } } + private void addReturnPreference(final Map headers) { + final String value = headers.get(HttpHeaders.PREFER); + if (StringUtils.isNotEmpty(value) && value.contains(HeaderValues.PREFER_RETURN_MINIMAL)) { + this.getReturnPreference().setValue(true); + } + } + private void fillTokenFromHeader(final Map headers, final Supplier supplier, final String name) { final String value = headers.get(name); diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosAsyncItemResponse.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosAsyncItemResponse.java index 56529eaf98ee1..a919a6a835543 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosAsyncItemResponse.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosAsyncItemResponse.java @@ -179,4 +179,15 @@ public CosmosResponseDiagnostics getResponseDiagnostics() { public Duration getRequestLatency() { return resourceResponse.getRequestLatency(); } + + /** + * Gets the ETag from the response headers. + * + * Null in case of delete operation. + * + * @return ETag + */ + public String getETag() { + return resourceResponse.getETag(); + } } diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosItemResponse.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosItemResponse.java index b1bde4ac913ac..13063cdb23b72 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosItemResponse.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosItemResponse.java @@ -121,4 +121,14 @@ public Duration getRequestLatency() { return responseWrapper.getRequestLatency(); } + /** + * Gets the ETag from the response headers. + * + * Null in case of delete operation. + * + * @return ETag + */ + public String getETag() { + return responseWrapper.getETag(); + } } diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/ClientUnderTestBuilder.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/ClientUnderTestBuilder.java index 107a9286372be..60d9aefe99202 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/ClientUnderTestBuilder.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/ClientUnderTestBuilder.java @@ -17,6 +17,7 @@ public ClientUnderTestBuilder(CosmosClientBuilder builder) { this.key(builder.getKey()); this.endpoint(builder.getEndpoint()); this.keyCredential(builder.getKeyCredential()); + this.contentResponseOnWriteEnabled(builder.isContentResponseOnWriteEnabled()); } @Override @@ -29,7 +30,8 @@ public CosmosAsyncClient buildAsyncClient() { this.getConnectionPolicy(), this.getConsistencyLevel(), this.configs(), - this.getKeyCredential()); + this.getKeyCredential(), + this.isContentResponseOnWriteEnabled()); } catch (URISyntaxException e) { throw new IllegalArgumentException(e.getMessage()); } diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosContainerContentResponseOnWriteTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosContainerContentResponseOnWriteTest.java new file mode 100644 index 0000000000000..da23f418b482d --- /dev/null +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosContainerContentResponseOnWriteTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + * + */ + +package com.azure.cosmos; + +import com.azure.cosmos.models.CosmosContainerProperties; +import com.azure.cosmos.models.CosmosContainerRequestOptions; +import com.azure.cosmos.models.CosmosContainerResponse; +import com.azure.cosmos.models.IndexingMode; +import com.azure.cosmos.models.IndexingPolicy; +import com.azure.cosmos.models.PartitionKeyDefinition; +import com.azure.cosmos.rx.TestSuiteBase; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CosmosContainerContentResponseOnWriteTest extends TestSuiteBase { + + private final String preExistingDatabaseId = CosmosDatabaseForTest.generateId(); + private CosmosClient client; + private CosmosDatabase createdDatabase; + + // Currently Gateway and Direct TCP support minimal response feature. + @Factory(dataProvider = "clientBuildersWithDirectTcpWithContentResponseOnWriteDisabled") + public CosmosContainerContentResponseOnWriteTest(CosmosClientBuilder clientBuilder) { + super(clientBuilder); + } + + @BeforeClass(groups = {"emulator"}, timeOut = SETUP_TIMEOUT) + public void beforeClass() { + assertThat(this.client).isNull(); + this.client = getClientBuilder().buildClient(); + createdDatabase = createSyncDatabase(client, preExistingDatabaseId); + } + + @AfterClass(groups = {"emulator"}, timeOut = SHUTDOWN_TIMEOUT, alwaysRun = true) + public void afterClass() { + safeDeleteSyncDatabase(createdDatabase); + safeCloseSyncClient(client); + } + + @Test(groups = { "emulator" }, timeOut = TIMEOUT) + public void createContainer_withContentResponseOnWriteDisabled() throws Exception { + String collectionName = UUID.randomUUID().toString(); + CosmosContainerProperties containerProperties = getCollectionDefinition(collectionName); + + CosmosContainerResponse containerResponse = createdDatabase.createContainer(containerProperties); + assertThat(containerResponse.getRequestCharge()).isGreaterThan(0); + validateContainerResponse(containerProperties, containerResponse); + } + + @Test(groups = { "emulator" }, timeOut = TIMEOUT) + public void readContainer_withContentResponseOnWriteDisabled() throws Exception { + String collectionName = UUID.randomUUID().toString(); + CosmosContainerProperties containerProperties = getCollectionDefinition(collectionName); + CosmosContainerRequestOptions options = new CosmosContainerRequestOptions(); + + CosmosContainerResponse containerResponse = createdDatabase.createContainer(containerProperties); + + CosmosContainer syncContainer = createdDatabase.getContainer(collectionName); + + CosmosContainerResponse read = syncContainer.read(); + validateContainerResponse(containerProperties, read); + + CosmosContainerResponse read1 = syncContainer.read(options); + validateContainerResponse(containerProperties, read1); + } + + @Test(groups = { "emulator" }, timeOut = TIMEOUT) + public void replaceContainer_withContentResponseOnWriteDisabled() throws Exception { + + String collectionName = UUID.randomUUID().toString(); + CosmosContainerProperties containerProperties = getCollectionDefinition(collectionName); + CosmosContainerRequestOptions options = new CosmosContainerRequestOptions(); + + CosmosContainerResponse containerResponse = createdDatabase.createContainer(containerProperties); + validateContainerResponse(containerProperties, containerResponse); + + assertThat(containerResponse.getProperties().getIndexingPolicy().getIndexingMode()).isEqualTo(IndexingMode.CONSISTENT); + + CosmosContainerResponse replaceResponse = containerResponse.getContainer() + .replace(containerResponse.getProperties().setIndexingPolicy( + new IndexingPolicy().setIndexingMode(IndexingMode.LAZY))); + assertThat(replaceResponse.getProperties().getIndexingPolicy().getIndexingMode()) + .isEqualTo(IndexingMode.LAZY); + + CosmosContainerResponse replaceResponse1 = containerResponse.getContainer() + .replace(containerResponse.getProperties().setIndexingPolicy( + new IndexingPolicy().setIndexingMode(IndexingMode.CONSISTENT)), + options); + assertThat(replaceResponse1.getProperties().getIndexingPolicy().getIndexingMode()) + .isEqualTo(IndexingMode.CONSISTENT); + + } + + private CosmosContainerProperties getCollectionDefinition(String collectionName) { + PartitionKeyDefinition partitionKeyDef = new PartitionKeyDefinition(); + ArrayList paths = new ArrayList(); + paths.add("/mypk"); + partitionKeyDef.setPaths(paths); + + return new CosmosContainerProperties( + collectionName, + partitionKeyDef); + } + + private void validateContainerResponse(CosmosContainerProperties containerProperties, + CosmosContainerResponse createResponse) { + // Basic validation + assertThat(createResponse.getProperties().getId()).isNotNull(); + assertThat(createResponse.getProperties().getId()) + .as("check Resource Id") + .isEqualTo(containerProperties.getId()); + + } + +} diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosDatabaseContentResponseOnWriteTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosDatabaseContentResponseOnWriteTest.java new file mode 100644 index 0000000000000..e4264996bdacb --- /dev/null +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosDatabaseContentResponseOnWriteTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + * + */ + +package com.azure.cosmos; + +import com.azure.cosmos.models.CosmosDatabaseProperties; +import com.azure.cosmos.models.CosmosDatabaseRequestOptions; +import com.azure.cosmos.models.CosmosDatabaseResponse; +import com.azure.cosmos.rx.TestSuiteBase; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CosmosDatabaseContentResponseOnWriteTest extends TestSuiteBase { + + private final String preExistingDatabaseId = CosmosDatabaseForTest.generateId(); + private final List databases = new ArrayList<>(); + private CosmosClient client; + private CosmosDatabase createdDatabase; + + // Currently Gateway and Direct TCP support minimal response feature. + @Factory(dataProvider = "clientBuildersWithDirectTcpWithContentResponseOnWriteDisabled") + public CosmosDatabaseContentResponseOnWriteTest(CosmosClientBuilder clientBuilder) { + super(clientBuilder); + } + + @BeforeClass(groups = {"emulator"}, timeOut = SETUP_TIMEOUT) + public void beforeClass() { + assertThat(this.client).isNull(); + this.client = getClientBuilder().buildClient(); + createdDatabase = createSyncDatabase(client, preExistingDatabaseId); + } + + @AfterClass(groups = {"emulator"}, timeOut = SHUTDOWN_TIMEOUT, alwaysRun = true) + public void afterClass() { + safeDeleteSyncDatabase(createdDatabase); + for (String dbId : databases) { + safeDeleteSyncDatabase(client.getDatabase(dbId)); + } + safeCloseSyncClient(client); + } + + @Test(groups = {"emulator"}, timeOut = TIMEOUT) + public void createDatabase_withContentResponseOnWriteDisabled() throws CosmosClientException { + CosmosDatabaseProperties databaseDefinition = new CosmosDatabaseProperties(CosmosDatabaseForTest.generateId()); + databases.add(databaseDefinition.getId()); + + CosmosDatabaseResponse createResponse = client.createDatabase(databaseDefinition, new CosmosDatabaseRequestOptions()); + + validateDatabaseResponse(databaseDefinition, createResponse); + } + + @Test(groups = {"emulator"}, timeOut = TIMEOUT) + public void readDatabase_withContentResponseOnWriteDisabled() throws Exception { + CosmosDatabase database = client.getDatabase(createdDatabase.getId()); + CosmosDatabaseProperties properties = new CosmosDatabaseProperties(createdDatabase.getId()); + CosmosDatabaseRequestOptions options = new CosmosDatabaseRequestOptions(); + + CosmosDatabaseResponse read = database.read(); + validateDatabaseResponse(properties, read); + + CosmosDatabaseResponse read1 = database.read(options); + validateDatabaseResponse(properties, read1); + } + + private void validateDatabaseResponse(CosmosDatabaseProperties databaseDefinition, CosmosDatabaseResponse createResponse) { + // Basic validation + assertThat(createResponse.getProperties().getId()).isNotNull(); + assertThat(createResponse.getProperties().getId()) + .as("check Resource Id") + .isEqualTo(databaseDefinition.getId()); + + } + +} diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosItemContentResponseOnWriteTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosItemContentResponseOnWriteTest.java new file mode 100644 index 0000000000000..a291d7a2f3ab0 --- /dev/null +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosItemContentResponseOnWriteTest.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + * + */ + +package com.azure.cosmos; + +import com.azure.cosmos.implementation.CosmosItemProperties; +import com.azure.cosmos.models.CosmosContainerProperties; +import com.azure.cosmos.models.CosmosItemRequestOptions; +import com.azure.cosmos.models.CosmosItemResponse; +import com.azure.cosmos.models.ModelBridgeInternal; +import com.azure.cosmos.models.PartitionKey; +import com.azure.cosmos.models.PartitionKeyDefinition; +import com.azure.cosmos.rx.TestSuiteBase; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CosmosItemContentResponseOnWriteTest extends TestSuiteBase { + + private CosmosClient client; + private CosmosContainer container; + + // Currently Gateway and Direct TCP support minimal response feature. + @Factory(dataProvider = "clientBuildersWithDirectTcpWithContentResponseOnWriteDisabled") + public CosmosItemContentResponseOnWriteTest(CosmosClientBuilder clientBuilder) { + super(clientBuilder); + } + + @BeforeClass(groups = {"simple"}, timeOut = SETUP_TIMEOUT) + public void beforeClass() { + assertThat(this.client).isNull(); + this.client = getClientBuilder().buildClient(); + CosmosAsyncContainer asyncContainer = getSharedMultiPartitionCosmosContainer(this.client.asyncClient()); + container = client.getDatabase(asyncContainer.getDatabase().getId()).getContainer(asyncContainer.getId()); + } + + @AfterClass(groups = {"simple"}, timeOut = SHUTDOWN_TIMEOUT, alwaysRun = true) + public void afterClass() { + assertThat(this.client).isNotNull(); + this.client.close(); + } + + @Test(groups = { "simple" }, timeOut = TIMEOUT) + public void createItem_withContentResponseOnWriteDisabled() throws Exception { + CosmosItemProperties properties = getDocumentDefinition(UUID.randomUUID().toString()); + CosmosItemResponse itemResponse = container.createItem(properties); + assertThat(itemResponse.getRequestCharge()).isGreaterThan(0); + validateMinimalItemResponse(properties, itemResponse, true); + + properties = getDocumentDefinition(UUID.randomUUID().toString()); + CosmosItemResponse itemResponse1 = container.createItem(properties, new CosmosItemRequestOptions()); + validateMinimalItemResponse(properties, itemResponse1, true); + } + + @Test(groups = { "simple" }, timeOut = TIMEOUT) + public void readItem_withContentResponseOnWriteDisabled() throws Exception { + CosmosItemProperties properties = getDocumentDefinition(UUID.randomUUID().toString()); + CosmosItemResponse itemResponse = container.createItem(properties); + + CosmosItemResponse readResponse1 = container.readItem(properties.getId(), + new PartitionKey(ModelBridgeInternal.getObjectFromJsonSerializable(properties, "mypk")), + new CosmosItemRequestOptions(), + CosmosItemProperties.class); + // Read item should have full response irrespective of the flag - contentResponseOnWriteEnabled + validateItemResponse(properties, readResponse1); + + } + + @Test(groups = { "simple" }, timeOut = TIMEOUT) + public void replaceItem_withContentResponseOnWriteDisabled() throws Exception{ + CosmosItemProperties properties = getDocumentDefinition(UUID.randomUUID().toString()); + CosmosItemResponse itemResponse = container.createItem(properties); + + validateMinimalItemResponse(properties, itemResponse, true); + String newPropValue = UUID.randomUUID().toString(); + BridgeInternal.setProperty(properties, "newProp", newPropValue); + CosmosItemRequestOptions options = new CosmosItemRequestOptions(); + ModelBridgeInternal.setPartitionKey(options, new PartitionKey(ModelBridgeInternal.getObjectFromJsonSerializable(properties, "mypk"))); + // replace document + CosmosItemResponse replace = container.replaceItem(properties, + properties.getId(), + new PartitionKey(ModelBridgeInternal.getObjectFromJsonSerializable(properties, "mypk")), + options); + validateMinimalItemResponse(properties, replace, true); + } + + @Test(groups = { "simple" }, timeOut = TIMEOUT) + public void deleteItem_withContentResponseOnWriteDisabled() throws Exception { + CosmosItemProperties properties = getDocumentDefinition(UUID.randomUUID().toString()); + CosmosItemResponse itemResponse = container.createItem(properties); + CosmosItemRequestOptions options = new CosmosItemRequestOptions(); + + CosmosItemResponse deleteResponse = container.deleteItem(properties.getId(), + new PartitionKey(ModelBridgeInternal.getObjectFromJsonSerializable(properties, "mypk")), + options); + assertThat(deleteResponse.getStatusCode()).isEqualTo(204); + validateMinimalItemResponse(properties, deleteResponse, false); + } + + private CosmosContainerProperties getCollectionDefinition(String collectionName) { + PartitionKeyDefinition partitionKeyDef = new PartitionKeyDefinition(); + ArrayList paths = new ArrayList(); + paths.add("/mypk"); + partitionKeyDef.setPaths(paths); + + return new CosmosContainerProperties( + collectionName, + partitionKeyDef); + } + + private CosmosItemProperties getDocumentDefinition(String documentId) { + final String uuid = UUID.randomUUID().toString(); + final CosmosItemProperties properties = + new CosmosItemProperties(String.format("{ " + + "\"id\": \"%s\", " + + "\"mypk\": \"%s\", " + + "\"sgmts\": [[6519456, 1471916863], [2498434, 1455671440]]" + + "}" + , documentId, uuid)); + return properties; + } + + private void validateItemResponse(CosmosItemProperties containerProperties, + CosmosItemResponse createResponse) { + // Basic validation + assertThat(BridgeInternal.getProperties(createResponse).getId()).isNotNull(); + assertThat(BridgeInternal.getProperties(createResponse).getId()) + .as("check Resource Id") + .isEqualTo(containerProperties.getId()); + } + + private void validateMinimalItemResponse(CosmosItemProperties containerProperties, + CosmosItemResponse createResponse, boolean withETag) { + // Basic validation + assertThat(BridgeInternal.getProperties(createResponse)).isNull(); + assertThat(createResponse.getStatusCode()).isNotNull(); + assertThat(createResponse.getResponseHeaders()).isNotEmpty(); + assertThat(createResponse.getRequestCharge()).isGreaterThan(0); + if (withETag) { + assertThat(createResponse.getETag()).isNotEmpty(); + } else { + assertThat(createResponse.getETag()).isNull(); + } + } + +} diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseDiagnosticsTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseDiagnosticsTest.java index 472a1ff27f6fa..de28d0cab4b6d 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseDiagnosticsTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseDiagnosticsTest.java @@ -9,7 +9,6 @@ import com.azure.cosmos.implementation.ResourceType; import com.azure.cosmos.implementation.RxDocumentServiceRequest; import com.azure.cosmos.implementation.TestConfigurations; -import com.azure.cosmos.models.CosmosContainerProperties; import com.azure.cosmos.models.CosmosContainerResponse; import com.azure.cosmos.models.CosmosDatabaseResponse; import com.azure.cosmos.models.CosmosItemRequestOptions; @@ -44,7 +43,8 @@ public void beforeClass() throws Exception { assertThat(this.gatewayClient).isNull(); cosmosClientBuilder = new CosmosClientBuilder() .endpoint(TestConfigurations.HOST) - .key(TestConfigurations.MASTER_KEY); + .key(TestConfigurations.MASTER_KEY) + .contentResponseOnWriteEnabled(true); ConnectionPolicy connectionPolicy = new ConnectionPolicy(); connectionPolicy.setConnectionMode(ConnectionMode.GATEWAY); gatewayClient = cosmosClientBuilder.connectionPolicy(connectionPolicy).buildClient(); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTests1.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTests1.java index 76d8bc40a3fa9..2cbb77032da92 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTests1.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTests1.java @@ -32,12 +32,12 @@ public void validateStrongConsistencyOnSyncReplication() throws Exception { this.writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.STRONG).build(); + .withConsistencyLevel(ConsistencyLevel.STRONG).withContentResponseOnWriteEnabled(true).build(); this.readClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.STRONG).build(); + .withConsistencyLevel(ConsistencyLevel.STRONG).withContentResponseOnWriteEnabled(true).build(); User userDefinition = getUserDefinition(); userDefinition.setId(userDefinition.getId() + "validateStrongConsistencyOnSyncReplication"); User user = safeCreateUser(this.initClient, createdDatabase.getId(), userDefinition); @@ -54,12 +54,12 @@ public void validateConsistentLSNForDirectTCPClient() { this.writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .build(); + .withContentResponseOnWriteEnabled(true).build(); this.readClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .build(); + .withContentResponseOnWriteEnabled(true).build(); validateConsistentLSN(); } @@ -70,12 +70,12 @@ public void validateConsistentLSNForDirectHttpsClient() { this.writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .build(); + .withContentResponseOnWriteEnabled(true).build(); this.readClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .build(); + .withContentResponseOnWriteEnabled(true).build(); validateConsistentLSN(); } @@ -88,12 +88,12 @@ public void validateConsistentLSNAndQuorumAckedLSNForDirectTCPClient() { this.writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .build(); + .withContentResponseOnWriteEnabled(true).build(); this.readClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .build(); + .withContentResponseOnWriteEnabled(true).build(); validateConsistentLSNAndQuorumAckedLSN(); } @@ -122,12 +122,12 @@ public void validateConsistentLSNAndQuorumAckedLSNForDirectHttpsClient() { this.writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .build(); + .withContentResponseOnWriteEnabled(true).build(); this.readClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .build(); + .withContentResponseOnWriteEnabled(true).build(); validateConsistentLSNAndQuorumAckedLSN(); } @@ -165,22 +165,17 @@ public void validateConsistentPrefixOnSyncReplication() throws InterruptedExcept this.writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.BOUNDED_STALENESS).build(); + .withConsistencyLevel(ConsistencyLevel.BOUNDED_STALENESS).withContentResponseOnWriteEnabled(true).build(); this.readClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.BOUNDED_STALENESS).build(); + .withConsistencyLevel(ConsistencyLevel.BOUNDED_STALENESS).withContentResponseOnWriteEnabled(true).build(); User user = safeCreateUser(this.initClient, createdDatabase.getId(), getUserDefinition()); boolean readLagging = validateConsistentPrefix(user); assertThat(readLagging).isFalse(); } - // TODO (DANOBLE) ConsistencyTests1::validateConsistentPrefixOnAsyncReplication test fails - // This test requires BoundedStaleness and fails due to timeouts when run in Direct TCP mode. - // This test should be enabled when we are ready to address our BoundedStaleness consistency issues. - // see https://github.com/Azure/azure-sdk-for-java/issues/6378 - @Ignore @Test(groups = {"direct"}, timeOut = CONSISTENCY_TEST_TIMEOUT) public void validateConsistentPrefixOnAsyncReplication() throws InterruptedException { if (!(TestConfigurations.CONSISTENCY.equalsIgnoreCase(ConsistencyLevel.STRONG.toString()) || TestConfigurations.CONSISTENCY.equalsIgnoreCase(ConsistencyLevel.BOUNDED_STALENESS.toString()))) { @@ -193,13 +188,13 @@ public void validateConsistentPrefixOnAsyncReplication() throws InterruptedExcep .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.BOUNDED_STALENESS) - .build(); + .withContentResponseOnWriteEnabled(true).build(); this.readClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.BOUNDED_STALENESS) - .build(); + .withContentResponseOnWriteEnabled(true).build(); Document documentDefinition = getDocumentDefinition(); Document document = createDocument(this.initClient, createdDatabase.getId(), createdCollection.getId(), documentDefinition); boolean readLagging = validateConsistentPrefix(document); @@ -245,7 +240,7 @@ private void validateSubstatusCodeOnNotFoundExceptionInSessionReadAsync(boolean .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.SESSION) - .build(); + .withContentResponseOnWriteEnabled(true).build(); try { DocumentCollection documentCollection = new DocumentCollection(); documentCollection.setId(UUID.randomUUID().toString()); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTests2.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTests2.java index ca39e63be90c8..6bfd2e1223354 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTests2.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTests2.java @@ -33,12 +33,12 @@ public void validateReadSessionOnAsyncReplication() throws InterruptedException this.writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION).build(); + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true).build(); this.readClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION).build(); + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true).build(); Document document = this.initClient.createDocument(createdCollection.getSelfLink(), getDocumentDefinition(), null, false).block().getResource(); @@ -54,12 +54,12 @@ public void validateWriteSessionOnAsyncReplication() throws InterruptedException this.writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION).build(); + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true).build(); this.readClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION).build(); + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true).build(); Document document = this.initClient.createDocument(createdCollection.getSelfLink(), getDocumentDefinition(), null, false).block().getResource(); @@ -161,13 +161,13 @@ public void validateNoChargeOnFailedSessionRead() throws Exception { RxDocumentClientImpl writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); // Client locked to replica for pause/resume RxDocumentClientImpl readSecondaryClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); try { // CREATE collection @@ -221,7 +221,7 @@ public void validateSessionTokenAsync() { RxDocumentClientImpl client = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); try { diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTestsBase.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTestsBase.java index 7cc07073fc08a..f1780f389f92e 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTestsBase.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ConsistencyTestsBase.java @@ -124,12 +124,12 @@ void validateStrongConsistencyOnAsyncReplication(boolean useGateway) throws Inte this.writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.STRONG).build(); + .withConsistencyLevel(ConsistencyLevel.STRONG).withContentResponseOnWriteEnabled(true).build(); this.readClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.STRONG).build(); + .withConsistencyLevel(ConsistencyLevel.STRONG).withContentResponseOnWriteEnabled(true).build(); Document documentDefinition = getDocumentDefinition(); Document document = createDocument(this.writeClient, createdDatabase.getId(), createdCollection.getId(), documentDefinition); @@ -164,7 +164,7 @@ void validateSessionContainerAfterCollectionCreateReplace(boolean useGateway) { RxDocumentClientImpl writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION).build(); + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true).build(); try { PartitionKeyDefinition partitionKey = new PartitionKeyDefinition(); @@ -371,12 +371,12 @@ void validateSessionContainerAfterCollectionDeletion(boolean useGateway) throws RxDocumentClientImpl client1 = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); RxDocumentClientImpl client2 = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); String collectionId = UUID.randomUUID().toString(); @@ -502,12 +502,12 @@ void validateSessionTokenWithPreConditionFailure(boolean useGateway) throws Exce RxDocumentClientImpl writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); RxDocumentClientImpl validationClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); try { // write a document, and upsert to it to update etag. @@ -546,12 +546,12 @@ void validateSessionTokenWithDocumentNotFoundException(boolean useGateway) throw RxDocumentClientImpl writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); RxDocumentClientImpl validationClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); try { DocumentCollection collectionDefinition = getCollectionDefinition(); @@ -582,7 +582,7 @@ void validateSessionTokenWithExpectedException(boolean useGateway) throws Except RxDocumentClientImpl writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); try { ResourceResponse documentResponse = @@ -615,12 +615,12 @@ void validateSessionTokenWithConflictException(boolean useGateway) { RxDocumentClientImpl writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); RxDocumentClientImpl validationClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); try { Document documentDefinition = getDocumentDefinition(); @@ -648,7 +648,7 @@ void validateSessionTokenMultiPartitionCollection(boolean useGateway) throws Exc RxDocumentClientImpl writeClient = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); try { @@ -727,7 +727,7 @@ void validateSessionTokenFromCollectionReplaceIsServerToken(boolean useGateway) RxDocumentClientImpl client1 = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); RxDocumentClientImpl client2 = null; try { @@ -740,7 +740,7 @@ void validateSessionTokenFromCollectionReplaceIsServerToken(boolean useGateway) client2 = (RxDocumentClientImpl) new AsyncDocumentClient.Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION) + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true) .build(); client2.replaceCollection(createdCollection, null).block(); String token2 = ((SessionContainer) client2.getSession()).getSessionToken(createdCollection.getSelfLink()); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RetryThrottleTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RetryThrottleTest.java index e77e425c45fc6..c10853d2352cb 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RetryThrottleTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RetryThrottleTest.java @@ -47,7 +47,8 @@ public void retryCreateDocumentsOnSpike() throws Exception { .withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(policy) - .withConsistencyLevel(ConsistencyLevel.EVENTUAL); + .withConsistencyLevel(ConsistencyLevel.EVENTUAL) + .withContentResponseOnWriteEnabled(true); client = SpyClientUnderTestFactory.createClientWithGatewaySpy(builder); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RxDocumentClientUnderTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RxDocumentClientUnderTest.java index 549e7b8346fe2..cf9695dae8fa2 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RxDocumentClientUnderTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RxDocumentClientUnderTest.java @@ -36,8 +36,9 @@ public RxDocumentClientUnderTest(URI serviceEndpoint, ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, Configs configs, - CosmosKeyCredential cosmosKeyCredential) { - super(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential, false, false); + CosmosKeyCredential cosmosKeyCredential, + boolean contentResponseOnWriteEnabled) { + super(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential, false, false, contentResponseOnWriteEnabled); init(); } diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RxDocumentServiceRequestTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RxDocumentServiceRequestTest.java index 2cd57da2124d8..5540345e13d54 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RxDocumentServiceRequestTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/RxDocumentServiceRequestTest.java @@ -404,24 +404,6 @@ public void isValidAddress(String documentUrlWithId, String documentUrlWithName, assertThat(request.isValidAddress(ResourceType.Unknown)).isTrue(); } - @Test(groups = { "unit" }, dataProvider = "documentUrl") - public void addPreferHeader(String documentUrlWithId, String documentUrlWithName, OperationType operationType) { - RxDocumentServiceRequest request = RxDocumentServiceRequest.create(operationType, - ResourceType.Document, - documentUrlWithId, - new HashedMap()); - - request.addPreferHeader("preferHeaderName1", "preferHeaderValue1"); - assertThat(request.getHeaders().size()).isEqualTo(1); - assertThat(request.getHeaders().get(HttpConstants.HttpHeaders.PREFER)) - .isEqualTo("preferHeaderName1=preferHeaderValue1"); - - request.addPreferHeader("preferHeaderName2", "preferHeaderValue2"); - assertThat(request.getHeaders().size()).isEqualTo(1); - assertThat(request.getHeaders().get(HttpConstants.HttpHeaders.PREFER)) - .isEqualTo("preferHeaderName1=preferHeaderValue1;" + "preferHeaderName2=preferHeaderValue2"); - } - private Document getDocumentDefinition() { String uuid = UUID.randomUUID().toString(); Document doc = new Document(String.format(DOCUMENT_DEFINITION, uuid, PARTITION_KEY_VALUE)); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/SpyClientBuilder.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/SpyClientBuilder.java index db0950fe283ec..08cabe7151965 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/SpyClientBuilder.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/SpyClientBuilder.java @@ -12,31 +12,38 @@ public SpyClientBuilder(AsyncDocumentClient.Builder builder) { super.masterKeyOrResourceToken = builder.masterKeyOrResourceToken; super.serviceEndpoint = builder.serviceEndpoint; super.cosmosKeyCredential = builder.cosmosKeyCredential; + super.contentResponseOnWriteEnabled = builder.contentResponseOnWriteEnabled; } public SpyClientUnderTestFactory.ClientUnderTest build() { return SpyClientUnderTestFactory.createClientUnderTest( - serviceEndpoint, - masterKeyOrResourceToken, - connectionPolicy, - desiredConsistencyLevel, - configs, cosmosKeyCredential); + serviceEndpoint, + masterKeyOrResourceToken, + connectionPolicy, + desiredConsistencyLevel, + configs, + cosmosKeyCredential, + contentResponseOnWriteEnabled); } public SpyClientUnderTestFactory.ClientWithGatewaySpy buildWithGatewaySpy() { return SpyClientUnderTestFactory.createClientWithGatewaySpy( - serviceEndpoint, - masterKeyOrResourceToken, - connectionPolicy, - desiredConsistencyLevel, - configs, cosmosKeyCredential); + serviceEndpoint, + masterKeyOrResourceToken, + connectionPolicy, + desiredConsistencyLevel, + configs, + cosmosKeyCredential, + contentResponseOnWriteEnabled); } public SpyClientUnderTestFactory.DirectHttpsClientUnderTest buildWithDirectHttps() { return SpyClientUnderTestFactory.createDirectHttpsClientUnderTest( - serviceEndpoint, - masterKeyOrResourceToken, - connectionPolicy, - desiredConsistencyLevel, cosmosKeyCredential); + serviceEndpoint, + masterKeyOrResourceToken, + connectionPolicy, + desiredConsistencyLevel, + cosmosKeyCredential, + contentResponseOnWriteEnabled); } } diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/SpyClientUnderTestFactory.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/SpyClientUnderTestFactory.java index e3e52cdba795b..dac2acff90b9b 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/SpyClientUnderTestFactory.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/SpyClientUnderTestFactory.java @@ -32,8 +32,8 @@ public class SpyClientUnderTestFactory { public static abstract class SpyBaseClass extends RxDocumentClientImpl { - public SpyBaseClass(URI serviceEndpoint, String masterKeyOrResourceToken, ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, Configs configs, CosmosKeyCredential cosmosKeyCredential) { - super(serviceEndpoint, masterKeyOrResourceToken, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential, false, false); + public SpyBaseClass(URI serviceEndpoint, String masterKeyOrResourceToken, ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, Configs configs, CosmosKeyCredential cosmosKeyCredential, boolean contentResponseOnWriteEnabled) { + super(serviceEndpoint, masterKeyOrResourceToken, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential, false, false, contentResponseOnWriteEnabled); } public abstract List getCapturedRequests(); @@ -55,8 +55,8 @@ public static class ClientWithGatewaySpy extends SpyBaseClass requests; - ClientWithGatewaySpy(URI serviceEndpoint, String masterKey, ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, Configs configs, CosmosKeyCredential cosmosKeyCredential) { - super(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential); + ClientWithGatewaySpy(URI serviceEndpoint, String masterKey, ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, Configs configs, CosmosKeyCredential cosmosKeyCredential, boolean contentResponseOnWriteEnabled) { + super(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential, contentResponseOnWriteEnabled); init(); } @@ -117,8 +117,8 @@ public static class ClientUnderTest extends SpyBaseClass { List>> requestsResponsePairs = Collections.synchronizedList(new ArrayList<>()); - ClientUnderTest(URI serviceEndpoint, String masterKey, ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, Configs configs, CosmosKeyCredential cosmosKeyCredential) { - super(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential); + ClientUnderTest(URI serviceEndpoint, String masterKey, ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, Configs configs, CosmosKeyCredential cosmosKeyCredential, boolean contentResponseOnWriteEnabled) { + super(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential, contentResponseOnWriteEnabled); init(); } @@ -169,8 +169,8 @@ public static class DirectHttpsClientUnderTest extends SpyBaseClass List>> requestsResponsePairs = Collections.synchronizedList(new ArrayList<>()); - DirectHttpsClientUnderTest(URI serviceEndpoint, String masterKey, ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, CosmosKeyCredential cosmosKeyCredential) { - super(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, createConfigsSpy(Protocol.HTTPS), cosmosKeyCredential); + DirectHttpsClientUnderTest(URI serviceEndpoint, String masterKey, ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, CosmosKeyCredential cosmosKeyCredential, boolean contentResponseOnWriteEnabled) { + super(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, createConfigsSpy(Protocol.HTTPS), cosmosKeyCredential, contentResponseOnWriteEnabled); assert connectionPolicy.getConnectionMode() == ConnectionMode.DIRECT; init(); @@ -230,8 +230,9 @@ public static ClientWithGatewaySpy createClientWithGatewaySpy(URI serviceEndpoin ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, Configs configs, - CosmosKeyCredential cosmosKeyCredential) { - return new ClientWithGatewaySpy(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential); + CosmosKeyCredential cosmosKeyCredential, + boolean contentResponseOnWriteEnabled) { + return new ClientWithGatewaySpy(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential, contentResponseOnWriteEnabled); } public static ClientUnderTest createClientUnderTest(AsyncDocumentClient.Builder builder) { @@ -247,8 +248,9 @@ public static ClientUnderTest createClientUnderTest(URI serviceEndpoint, ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, Configs configs, - CosmosKeyCredential cosmosKeyCredential) { - return new ClientUnderTest(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential) { + CosmosKeyCredential cosmosKeyCredential, + boolean contentResponseOnWriteEnabled) { + return new ClientUnderTest(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, configs, cosmosKeyCredential, contentResponseOnWriteEnabled) { @Override RxGatewayStoreModel createRxGatewayProxy(ISessionContainer sessionContainer, @@ -277,7 +279,7 @@ RxGatewayStoreModel createRxGatewayProxy(ISessionContainer sessionContainer, } public static DirectHttpsClientUnderTest createDirectHttpsClientUnderTest(URI serviceEndpoint, String masterKey, - ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, CosmosKeyCredential cosmosKeyCredential) { - return new DirectHttpsClientUnderTest(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, cosmosKeyCredential); + ConnectionPolicy connectionPolicy, ConsistencyLevel consistencyLevel, CosmosKeyCredential cosmosKeyCredential, boolean contentResponseOnWriteEnabled) { + return new DirectHttpsClientUnderTest(serviceEndpoint, masterKey, connectionPolicy, consistencyLevel, cosmosKeyCredential, contentResponseOnWriteEnabled); } } diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/TestSuiteBase.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/TestSuiteBase.java index d4caa3fc19f94..727a76ac14661 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/TestSuiteBase.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/TestSuiteBase.java @@ -727,15 +727,15 @@ public static void validateQueryFailure(Flux parseProtocols(String protocols) { @DataProvider public static Object[][] simpleClientBuildersWithDirect() { - return simpleClientBuildersWithDirect(toArray(protocols)); + return simpleClientBuildersWithDirect(true, toArray(protocols)); } @DataProvider public static Object[][] simpleClientBuildersWithDirectHttps() { - return simpleClientBuildersWithDirect(Protocol.HTTPS); + return simpleClientBuildersWithDirect(true, Protocol.HTTPS); } - private static Object[][] simpleClientBuildersWithDirect(Protocol... protocols) { + private static Object[][] simpleClientBuildersWithDirect(boolean contentResponseOnWriteEnabled, Protocol... protocols) { logger.info("Max test consistency to use is [{}]", accountConsistency); List testConsistencies = ImmutableList.of(ConsistencyLevel.EVENTUAL); boolean isMultiMasterEnabled = preferredLocations != null && accountConsistency == ConsistencyLevel.SESSION; List builders = new ArrayList<>(); - builders.add(createGatewayRxDocumentClient(ConsistencyLevel.SESSION, false, null)); + builders.add(createGatewayRxDocumentClient(ConsistencyLevel.SESSION, false, null, contentResponseOnWriteEnabled)); for (Protocol protocol : protocols) { testConsistencies.forEach(consistencyLevel -> builders.add(createDirectRxDocumentClient(consistencyLevel, protocol, isMultiMasterEnabled, - preferredLocations))); + preferredLocations, contentResponseOnWriteEnabled))); } builders.forEach(b -> logger.info("Will Use ConnectionMode [{}], Consistency [{}], Protocol [{}]", @@ -838,12 +838,12 @@ static Protocol[] toArray(List protocols) { private static Object[][] clientBuildersWithDirectSession(Protocol... protocols) { return clientBuildersWithDirect(new ArrayList() {{ add(ConsistencyLevel.SESSION); - }}, protocols); + }}, true, protocols); } private static Object[][] clientBuildersWithDirectAllConsistencies(Protocol... protocols) { logger.info("Max test consistency to use is [{}]", accountConsistency); - return clientBuildersWithDirect(desiredConsistencies, protocols); + return clientBuildersWithDirect(desiredConsistencies, true, protocols); } static List parseDesiredConsistencies(String consistencies) { @@ -884,17 +884,17 @@ static List allEqualOrLowerConsistencies(ConsistencyLevel acco return testConsistencies; } - private static Object[][] clientBuildersWithDirect(List testConsistencies, Protocol... protocols) { + private static Object[][] clientBuildersWithDirect(List testConsistencies, boolean contentResponseOnWriteEnabled, Protocol... protocols) { boolean isMultiMasterEnabled = preferredLocations != null && accountConsistency == ConsistencyLevel.SESSION; List builders = new ArrayList<>(); - builders.add(createGatewayRxDocumentClient(ConsistencyLevel.SESSION, isMultiMasterEnabled, preferredLocations)); + builders.add(createGatewayRxDocumentClient(ConsistencyLevel.SESSION, isMultiMasterEnabled, preferredLocations, contentResponseOnWriteEnabled)); for (Protocol protocol : protocols) { testConsistencies.forEach(consistencyLevel -> builders.add(createDirectRxDocumentClient(consistencyLevel, protocol, isMultiMasterEnabled, - preferredLocations))); + preferredLocations, contentResponseOnWriteEnabled))); } builders.forEach(b -> logger.info("Will Use ConnectionMode [{}], Consistency [{}], Protocol [{}]", @@ -915,28 +915,30 @@ static protected Builder createGatewayHouseKeepingDocumentClient() { return new Builder().withServiceEndpoint(TestConfigurations.HOST) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(ConsistencyLevel.SESSION); + .withConsistencyLevel(ConsistencyLevel.SESSION).withContentResponseOnWriteEnabled(true); } - static protected Builder createGatewayRxDocumentClient(ConsistencyLevel consistencyLevel, boolean multiMasterEnabled, List preferredLocations) { + static protected Builder createGatewayRxDocumentClient(ConsistencyLevel consistencyLevel, boolean multiMasterEnabled, List preferredLocations, boolean contentResponseOnWriteEnabled) { ConnectionPolicy connectionPolicy = new ConnectionPolicy(); connectionPolicy.setConnectionMode(ConnectionMode.GATEWAY); connectionPolicy.setUsingMultipleWriteRegions(multiMasterEnabled); connectionPolicy.setPreferredRegions(preferredLocations); return new Builder().withServiceEndpoint(TestConfigurations.HOST) - .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) - .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(consistencyLevel); + .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) + .withConnectionPolicy(connectionPolicy) + .withConsistencyLevel(consistencyLevel) + .withContentResponseOnWriteEnabled(contentResponseOnWriteEnabled); } static protected Builder createGatewayRxDocumentClient() { - return createGatewayRxDocumentClient(ConsistencyLevel.SESSION, false, null); + return createGatewayRxDocumentClient(ConsistencyLevel.SESSION, false, null, true); } static protected Builder createDirectRxDocumentClient(ConsistencyLevel consistencyLevel, - Protocol protocol, - boolean multiMasterEnabled, - List preferredRegions) { + Protocol protocol, + boolean multiMasterEnabled, + List preferredRegions, + boolean contentResponseOnWriteEnabled) { ConnectionPolicy connectionPolicy = new ConnectionPolicy(); connectionPolicy.setConnectionMode(ConnectionMode.DIRECT); @@ -952,10 +954,11 @@ static protected Builder createDirectRxDocumentClient(ConsistencyLevel consisten doAnswer((Answer)invocation -> protocol).when(configs).getProtocol(); return new Builder().withServiceEndpoint(TestConfigurations.HOST) - .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) - .withConnectionPolicy(connectionPolicy) - .withConsistencyLevel(consistencyLevel) - .withConfigs(configs); + .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) + .withConnectionPolicy(connectionPolicy) + .withConsistencyLevel(consistencyLevel) + .withConfigs(configs) + .withContentResponseOnWriteEnabled(contentResponseOnWriteEnabled); } protected int expectedNumberOfPages(int totalExpectedResult, int maxPageSize) { diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/DCDocumentCrudTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/DCDocumentCrudTest.java index 78249af3f22fe..bdade11a4cefb 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/DCDocumentCrudTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/DCDocumentCrudTest.java @@ -80,6 +80,7 @@ static Builder createDCBuilder(Protocol protocol) { .withConfigs(configs) .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.SESSION) + .withContentResponseOnWriteEnabled(true) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY); } diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/AggregateQueryTests.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/AggregateQueryTests.java index 8879e18c3056d..decbcbda007ae 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/AggregateQueryTests.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/AggregateQueryTests.java @@ -188,8 +188,6 @@ public void afterClass() { safeClose(client); } - // TODO (DANOBLE) AggregateQueryTests initialization intermittently fails due to collection truncation error. - // see https://github.com/Azure/azure-sdk-for-java/issues/6346 @BeforeClass(groups = { "simple" }, timeOut = 4 * SETUP_TIMEOUT) public void before_AggregateQueryTests() throws Throwable { client = this.getClientBuilder().buildAsyncClient(); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CosmosAuthorizationTokenResolverTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CosmosAuthorizationTokenResolverTest.java index 411f68df03726..131536ac8fb8f 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CosmosAuthorizationTokenResolverTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CosmosAuthorizationTokenResolverTest.java @@ -239,6 +239,7 @@ public void verifyingAuthTokenAPISequence(ConnectionMode connectionMode) { .withTokenResolver(getTokenResolver(null)) //TokenResolver always generating invalid token. .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withPermissionFeed(permissionFeed) + .withContentResponseOnWriteEnabled(true) .build(); RequestOptions requestOptions = new RequestOptions(); requestOptions.setPartitionKey(new PartitionKey(ModelBridgeInternal.getObjectFromJsonSerializable(resourceResponse.getResource(), "mypk"))); @@ -254,6 +255,7 @@ public void verifyingAuthTokenAPISequence(ConnectionMode connectionMode) { .withTokenResolver(getTokenResolver(PermissionMode.READ)) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) .withPermissionFeed(permissionFeed) + .withContentResponseOnWriteEnabled(true) .build(); readObservable = asyncClientWithTokenResolver.readDocument(resourceResponse.getResource().getSelfLink(), requestOptions); ResourceResponseValidator sucessValidator = new ResourceResponseValidator.Builder() @@ -267,6 +269,7 @@ public void verifyingAuthTokenAPISequence(ConnectionMode connectionMode) { .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.SESSION) .withPermissionFeed(permissionFeed) + .withContentResponseOnWriteEnabled(true) .build(); readObservable = asyncClientWithTokenResolver.readDocument(resourceResponse.getResource().getSelfLink(), requestOptions); validateSuccess(readObservable, sucessValidator); @@ -278,6 +281,7 @@ public void verifyingAuthTokenAPISequence(ConnectionMode connectionMode) { .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.SESSION) .withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY) + .withContentResponseOnWriteEnabled(true) .build(); readObservable = asyncClientWithTokenResolver.readDocument(resourceResponse.getResource().getSelfLink(), requestOptions); validateSuccess(readObservable, sucessValidator); @@ -418,6 +422,7 @@ public void verifyRuntimeExceptionWhenUserModifiesProperties(ConnectionMode conn .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.SESSION) .withTokenResolver(getBadTokenResolver()) + .withContentResponseOnWriteEnabled(true) .build(); RequestOptions options = new RequestOptions(); @@ -445,6 +450,7 @@ public void verifyBlockListedUserThrows(ConnectionMode connectionMode) { .withConnectionPolicy(connectionPolicy) .withConsistencyLevel(ConsistencyLevel.SESSION) .withTokenResolver(getTokenResolverWithBlockList(PermissionMode.READ, field, blockListedUser, errorMessage)) + .withContentResponseOnWriteEnabled(true) .build(); RequestOptions options = new RequestOptions(); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/DocumentCrudTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/DocumentCrudTest.java index 1b62596f76c2f..3aa8f71540151 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/DocumentCrudTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/DocumentCrudTest.java @@ -65,8 +65,6 @@ public void createDocument(String documentId) throws InterruptedException { this.validateItemSuccess(createObservable, validator); } - // TODO (DANOBLE) DocumentCrudTest::createLargeDocument fails in some environments - // see https://github.com/Azure/azure-sdk-for-java/issues/6335 @Test(groups = { "simple" }, timeOut = TIMEOUT, dataProvider = "documentCrudArgProvider") public void createLargeDocument(String documentId) throws InterruptedException { CosmosItemProperties docDefinition = getDocumentDefinition(documentId); @@ -105,8 +103,6 @@ public void createDocumentWithVeryLargePartitionKey(String documentId) throws In this.validateItemSuccess(createObservable, validator); } - // TODO (DANOBLE) DocumentCrudTest::readDocumentWithVeryLargePartitionKey test fails in some environments - // see https://github.com/Azure/azure-sdk-for-java/issues/6336 @Test(groups = { "simple" }, timeOut = TIMEOUT, dataProvider = "documentCrudArgProvider") public void readDocumentWithVeryLargePartitionKey(String documentId) throws InterruptedException { CosmosItemProperties docDefinition = getDocumentDefinition(documentId); @@ -213,8 +209,6 @@ public void readDocument_DoesntExist(String documentId) throws InterruptedExcept validateItemFailure(readObservable, validator); } - // TODO (DANOBLE) DocumentCrudTest::deleteDocument test fails in some test environments - // see https://github.com/Azure/azure-sdk-for-java/issues/6337 @Test(groups = { "simple" }, timeOut = TIMEOUT, dataProvider = "documentCrudArgProvider") public void deleteDocument(String documentId) throws InterruptedException { CosmosItemProperties docDefinition = getDocumentDefinition(documentId); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/OrderbyDocumentQueryTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/OrderbyDocumentQueryTest.java index 7307006966283..58af64103a088 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/OrderbyDocumentQueryTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/OrderbyDocumentQueryTest.java @@ -390,8 +390,6 @@ public void beforeMethod() throws Exception { TimeUnit.SECONDS.sleep(10); } - // TODO (DANOBLE) OrderbyDocumentQueryTest initialization intermittently times out in CI environments - // see https://github.com/Azure/azure-sdk-for-java/issues/6386 @BeforeClass(groups = { "simple" }, timeOut = 4 * SETUP_TIMEOUT) public void before_OrderbyDocumentQueryTest() throws Exception { client = getClientBuilder().buildAsyncClient(); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ParallelDocumentQueryTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ParallelDocumentQueryTest.java index b652b2f0937e8..58249da49e7c4 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ParallelDocumentQueryTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ParallelDocumentQueryTest.java @@ -373,8 +373,6 @@ public void queryDocumentsPojo(){ } - // TODO (DANOBLE) ParallelDocumentQueryTest initialization intermittently fails in CI environments - // see https://github.com/Azure/azure-sdk-for-java/issues/6398 @BeforeClass(groups = { "simple", "non-emulator" }, timeOut = 4 * SETUP_TIMEOUT) public void before_ParallelDocumentQueryTest() { client = getClientBuilder().buildAsyncClient(); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ProxyHostTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ProxyHostTest.java index 772a21a17aeeb..6f499de9d5b92 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ProxyHostTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ProxyHostTest.java @@ -74,7 +74,9 @@ public void createDocumentWithValidHttpProxy() throws Exception { clientWithRightProxy = new CosmosClientBuilder().endpoint(TestConfigurations.HOST) .key(TestConfigurations.MASTER_KEY) .connectionPolicy(connectionPolicy) - .consistencyLevel(ConsistencyLevel.SESSION).buildAsyncClient(); + .consistencyLevel(ConsistencyLevel.SESSION) + .contentResponseOnWriteEnabled(true) + .buildAsyncClient(); CosmosItemProperties docDefinition = getDocumentDefinition(); Mono> createObservable = clientWithRightProxy.getDatabase(createdDatabase.getId()).getContainer(createdCollection.getId()) .createItem(docDefinition, new CosmosItemRequestOptions()); @@ -108,7 +110,9 @@ public void createDocumentWithValidHttpProxyWithNettyWireLogging() throws Except clientWithRightProxy = new CosmosClientBuilder().endpoint(TestConfigurations.HOST) .key(TestConfigurations.MASTER_KEY) .connectionPolicy(connectionPolicy) - .consistencyLevel(ConsistencyLevel.SESSION).buildAsyncClient(); + .consistencyLevel(ConsistencyLevel.SESSION) + .contentResponseOnWriteEnabled(true) + .buildAsyncClient(); CosmosItemProperties docDefinition = getDocumentDefinition(); Mono> createObservable = clientWithRightProxy.getDatabase(createdDatabase.getId()).getContainer(createdCollection.getId()) .createItem(docDefinition, new CosmosItemRequestOptions()); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ReadFeedDocumentsTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ReadFeedDocumentsTest.java index d0a0881423288..3da9aa91f6526 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ReadFeedDocumentsTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/ReadFeedDocumentsTest.java @@ -77,8 +77,6 @@ public void readDocuments_withoutEnableCrossPartitionQuery() { validateQuerySuccess(feedObservable.byPage(maxItemCount), validator, FEED_TIMEOUT); } - // TODO (DANOBLE) ReadFeedDocumentsTest initialization consistently times out in CI environments. - // see https://github.com/Azure/azure-sdk-for-java/issues/6379 @BeforeClass(groups = { "simple" }, timeOut = 4 * SETUP_TIMEOUT, alwaysRun = true) public void before_ReadFeedDocumentsTest() { client = getClientBuilder().buildAsyncClient(); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/SinglePartitionReadFeedDocumentsTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/SinglePartitionReadFeedDocumentsTest.java index df1386b7e37cf..75d3c0833a3a8 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/SinglePartitionReadFeedDocumentsTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/SinglePartitionReadFeedDocumentsTest.java @@ -50,8 +50,6 @@ public void readDocuments() { validateQuerySuccess(feedObservable.byPage(maxItemCount), validator, FEED_TIMEOUT); } - // TODO (DANOBLE) SinglePartitionReadFeedDocumentsTest initialization consistently times out in CI environments. - // see https://github.com/Azure/azure-sdk-for-java/issues/6380 @BeforeClass(groups = { "simple" }, timeOut = 4 * SETUP_TIMEOUT) public void before_SinglePartitionReadFeedDocumentsTest() { client = getClientBuilder().buildAsyncClient(); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/TestSuiteBase.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/TestSuiteBase.java index 4db0d37889a0e..eb10a19ac883c 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/TestSuiteBase.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/TestSuiteBase.java @@ -200,7 +200,7 @@ public static void beforeSuite() { logger.info("beforeSuite Started"); - try (CosmosAsyncClient houseKeepingClient = createGatewayHouseKeepingDocumentClient().buildAsyncClient()) { + try (CosmosAsyncClient houseKeepingClient = createGatewayHouseKeepingDocumentClient(true).buildAsyncClient()) { CosmosDatabaseForTest dbForTest = CosmosDatabaseForTest.create(DatabaseManagerImpl.getInstance(houseKeepingClient)); SHARED_DATABASE = dbForTest.createdDatabase; CosmosContainerRequestOptions options = new CosmosContainerRequestOptions(); @@ -216,7 +216,7 @@ public static void afterSuite() { logger.info("afterSuite Started"); - try (CosmosAsyncClient houseKeepingClient = createGatewayHouseKeepingDocumentClient().buildAsyncClient()) { + try (CosmosAsyncClient houseKeepingClient = createGatewayHouseKeepingDocumentClient(true).buildAsyncClient()) { safeDeleteDatabase(SHARED_DATABASE); CosmosDatabaseForTest.cleanupStaleTestDatabases(DatabaseManagerImpl.getInstance(houseKeepingClient)); } @@ -844,15 +844,15 @@ public static void validateQueryFailure(Flux parseProtocols(String protocols) { @DataProvider public static Object[][] simpleClientBuildersWithDirect() { - return simpleClientBuildersWithDirect(toArray(protocols)); + return simpleClientBuildersWithDirect(true, toArray(protocols)); } @DataProvider public static Object[][] simpleClientBuildersWithDirectHttps() { - return simpleClientBuildersWithDirect(Protocol.HTTPS); + return simpleClientBuildersWithDirect(true, Protocol.HTTPS); } - private static Object[][] simpleClientBuildersWithDirect(Protocol... protocols) { + @DataProvider + public static Object[][] simpleClientBuildersWithDirectTcp() { + return simpleClientBuildersWithDirect(true, Protocol.TCP); + } + + @DataProvider + public static Object[][] simpleClientBuildersWithDirectTcpWithContentResponseOnWriteDisabled() { + return simpleClientBuildersWithDirect(false, Protocol.TCP); + } + + private static Object[][] simpleClientBuildersWithDirect(boolean contentResponseOnWriteEnabled, Protocol... protocols) { logger.info("Max test consistency to use is [{}]", accountConsistency); List testConsistencies = ImmutableList.of(ConsistencyLevel.EVENTUAL); @@ -921,7 +931,8 @@ private static Object[][] simpleClientBuildersWithDirect(Protocol... protocols) consistencyLevel, protocol, isMultiMasterEnabled, - preferredLocations))); + preferredLocations, + contentResponseOnWriteEnabled))); } cosmosConfigurations.forEach(c -> { @@ -934,39 +945,49 @@ private static Object[][] simpleClientBuildersWithDirect(Protocol... protocols) ); }); - cosmosConfigurations.add(createGatewayRxDocumentClient(ConsistencyLevel.SESSION, false, null)); + cosmosConfigurations.add(createGatewayRxDocumentClient(ConsistencyLevel.SESSION, false, null, contentResponseOnWriteEnabled)); return cosmosConfigurations.stream().map(b -> new Object[]{b}).collect(Collectors.toList()).toArray(new Object[0][]); } @DataProvider public static Object[][] clientBuildersWithDirect() { - return clientBuildersWithDirectAllConsistencies(toArray(protocols)); + return clientBuildersWithDirectAllConsistencies(true, toArray(protocols)); } @DataProvider public static Object[][] clientBuildersWithDirectHttps() { - return clientBuildersWithDirectAllConsistencies(Protocol.HTTPS); + return clientBuildersWithDirectAllConsistencies(true, Protocol.HTTPS); + } + + @DataProvider + public static Object[][] clientBuildersWithDirectTcp() { + return clientBuildersWithDirectAllConsistencies(true, Protocol.TCP); + } + + @DataProvider + public static Object[][] clientBuildersWithDirectTcpWithContentResponseOnWriteDisabled() { + return clientBuildersWithDirectAllConsistencies(false, Protocol.TCP); } @DataProvider public static Object[][] clientBuildersWithDirectSession() { - return clientBuildersWithDirectSession(toArray(protocols)); + return clientBuildersWithDirectSession(true, toArray(protocols)); } static Protocol[] toArray(List protocols) { return protocols.toArray(new Protocol[protocols.size()]); } - private static Object[][] clientBuildersWithDirectSession(Protocol... protocols) { + private static Object[][] clientBuildersWithDirectSession(boolean contentResponseOnWriteEnabled, Protocol... protocols) { return clientBuildersWithDirect(new ArrayList() {{ add(ConsistencyLevel.SESSION); - }}, protocols); + }}, contentResponseOnWriteEnabled, protocols); } - private static Object[][] clientBuildersWithDirectAllConsistencies(Protocol... protocols) { + private static Object[][] clientBuildersWithDirectAllConsistencies(boolean contentResponseOnWriteEnabled, Protocol... protocols) { logger.info("Max test consistency to use is [{}]", accountConsistency); - return clientBuildersWithDirect(desiredConsistencies, protocols); + return clientBuildersWithDirect(desiredConsistencies, contentResponseOnWriteEnabled, protocols); } static List parseDesiredConsistencies(String consistencies) { @@ -1008,7 +1029,7 @@ static List allEqualOrLowerConsistencies(ConsistencyLevel acco return testConsistencies; } - private static Object[][] clientBuildersWithDirect(List testConsistencies, Protocol... protocols) { + private static Object[][] clientBuildersWithDirect(List testConsistencies, boolean contentResponseOnWriteEnabled, Protocol... protocols) { boolean isMultiMasterEnabled = preferredLocations != null && accountConsistency == ConsistencyLevel.SESSION; List cosmosConfigurations = new ArrayList<>(); @@ -1017,7 +1038,8 @@ private static Object[][] clientBuildersWithDirect(List testCo testConsistencies.forEach(consistencyLevel -> cosmosConfigurations.add(createDirectRxDocumentClient(consistencyLevel, protocol, isMultiMasterEnabled, - preferredLocations))); + preferredLocations, + contentResponseOnWriteEnabled))); } cosmosConfigurations.forEach(c -> { @@ -1030,42 +1052,46 @@ private static Object[][] clientBuildersWithDirect(List testCo ); }); - cosmosConfigurations.add(createGatewayRxDocumentClient(ConsistencyLevel.SESSION, isMultiMasterEnabled, preferredLocations)); + cosmosConfigurations.add(createGatewayRxDocumentClient(ConsistencyLevel.SESSION, isMultiMasterEnabled, preferredLocations, contentResponseOnWriteEnabled)); return cosmosConfigurations.stream().map(c -> new Object[]{c}).collect(Collectors.toList()).toArray(new Object[0][]); } - static protected CosmosClientBuilder createGatewayHouseKeepingDocumentClient() { + static protected CosmosClientBuilder createGatewayHouseKeepingDocumentClient(boolean contentResponseOnWriteEnabled) { ConnectionPolicy connectionPolicy = new ConnectionPolicy(); connectionPolicy.setConnectionMode(ConnectionMode.GATEWAY); ThrottlingRetryOptions options = new ThrottlingRetryOptions(); options.setMaxRetryWaitTime(Duration.ofSeconds(SUITE_SETUP_TIMEOUT)); connectionPolicy.setThrottlingRetryOptions(options); return new CosmosClientBuilder().endpoint(TestConfigurations.HOST) - .keyCredential(cosmosKeyCredential) - .connectionPolicy(connectionPolicy) - .consistencyLevel(ConsistencyLevel.SESSION); + .keyCredential(cosmosKeyCredential) + .connectionPolicy(connectionPolicy) + .contentResponseOnWriteEnabled(contentResponseOnWriteEnabled) + .consistencyLevel(ConsistencyLevel.SESSION); } - static protected CosmosClientBuilder createGatewayRxDocumentClient(ConsistencyLevel consistencyLevel, boolean multiMasterEnabled, List preferredRegions) { + static protected CosmosClientBuilder createGatewayRxDocumentClient(ConsistencyLevel consistencyLevel, boolean multiMasterEnabled, + List preferredRegions, boolean contentResponseOnWriteEnabled) { ConnectionPolicy connectionPolicy = new ConnectionPolicy(); connectionPolicy.setConnectionMode(ConnectionMode.GATEWAY); connectionPolicy.setUsingMultipleWriteRegions(multiMasterEnabled); connectionPolicy.setPreferredRegions(preferredRegions); return new CosmosClientBuilder().endpoint(TestConfigurations.HOST) - .keyCredential(cosmosKeyCredential) - .connectionPolicy(connectionPolicy) - .consistencyLevel(consistencyLevel); + .keyCredential(cosmosKeyCredential) + .connectionPolicy(connectionPolicy) + .contentResponseOnWriteEnabled(contentResponseOnWriteEnabled) + .consistencyLevel(consistencyLevel); } static protected CosmosClientBuilder createGatewayRxDocumentClient() { - return createGatewayRxDocumentClient(ConsistencyLevel.SESSION, false, null); + return createGatewayRxDocumentClient(ConsistencyLevel.SESSION, false, null, true); } static protected CosmosClientBuilder createDirectRxDocumentClient(ConsistencyLevel consistencyLevel, Protocol protocol, boolean multiMasterEnabled, - List preferredRegions) { + List preferredRegions, + boolean contentResponseOnWriteEnabled) { ConnectionPolicy connectionPolicy = new ConnectionPolicy(); connectionPolicy.setConnectionMode(ConnectionMode.DIRECT); @@ -1081,9 +1107,10 @@ static protected CosmosClientBuilder createDirectRxDocumentClient(ConsistencyLev doAnswer((Answer)invocation -> protocol).when(configs).getProtocol(); CosmosClientBuilder builder = new CosmosClientBuilder().endpoint(TestConfigurations.HOST) - .keyCredential(cosmosKeyCredential) - .connectionPolicy(connectionPolicy) - .consistencyLevel(consistencyLevel); + .keyCredential(cosmosKeyCredential) + .connectionPolicy(connectionPolicy) + .contentResponseOnWriteEnabled(contentResponseOnWriteEnabled) + .consistencyLevel(consistencyLevel); return injectConfigs(builder, configs); } diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/UniqueIndexTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/UniqueIndexTest.java index 1e500fe5d7165..4a71ad9c734f5 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/UniqueIndexTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/UniqueIndexTest.java @@ -16,7 +16,6 @@ import com.azure.cosmos.models.CosmosItemRequestOptions; import com.azure.cosmos.models.DataType; import com.azure.cosmos.models.ExcludedPath; -import com.azure.cosmos.models.HashIndex; import com.azure.cosmos.models.IncludedPath; import com.azure.cosmos.models.Index; import com.azure.cosmos.models.IndexingMode; @@ -224,7 +223,9 @@ public void before_UniqueIndexTest() { .endpoint(TestConfigurations.HOST) .key(TestConfigurations.MASTER_KEY) .connectionPolicy(ConnectionPolicy.getDefaultPolicy()) - .consistencyLevel(ConsistencyLevel.SESSION).buildAsyncClient(); + .consistencyLevel(ConsistencyLevel.SESSION) + .contentResponseOnWriteEnabled(true) + .buildAsyncClient(); database = createDatabase(client, databaseId); } diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/UserDefinedFunctionUpsertReplaceTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/UserDefinedFunctionUpsertReplaceTest.java index 2b91a91ae3166..880c1b99eb891 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/UserDefinedFunctionUpsertReplaceTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/UserDefinedFunctionUpsertReplaceTest.java @@ -65,8 +65,6 @@ public void replaceUserDefinedFunction() throws Exception { validateSuccess(replaceObservable, validatorForReplace); } - // TODO (DANOBLE) UserDefinedFunctionUpsertReplaceTest initialization consistently times out in CI environments. - // see https://github.com/Azure/azure-sdk-for-java/issues/6383 @BeforeClass(groups = { "simple" }, timeOut = 4 * SETUP_TIMEOUT) public void before_UserDefinedFunctionUpsertReplaceTest() { client = getClientBuilder().buildAsyncClient(); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/VeryLargeDocumentQueryTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/VeryLargeDocumentQueryTest.java index 7745887c51ed5..66e652ab76ccc 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/VeryLargeDocumentQueryTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/VeryLargeDocumentQueryTest.java @@ -39,9 +39,6 @@ public VeryLargeDocumentQueryTest(CosmosClientBuilder clientBuilder) { super(clientBuilder); } - // TODO (DANOBLE) VeryLargeDocumentQueryTest::queryLargeDocuments intermittently times out - // Move this test back into the emulator group after we've addressed query performance on 4.X. - // see https://github.com/Azure/azure-sdk-for-java/issues/6377 @Test(groups = { "simple" }, timeOut = 2 * TIMEOUT) public void queryLargeDocuments() { @@ -83,8 +80,6 @@ private void createLargeDocument() { .verify(Duration.ofMillis(subscriberValidationTimeout)); } - // TODO (DANOBLE) beforeClass method intermittently times out within the SETUP_TIMEOUT interval. - // see see https://github.com/Azure/azure-sdk-for-java/issues/6377 @BeforeClass(groups = { "simple" }, timeOut = 2 * SETUP_TIMEOUT) public void before_VeryLargeDocumentQueryTest() { client = getClientBuilder().buildAsyncClient();