diff --git a/src/main/java/org/springframework/data/couchbase/core/ExecutableInsertByIdOperation.java b/src/main/java/org/springframework/data/couchbase/core/ExecutableInsertByIdOperation.java index 44d6a7631..6ab0ea948 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ExecutableInsertByIdOperation.java +++ b/src/main/java/org/springframework/data/couchbase/core/ExecutableInsertByIdOperation.java @@ -15,6 +15,7 @@ */ package org.springframework.data.couchbase.core; +import java.time.Duration; import java.util.Collection; import com.couchbase.client.core.msg.kv.DurabilityLevel; @@ -46,6 +47,11 @@ interface InsertByIdWithDurability extends InsertByIdWithCollection { } - interface ExecutableInsertById extends InsertByIdWithDurability {} + interface InsertByIdWithExpiry extends InsertByIdWithDurability { + + InsertByIdWithDurability withExpiry(Duration expiry); + } + + interface ExecutableInsertById extends InsertByIdWithExpiry {} } diff --git a/src/main/java/org/springframework/data/couchbase/core/ExecutableInsertByIdOperationSupport.java b/src/main/java/org/springframework/data/couchbase/core/ExecutableInsertByIdOperationSupport.java index df0b8f0f9..913630179 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ExecutableInsertByIdOperationSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/ExecutableInsertByIdOperationSupport.java @@ -15,6 +15,7 @@ */ package org.springframework.data.couchbase.core; +import java.time.Duration; import java.util.Collection; import org.springframework.util.Assert; @@ -35,7 +36,7 @@ public ExecutableInsertByIdOperationSupport(final CouchbaseTemplate template) { public ExecutableInsertById insertById(final Class domainType) { Assert.notNull(domainType, "DomainType must not be null!"); return new ExecutableInsertByIdSupport<>(template, domainType, null, PersistTo.NONE, ReplicateTo.NONE, - DurabilityLevel.NONE); + DurabilityLevel.NONE, Duration.ofSeconds(0)); } static class ExecutableInsertByIdSupport implements ExecutableInsertById { @@ -46,18 +47,21 @@ static class ExecutableInsertByIdSupport implements ExecutableInsertById { private final PersistTo persistTo; private final ReplicateTo replicateTo; private final DurabilityLevel durabilityLevel; + private final Duration expiry; private final ReactiveInsertByIdOperationSupport.ReactiveInsertByIdSupport reactiveSupport; ExecutableInsertByIdSupport(final CouchbaseTemplate template, final Class domainType, final String collection, - final PersistTo persistTo, final ReplicateTo replicateTo, final DurabilityLevel durabilityLevel) { + final PersistTo persistTo, final ReplicateTo replicateTo, final DurabilityLevel durabilityLevel, + final Duration expiry) { this.template = template; this.domainType = domainType; this.collection = collection; this.persistTo = persistTo; this.replicateTo = replicateTo; this.durabilityLevel = durabilityLevel; + this.expiry = expiry; this.reactiveSupport = new ReactiveInsertByIdOperationSupport.ReactiveInsertByIdSupport<>(template.reactive(), - domainType, collection, persistTo, replicateTo, durabilityLevel); + domainType, collection, persistTo, replicateTo, durabilityLevel, expiry); } @Override @@ -74,14 +78,14 @@ public Collection all(Collection objects) { public TerminatingInsertById inCollection(final String collection) { Assert.hasText(collection, "Collection must not be null nor empty."); return new ExecutableInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, - durabilityLevel); + durabilityLevel, expiry); } @Override public InsertByIdWithCollection withDurability(final DurabilityLevel durabilityLevel) { Assert.notNull(durabilityLevel, "Durability Level must not be null."); return new ExecutableInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, - durabilityLevel); + durabilityLevel, expiry); } @Override @@ -89,7 +93,14 @@ public InsertByIdWithCollection withDurability(final PersistTo persistTo, fin Assert.notNull(persistTo, "PersistTo must not be null."); Assert.notNull(replicateTo, "ReplicateTo must not be null."); return new ExecutableInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, - durabilityLevel); + durabilityLevel, expiry); + } + + @Override + public InsertByIdWithDurability withExpiry(final Duration expiry) { + Assert.notNull(expiry, "expiry must not be null."); + return new ExecutableInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, + durabilityLevel, expiry); } } diff --git a/src/main/java/org/springframework/data/couchbase/core/ExecutableUpsertByIdOperation.java b/src/main/java/org/springframework/data/couchbase/core/ExecutableUpsertByIdOperation.java index dacd06d83..3d919a8c2 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ExecutableUpsertByIdOperation.java +++ b/src/main/java/org/springframework/data/couchbase/core/ExecutableUpsertByIdOperation.java @@ -15,6 +15,7 @@ */ package org.springframework.data.couchbase.core; +import java.time.Duration; import java.util.Collection; import com.couchbase.client.core.msg.kv.DurabilityLevel; @@ -46,6 +47,11 @@ interface UpsertByIdWithDurability extends UpsertByIdWithCollection { } - interface ExecutableUpsertById extends UpsertByIdWithDurability {} + interface UpsertByIdWithExpiry extends UpsertByIdWithDurability { + + UpsertByIdWithDurability withExpiry(Duration expiry); + } + + interface ExecutableUpsertById extends UpsertByIdWithExpiry {} } diff --git a/src/main/java/org/springframework/data/couchbase/core/ExecutableUpsertByIdOperationSupport.java b/src/main/java/org/springframework/data/couchbase/core/ExecutableUpsertByIdOperationSupport.java index 3a4af6cd6..173bdb8cb 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ExecutableUpsertByIdOperationSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/ExecutableUpsertByIdOperationSupport.java @@ -15,6 +15,7 @@ */ package org.springframework.data.couchbase.core; +import java.time.Duration; import java.util.Collection; import org.springframework.util.Assert; @@ -35,7 +36,7 @@ public ExecutableUpsertByIdOperationSupport(final CouchbaseTemplate template) { public ExecutableUpsertById upsertById(final Class domainType) { Assert.notNull(domainType, "DomainType must not be null!"); return new ExecutableUpsertByIdSupport<>(template, domainType, null, PersistTo.NONE, ReplicateTo.NONE, - DurabilityLevel.NONE); + DurabilityLevel.NONE, Duration.ofSeconds(0)); } static class ExecutableUpsertByIdSupport implements ExecutableUpsertById { @@ -46,18 +47,21 @@ static class ExecutableUpsertByIdSupport implements ExecutableUpsertById { private final PersistTo persistTo; private final ReplicateTo replicateTo; private final DurabilityLevel durabilityLevel; + private final Duration expiry; private final ReactiveUpsertByIdOperationSupport.ReactiveUpsertByIdSupport reactiveSupport; ExecutableUpsertByIdSupport(final CouchbaseTemplate template, final Class domainType, final String collection, - final PersistTo persistTo, final ReplicateTo replicateTo, final DurabilityLevel durabilityLevel) { + final PersistTo persistTo, final ReplicateTo replicateTo, final DurabilityLevel durabilityLevel, + final Duration expiry) { this.template = template; this.domainType = domainType; this.collection = collection; this.persistTo = persistTo; this.replicateTo = replicateTo; this.durabilityLevel = durabilityLevel; + this.expiry = expiry; this.reactiveSupport = new ReactiveUpsertByIdOperationSupport.ReactiveUpsertByIdSupport<>(template.reactive(), - domainType, collection, persistTo, replicateTo, durabilityLevel); + domainType, collection, persistTo, replicateTo, durabilityLevel, expiry); } @Override @@ -74,14 +78,14 @@ public Collection all(Collection objects) { public TerminatingUpsertById inCollection(final String collection) { Assert.hasText(collection, "Collection must not be null nor empty."); return new ExecutableUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, - durabilityLevel); + durabilityLevel, expiry); } @Override public UpsertByIdWithCollection withDurability(final DurabilityLevel durabilityLevel) { Assert.notNull(durabilityLevel, "Durability Level must not be null."); return new ExecutableUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, - durabilityLevel); + durabilityLevel, expiry); } @Override @@ -89,7 +93,14 @@ public UpsertByIdWithCollection withDurability(final PersistTo persistTo, fin Assert.notNull(persistTo, "PersistTo must not be null."); Assert.notNull(replicateTo, "ReplicateTo must not be null."); return new ExecutableUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, - durabilityLevel); + durabilityLevel, expiry); + } + + @Override + public UpsertByIdWithDurability withExpiry(final Duration expiry) { + Assert.notNull(expiry, "expiry must not be null."); + return new ExecutableUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, + durabilityLevel, expiry); } } diff --git a/src/main/java/org/springframework/data/couchbase/core/ReactiveInsertByIdOperation.java b/src/main/java/org/springframework/data/couchbase/core/ReactiveInsertByIdOperation.java index d578ef13b..54e10163c 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ReactiveInsertByIdOperation.java +++ b/src/main/java/org/springframework/data/couchbase/core/ReactiveInsertByIdOperation.java @@ -18,6 +18,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.time.Duration; import java.util.Collection; import com.couchbase.client.core.msg.kv.DurabilityLevel; @@ -49,6 +50,11 @@ interface InsertByIdWithDurability extends InsertByIdWithCollection { } - interface ReactiveInsertById extends InsertByIdWithDurability {} + interface InsertByIdWithExpiry extends InsertByIdWithDurability { + + InsertByIdWithDurability withExpiry(Duration expiry); + } + + interface ReactiveInsertById extends InsertByIdWithExpiry {} } diff --git a/src/main/java/org/springframework/data/couchbase/core/ReactiveInsertByIdOperationSupport.java b/src/main/java/org/springframework/data/couchbase/core/ReactiveInsertByIdOperationSupport.java index a7e35e37d..c977511f4 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ReactiveInsertByIdOperationSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/ReactiveInsertByIdOperationSupport.java @@ -15,9 +15,12 @@ */ package org.springframework.data.couchbase.core; +import com.couchbase.client.java.kv.UpsertOptions; +import org.springframework.data.couchbase.core.mapping.Document; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.time.Duration; import java.util.Collection; import org.springframework.data.couchbase.core.mapping.CouchbaseDocument; @@ -40,7 +43,7 @@ public ReactiveInsertByIdOperationSupport(final ReactiveCouchbaseTemplate templa public ReactiveInsertById insertById(final Class domainType) { Assert.notNull(domainType, "DomainType must not be null!"); return new ReactiveInsertByIdSupport<>(template, domainType, null, PersistTo.NONE, ReplicateTo.NONE, - DurabilityLevel.NONE); + DurabilityLevel.NONE, Duration.ofSeconds(0)); } static class ReactiveInsertByIdSupport implements ReactiveInsertById { @@ -51,16 +54,18 @@ static class ReactiveInsertByIdSupport implements ReactiveInsertById { private final PersistTo persistTo; private final ReplicateTo replicateTo; private final DurabilityLevel durabilityLevel; + private final Duration expiry; ReactiveInsertByIdSupport(final ReactiveCouchbaseTemplate template, final Class domainType, final String collection, final PersistTo persistTo, final ReplicateTo replicateTo, - final DurabilityLevel durabilityLevel) { + final DurabilityLevel durabilityLevel, Duration expiry) { this.template = template; this.domainType = domainType; this.collection = collection; this.persistTo = persistTo; this.replicateTo = replicateTo; this.durabilityLevel = durabilityLevel; + this.expiry = expiry; } @Override @@ -93,28 +98,40 @@ private InsertOptions buildInsertOptions() { } else if (durabilityLevel != DurabilityLevel.NONE) { options.durability(durabilityLevel); } + if (expiry != null) { + options.expiry(expiry); + } else if (domainType.isAnnotationPresent(Document.class)) { + Document documentAnn = domainType.getAnnotation(Document.class); + long durationSeconds = documentAnn.expiryUnit().toSeconds(documentAnn.expiry()); + options.expiry(Duration.ofSeconds(durationSeconds)); + } return options; } @Override public TerminatingInsertById inCollection(final String collection) { Assert.hasText(collection, "Collection must not be null nor empty."); - return new ReactiveInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel); + return new ReactiveInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel, expiry); } @Override public InsertByIdWithCollection withDurability(final DurabilityLevel durabilityLevel) { Assert.notNull(durabilityLevel, "Durability Level must not be null."); - return new ReactiveInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel); + return new ReactiveInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel, expiry); } @Override public InsertByIdWithCollection withDurability(final PersistTo persistTo, final ReplicateTo replicateTo) { Assert.notNull(persistTo, "PersistTo must not be null."); Assert.notNull(replicateTo, "ReplicateTo must not be null."); - return new ReactiveInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel); + return new ReactiveInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel, expiry); } + @Override + public InsertByIdWithDurability withExpiry(final Duration expiry) { + Assert.notNull(expiry, "expiry must not be null."); + return new ReactiveInsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel, expiry); + } } } diff --git a/src/main/java/org/springframework/data/couchbase/core/ReactiveUpsertByIdOperation.java b/src/main/java/org/springframework/data/couchbase/core/ReactiveUpsertByIdOperation.java index 7c1811bea..da0df85bd 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ReactiveUpsertByIdOperation.java +++ b/src/main/java/org/springframework/data/couchbase/core/ReactiveUpsertByIdOperation.java @@ -18,6 +18,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.time.Duration; import java.util.Collection; import com.couchbase.client.core.msg.kv.DurabilityLevel; @@ -49,6 +50,11 @@ interface UpsertByIdWithDurability extends UpsertByIdWithCollection { } - interface ReactiveUpsertById extends UpsertByIdWithDurability {} + interface UpsertByIdWithExpiry extends UpsertByIdWithDurability { + + UpsertByIdWithDurability withExpiry(Duration expiry); + } + + interface ReactiveUpsertById extends UpsertByIdWithExpiry {} } diff --git a/src/main/java/org/springframework/data/couchbase/core/ReactiveUpsertByIdOperationSupport.java b/src/main/java/org/springframework/data/couchbase/core/ReactiveUpsertByIdOperationSupport.java index 26d47c09f..bb07b2c77 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ReactiveUpsertByIdOperationSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/ReactiveUpsertByIdOperationSupport.java @@ -15,9 +15,12 @@ */ package org.springframework.data.couchbase.core; +import com.couchbase.client.java.kv.Expiry; +import org.springframework.data.couchbase.core.mapping.Document; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.time.Duration; import java.util.Collection; import org.springframework.data.couchbase.core.mapping.CouchbaseDocument; @@ -40,7 +43,7 @@ public ReactiveUpsertByIdOperationSupport(final ReactiveCouchbaseTemplate templa public ReactiveUpsertById upsertById(final Class domainType) { Assert.notNull(domainType, "DomainType must not be null!"); return new ReactiveUpsertByIdSupport<>(template, domainType, null, PersistTo.NONE, ReplicateTo.NONE, - DurabilityLevel.NONE); + DurabilityLevel.NONE, Duration.ofSeconds(0)); } static class ReactiveUpsertByIdSupport implements ReactiveUpsertById { @@ -51,16 +54,18 @@ static class ReactiveUpsertByIdSupport implements ReactiveUpsertById { private final PersistTo persistTo; private final ReplicateTo replicateTo; private final DurabilityLevel durabilityLevel; + private final Duration expiry; ReactiveUpsertByIdSupport(final ReactiveCouchbaseTemplate template, final Class domainType, final String collection, final PersistTo persistTo, final ReplicateTo replicateTo, - final DurabilityLevel durabilityLevel) { + final DurabilityLevel durabilityLevel, final Duration expiry) { this.template = template; this.domainType = domainType; this.collection = collection; this.persistTo = persistTo; this.replicateTo = replicateTo; this.durabilityLevel = durabilityLevel; + this.expiry = expiry; } @Override @@ -93,28 +98,44 @@ private UpsertOptions buildUpsertOptions() { } else if (durabilityLevel != DurabilityLevel.NONE) { options.durability(durabilityLevel); } + if (expiry != null) { + options.expiry(expiry); + } else if (domainType.isAnnotationPresent(Document.class)) { + Document documentAnn = domainType.getAnnotation(Document.class); + long durationSeconds = documentAnn.expiryUnit().toSeconds(documentAnn.expiry()); + options.expiry(Duration.ofSeconds(durationSeconds)); + } return options; } @Override public TerminatingUpsertById inCollection(final String collection) { Assert.hasText(collection, "Collection must not be null nor empty."); - return new ReactiveUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel); + return new ReactiveUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel, + expiry); } @Override public UpsertByIdWithCollection withDurability(final DurabilityLevel durabilityLevel) { Assert.notNull(durabilityLevel, "Durability Level must not be null."); - return new ReactiveUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel); + return new ReactiveUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel, + expiry); } @Override public UpsertByIdWithCollection withDurability(final PersistTo persistTo, final ReplicateTo replicateTo) { Assert.notNull(persistTo, "PersistTo must not be null."); Assert.notNull(replicateTo, "ReplicateTo must not be null."); - return new ReactiveUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel); + return new ReactiveUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel, + expiry); } + @Override + public UpsertByIdWithDurability withExpiry(final Duration expiry) { + Assert.notNull(expiry, "expiry must not be null."); + return new ReactiveUpsertByIdSupport<>(template, domainType, collection, persistTo, replicateTo, durabilityLevel, + expiry); + } } } diff --git a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java index d0ebb50ba..1ddf61037 100644 --- a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java @@ -23,6 +23,9 @@ import java.time.Duration; import java.util.UUID; +import com.couchbase.client.core.error.DocumentNotFoundException; +import com.couchbase.client.java.kv.PersistTo; +import com.couchbase.client.java.kv.ReplicateTo; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -30,11 +33,13 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.dao.DataIntegrityViolationException;; +import org.springframework.dao.DataRetrievalFailureException; import org.springframework.dao.DuplicateKeyException; import org.springframework.data.couchbase.CouchbaseClientFactory; import org.springframework.data.couchbase.SimpleCouchbaseClientFactory; import org.springframework.data.couchbase.domain.Config; import org.springframework.data.couchbase.domain.User; +import org.springframework.data.couchbase.domain.UserAnnotated; import org.springframework.data.couchbase.util.ClusterAwareIntegrationTests; import org.springframework.data.couchbase.util.ClusterType; import org.springframework.data.couchbase.util.IgnoreWhen; @@ -86,6 +91,53 @@ void upsertAndFindById() { couchbaseTemplate.removeById().one(user.getId()); } + @Test + void upsertWithDurability() { + User user = new User(UUID.randomUUID().toString(), "firstname", "lastname"); + User modified = couchbaseTemplate.upsertById(User.class).withDurability(PersistTo.ACTIVE, ReplicateTo.NONE) + .one(user); + assertEquals(user, modified); + User found = couchbaseTemplate.findById(User.class).one(user.getId()); + assertEquals(user, found); + couchbaseTemplate.removeById().one(user.getId()); + } + + @Test + void upsertWithExpiry() { + User user = new User(UUID.randomUUID().toString(), "firstname", "lastname"); + try { + User modified = couchbaseTemplate.upsertById(User.class).withExpiry(Duration.ofSeconds(1)).one(user); + assertEquals(user, modified); + sleepSecs(2); + User found = couchbaseTemplate.findById(User.class).one(user.getId()); + assertNull(found, "found should have been null as document should be expired"); + } finally { + try { + couchbaseTemplate.removeById().one(user.getId()); + } catch (DataRetrievalFailureException e) { + // + } + } + } + + @Test + void upsertWithExpiryAnnotation() { + UserAnnotated user = new UserAnnotated(UUID.randomUUID().toString(), "firstname", "lastname"); + try { + UserAnnotated modified = couchbaseTemplate.upsertById(UserAnnotated.class).one(user); + assertEquals(user, modified); + sleepSecs(6); + User found = couchbaseTemplate.findById(User.class).one(user.getId()); + assertNull(found, "found should have been null as document should be expired"); + } finally { + try { + couchbaseTemplate.removeById().one(user.getId()); + } catch (DataRetrievalFailureException e) { + // + } + } + } + @Test void findDocWhichDoesNotExist() { assertNull(couchbaseTemplate.findById(User.class).one(UUID.randomUUID().toString())); @@ -132,6 +184,55 @@ void insertById() { } + @Test + void insertByIdwithDurability() { + User user = new User(UUID.randomUUID().toString(), "firstname", "lastname"); + User inserted = couchbaseTemplate.insertById(User.class).withDurability(PersistTo.ACTIVE, ReplicateTo.NONE) + .one(user); + assertEquals(user, inserted); + + assertThrows(DuplicateKeyException.class, () -> couchbaseTemplate.insertById(User.class).one(user)); + couchbaseTemplate.removeById().one(user.getId()); + + } + + @Test + void insertByIdwithExpiry() { + User user = new User(UUID.randomUUID().toString(), "firstname", "lastname"); + try { + User inserted = couchbaseTemplate.insertById(User.class).withExpiry(Duration.ofSeconds(1)).one(user); + assertEquals(user, inserted); + sleepSecs(2); + User found = couchbaseTemplate.findById(User.class).one(user.getId()); + assertNull(found, "found should have been null as document should be expired"); + } finally { + try { + couchbaseTemplate.removeById().one(user.getId()); + } catch (DataRetrievalFailureException e) { + // ignore + } + } + + } + + @Test + void insertWithExpiryAnnotation() { + UserAnnotated user = new UserAnnotated(UUID.randomUUID().toString(), "firstname", "lastname"); + try { + UserAnnotated inserted = couchbaseTemplate.insertById(UserAnnotated.class).one(user); + assertEquals(user, inserted); + sleepSecs(6); + User found = couchbaseTemplate.findById(User.class).one(user.getId()); + assertNull(found, "found should have been null as document should be expired"); + } finally { + try { + couchbaseTemplate.removeById().one(user.getId()); + } catch (DataRetrievalFailureException e) { + // ignore + } + } + } + @Test void existsById() { String id = UUID.randomUUID().toString(); @@ -146,4 +247,10 @@ void existsById() { } + private void sleepSecs(int i) { + try { + Thread.sleep(i * 1000); + } catch (InterruptedException ie) {} + } + } diff --git a/src/test/java/org/springframework/data/couchbase/domain/UserAnnotated.java b/src/test/java/org/springframework/data/couchbase/domain/UserAnnotated.java new file mode 100644 index 000000000..32bc7dfa0 --- /dev/null +++ b/src/test/java/org/springframework/data/couchbase/domain/UserAnnotated.java @@ -0,0 +1,42 @@ +/* + * Copyright 2020 the original author or authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.couchbase.domain; + +import java.util.Objects; + +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.Version; +import org.springframework.data.couchbase.core.mapping.Document; + +/** + * Annoted User entity for tests + * + * @author Michael Reiche + */ + +@Document(expiry = 5) +public class UserAnnotated extends User { + + public UserAnnotated(String id, String firstname, String lastname) { + super(id, firstname, lastname); + } +}