From 20e4b107d346bac6c118d9f3681e573a297b7c04 Mon Sep 17 00:00:00 2001 From: Kushagra Thapar Date: Tue, 7 Jan 2020 13:16:11 -0800 Subject: [PATCH 1/3] Exposed default time to live API on CosmosContainerProperties --- .../cosmos/CosmosContainerProperties.java | 40 ++++++++++++ .../azure/cosmos/CosmosResponseValidator.java | 13 ++++ .../azure/cosmos/rx/CollectionCrudTest.java | 63 +++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosContainerProperties.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosContainerProperties.java index c6d2d22fb88c..cf85c39aba2b 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosContainerProperties.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosContainerProperties.java @@ -196,6 +196,46 @@ public CosmosContainerProperties setConflictResolutionPolicy(ConflictResolutionP return this; } + /** + * Gets the collection's default time-to-live value. + * + * @return the default time-to-live value in seconds. + */ + public Integer getDefaultTimeToLive() { + if (super.has(Constants.Properties.DEFAULT_TTL)) { + return super.getInt(Constants.Properties.DEFAULT_TTL); + } + + return null; + } + + /** + * Sets the collection's default time-to-live value. + *

+ * The default time-to-live value on a collection is an optional property. If set, the documents within the collection + * expires after the specified number of seconds since their last write time. The value of this property should be one of the following: + *

+ * null - indicates evaluation of time-to-live is disabled and documents within the collection will never expire, regardless whether + * individual documents have their time-to-live set. + *

+ * nonzero positive integer - indicates the default time-to-live value for all documents within the collection. This value can be overridden + * by individual documents' time-to-live value. + *

+ * -1 - indicates by default all documents within the collection never expire. This value can be overridden by individual documents' + * time-to-live value. + * + * @param timeToLive the default time-to-live value in seconds. + */ + public void setDefaultTimeToLive(Integer timeToLive) { + // a "null" value is represented as a missing element on the wire. + // setting timeToLive to null should remove the property from the property bag. + if (timeToLive != null) { + super.set(Constants.Properties.DEFAULT_TTL, timeToLive); + } else if (super.has(Constants.Properties.DEFAULT_TTL)) { + super.remove(Constants.Properties.DEFAULT_TTL); + } + } + DocumentCollection getV2Collection() { DocumentCollection collection = new DocumentCollection(this.toJson()); collection.setPartitionKey(this.getPartitionKeyDefinition()); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java index cefed5a6f9a2..8aac9debce4f 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java @@ -88,6 +88,19 @@ public void validate(CosmosAsyncContainerResponse resourceResponse) { return this; } + public Builder withDefaultTimeToLive(Integer timeToLive) { + validators.add(new CosmosResponseValidator() { + + @Override + public void validate(CosmosContainerResponse resourceResponse) { + assertThat(resourceResponse.getProperties()).isNotNull(); + assertThat(resourceResponse.getProperties().getDefaultTimeToLive()).isNotNull(); + assertThat(resourceResponse.getProperties().getDefaultTimeToLive()).isEqualTo(timeToLive); + } + }); + return this; + } + public Builder withProperty(String propertyName, String value) { validators.add(new CosmosResponseValidator() { @Override diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CollectionCrudTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CollectionCrudTest.java index 28c4b7e48d10..d9b43b6c2e84 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CollectionCrudTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CollectionCrudTest.java @@ -95,6 +95,23 @@ public void createCollection(String collectionName) throws InterruptedException safeDeleteAllCollections(database); } + @Test(groups = { "emulator" }, timeOut = TIMEOUT, dataProvider = "collectionCrudArgProvider") + public void createCollectionWithTTL(String collectionName) throws InterruptedException { + CosmosContainerProperties collectionDefinition = getCollectionDefinition(collectionName); + + Integer defaultTimeToLive = 300; + collectionDefinition.setDefaultTimeToLive(defaultTimeToLive); + + Mono createObservable = database + .createContainer(collectionDefinition); + + CosmosResponseValidator validator = new CosmosResponseValidator.Builder() + .withId(collectionDefinition.getId()).withDefaultTimeToLive(defaultTimeToLive).build(); + + validateSuccess(createObservable, validator); + safeDeleteAllCollections(database); + } + @Test(groups = { "emulator" }, timeOut = TIMEOUT) public void createCollectionWithCompositeIndexAndSpatialSpec() throws InterruptedException { PartitionKeyDefinition partitionKeyDef = new PartitionKeyDefinition(); @@ -188,6 +205,24 @@ public void readCollection(String collectionName) throws InterruptedException { safeDeleteAllCollections(database); } + @Test(groups = { "emulator" }, timeOut = TIMEOUT, dataProvider = "collectionCrudArgProvider") + public void readCollectionWithTTL(String collectionName) throws InterruptedException { + CosmosContainerProperties collectionDefinition = getCollectionDefinition(collectionName); + + Integer defaultTimeToLive = 200; + collectionDefinition.setDefaultTimeToLive(defaultTimeToLive); + + Mono createObservable = database.createContainer(collectionDefinition); + CosmosAsyncContainer collection = createObservable.block().getContainer(); + + Mono readObservable = collection.read(); + + CosmosResponseValidator validator = new CosmosResponseValidator.Builder() + .withId(collection.getId()).withDefaultTimeToLive(defaultTimeToLive).build(); + validateSuccess(readObservable, validator); + safeDeleteAllCollections(database); + } + @Test(groups = { "emulator" }, timeOut = TIMEOUT, dataProvider = "collectionCrudArgProvider") public void readCollection_DoesntExist(String collectionName) throws Exception { @@ -235,6 +270,34 @@ public void replaceCollection(String collectionName) throws InterruptedException safeDeleteAllCollections(database); } + @Test(groups = { "emulator" }, timeOut = TIMEOUT, dataProvider = "collectionCrudArgProvider") + public void replaceCollectionWithTTL(String collectionName) throws InterruptedException { + // create a collection + CosmosContainerProperties collectionDefinition = getCollectionDefinition(collectionName); + Integer defaultTimeToLive = 120; + collectionDefinition.setDefaultTimeToLive(defaultTimeToLive); + Mono createObservable = database.createContainer(collectionDefinition); + CosmosAsyncContainer collection = createObservable.block().getContainer(); + CosmosContainerProperties collectionSettings = collection.read().block().getProperties(); + // sanity check + assertThat(collectionSettings.getIndexingPolicy().getIndexingMode()).isEqualTo(IndexingMode.CONSISTENT); + assertThat(collectionSettings.getDefaultTimeToLive()).isEqualTo(defaultTimeToLive); + + // replace indexing mode + IndexingPolicy indexingMode = new IndexingPolicy(); + indexingMode.setIndexingMode(IndexingMode.LAZY); + collectionSettings.setIndexingPolicy(indexingMode); + collectionSettings.setDefaultTimeToLive(defaultTimeToLive * 2); + Mono readObservable = collection.replace(collectionSettings, new CosmosContainerRequestOptions()); + + // validate + CosmosResponseValidator validator = new CosmosResponseValidator.Builder() + .indexingMode(IndexingMode.LAZY).withDefaultTimeToLive(defaultTimeToLive * 2).build(); + validateSuccess(readObservable, validator); + safeDeleteAllCollections(database); + } + + @Test(groups = { "emulator" }, timeOut = 10 * TIMEOUT, retryAnalyzer = RetryAnalyzer.class) public void sessionTokenConsistencyCollectionDeleteCreateSameName() { CosmosAsyncClient client1 = clientBuilder().buildAsyncClient(); From 562f63cbd882fd47a41e5bc9bba4d656cca93aef Mon Sep 17 00:00:00 2001 From: Kushagra Thapar Date: Tue, 7 Jan 2020 16:07:52 -0800 Subject: [PATCH 2/3] Fixed response validator --- .../test/java/com/azure/cosmos/CosmosResponseValidator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java index 8aac9debce4f..8afc708684bb 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java @@ -89,10 +89,10 @@ public void validate(CosmosAsyncContainerResponse resourceResponse) { } public Builder withDefaultTimeToLive(Integer timeToLive) { - validators.add(new CosmosResponseValidator() { + validators.add(new CosmosResponseValidator() { @Override - public void validate(CosmosContainerResponse resourceResponse) { + public void validate(CosmosAsyncContainerResponse resourceResponse) { assertThat(resourceResponse.getProperties()).isNotNull(); assertThat(resourceResponse.getProperties().getDefaultTimeToLive()).isNotNull(); assertThat(resourceResponse.getProperties().getDefaultTimeToLive()).isEqualTo(timeToLive); From 74e40a65428a07ea61987596c48a3034b3e68de3 Mon Sep 17 00:00:00 2001 From: Kushagra Thapar Date: Wed, 8 Jan 2020 10:55:53 -0800 Subject: [PATCH 3/3] Added unit as suffix to the API --- .../com/azure/cosmos/CosmosContainerProperties.java | 4 ++-- .../java/com/azure/cosmos/CosmosResponseValidator.java | 4 ++-- .../java/com/azure/cosmos/rx/CollectionCrudTest.java | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosContainerProperties.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosContainerProperties.java index cf85c39aba2b..695d1bb38694 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosContainerProperties.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosContainerProperties.java @@ -201,7 +201,7 @@ public CosmosContainerProperties setConflictResolutionPolicy(ConflictResolutionP * * @return the default time-to-live value in seconds. */ - public Integer getDefaultTimeToLive() { + public Integer getDefaultTimeToLiveInSeconds() { if (super.has(Constants.Properties.DEFAULT_TTL)) { return super.getInt(Constants.Properties.DEFAULT_TTL); } @@ -226,7 +226,7 @@ public Integer getDefaultTimeToLive() { * * @param timeToLive the default time-to-live value in seconds. */ - public void setDefaultTimeToLive(Integer timeToLive) { + public void setDefaultTimeToLiveInSeconds(Integer timeToLive) { // a "null" value is represented as a missing element on the wire. // setting timeToLive to null should remove the property from the property bag. if (timeToLive != null) { diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java index 8afc708684bb..f5af62385c78 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosResponseValidator.java @@ -94,8 +94,8 @@ public Builder withDefaultTimeToLive(Integer timeToLive) { @Override public void validate(CosmosAsyncContainerResponse resourceResponse) { assertThat(resourceResponse.getProperties()).isNotNull(); - assertThat(resourceResponse.getProperties().getDefaultTimeToLive()).isNotNull(); - assertThat(resourceResponse.getProperties().getDefaultTimeToLive()).isEqualTo(timeToLive); + assertThat(resourceResponse.getProperties().getDefaultTimeToLiveInSeconds()).isNotNull(); + assertThat(resourceResponse.getProperties().getDefaultTimeToLiveInSeconds()).isEqualTo(timeToLive); } }); return this; diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CollectionCrudTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CollectionCrudTest.java index d9b43b6c2e84..709e7250daf9 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CollectionCrudTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/rx/CollectionCrudTest.java @@ -100,7 +100,7 @@ public void createCollectionWithTTL(String collectionName) throws InterruptedExc CosmosContainerProperties collectionDefinition = getCollectionDefinition(collectionName); Integer defaultTimeToLive = 300; - collectionDefinition.setDefaultTimeToLive(defaultTimeToLive); + collectionDefinition.setDefaultTimeToLiveInSeconds(defaultTimeToLive); Mono createObservable = database .createContainer(collectionDefinition); @@ -210,7 +210,7 @@ public void readCollectionWithTTL(String collectionName) throws InterruptedExcep CosmosContainerProperties collectionDefinition = getCollectionDefinition(collectionName); Integer defaultTimeToLive = 200; - collectionDefinition.setDefaultTimeToLive(defaultTimeToLive); + collectionDefinition.setDefaultTimeToLiveInSeconds(defaultTimeToLive); Mono createObservable = database.createContainer(collectionDefinition); CosmosAsyncContainer collection = createObservable.block().getContainer(); @@ -275,19 +275,19 @@ public void replaceCollectionWithTTL(String collectionName) throws InterruptedEx // create a collection CosmosContainerProperties collectionDefinition = getCollectionDefinition(collectionName); Integer defaultTimeToLive = 120; - collectionDefinition.setDefaultTimeToLive(defaultTimeToLive); + collectionDefinition.setDefaultTimeToLiveInSeconds(defaultTimeToLive); Mono createObservable = database.createContainer(collectionDefinition); CosmosAsyncContainer collection = createObservable.block().getContainer(); CosmosContainerProperties collectionSettings = collection.read().block().getProperties(); // sanity check assertThat(collectionSettings.getIndexingPolicy().getIndexingMode()).isEqualTo(IndexingMode.CONSISTENT); - assertThat(collectionSettings.getDefaultTimeToLive()).isEqualTo(defaultTimeToLive); + assertThat(collectionSettings.getDefaultTimeToLiveInSeconds()).isEqualTo(defaultTimeToLive); // replace indexing mode IndexingPolicy indexingMode = new IndexingPolicy(); indexingMode.setIndexingMode(IndexingMode.LAZY); collectionSettings.setIndexingPolicy(indexingMode); - collectionSettings.setDefaultTimeToLive(defaultTimeToLive * 2); + collectionSettings.setDefaultTimeToLiveInSeconds(defaultTimeToLive * 2); Mono readObservable = collection.replace(collectionSettings, new CosmosContainerRequestOptions()); // validate