diff --git a/src/main/asciidoc/caching.adoc b/src/main/asciidoc/caching.adoc index e0bfcfb3..5aacff6a 100644 --- a/src/main/asciidoc/caching.adoc +++ b/src/main/asciidoc/caching.adoc @@ -22,13 +22,13 @@ To make it work, you need to add the `@EnableCaching` annotation and configure t public class Config extends AbstractCouchbaseConfiguration { // general methods - @Bean - public CouchbaseCacheManager cacheManager(CouchbaseTemplate couchbaseTemplate) throws Exception { - CouchbaseCacheManager.CouchbaseCacheManagerBuilder builder = CouchbaseCacheManager.CouchbaseCacheManagerBuilder - .fromConnectionFactory(couchbaseTemplate.getCouchbaseClientFactory()); - return builder.build(); - } - + @Bean + public CouchbaseCacheManager cacheManager(CouchbaseTemplate couchbaseTemplate) throws Exception { + CouchbaseCacheManager.CouchbaseCacheManagerBuilder builder = CouchbaseCacheManager.CouchbaseCacheManagerBuilder + .fromConnectionFactory(couchbaseTemplate.getCouchbaseClientFactory()); + builder.withCacheConfiguration("mySpringCache", CouchbaseCacheConfiguration.defaultCacheConfig()); + return builder.build(); + } ---- ==== diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 65077956..96f910bd 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -26,6 +26,7 @@ include::template.adoc[] include::transactions.adoc[] include::collections.adoc[] include::ansijoins.adoc[] +include::caching.adoc[] :leveloffset: -1 [[appendix]] diff --git a/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheCollectionIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheCollectionIntegrationTests.java index f434f9ca..65aea1e3 100644 --- a/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheCollectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheCollectionIntegrationTests.java @@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; * * @author Michael Reiche */ -@IgnoreWhen(clusterTypes = ClusterType.MOCKED, missesCapabilities = { Capabilities.COLLECTIONS }) +@IgnoreWhen(clusterTypes = ClusterType.MOCKED, missesCapabilities = { Capabilities.COLLECTIONS }) class CouchbaseCacheCollectionIntegrationTests extends CollectionAwareIntegrationTests { volatile CouchbaseCache cache; @@ -58,7 +58,6 @@ class CouchbaseCacheCollectionIntegrationTests extends CollectionAwareIntegratio QueryOptions.queryOptions().scanConsistency(REQUEST_PLUS)); } - @Test void cachePutGet() { CacheUser user1 = new CacheUser(UUID.randomUUID().toString(), "first1", "last1"); diff --git a/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheIntegrationTests.java index 8dadb39c..1500fa81 100644 --- a/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheIntegrationTests.java @@ -21,10 +21,18 @@ import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import java.util.List; import java.util.UUID; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.data.couchbase.domain.Config; +import org.springframework.data.couchbase.domain.User; +import org.springframework.data.couchbase.domain.UserRepository; import org.springframework.data.couchbase.util.ClusterType; import org.springframework.data.couchbase.util.IgnoreWhen; import org.springframework.data.couchbase.util.JavaIntegrationTests; @@ -40,6 +48,8 @@ import com.couchbase.client.java.query.QueryOptions; class CouchbaseCacheIntegrationTests extends JavaIntegrationTests { volatile CouchbaseCache cache; + @Autowired CouchbaseCacheManager cacheManager; // autowired not working + @Autowired UserRepository userRepository; // autowired not working @BeforeEach @Override @@ -48,6 +58,16 @@ class CouchbaseCacheIntegrationTests extends JavaIntegrationTests { cache = CouchbaseCacheManager.create(couchbaseTemplate.getCouchbaseClientFactory()).createCouchbaseCache("myCache", CouchbaseCacheConfiguration.defaultCacheConfig()); clear(cache); + ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class); + cacheManager = ac.getBean(CouchbaseCacheManager.class); + userRepository = ac.getBean(UserRepository.class); + } + + @AfterEach + @Override + public void afterEach() { + clear(cache); + super.afterEach(); } private void clear(CouchbaseCache c) { @@ -69,6 +89,19 @@ class CouchbaseCacheIntegrationTests extends JavaIntegrationTests { assertEquals(user2, cache.get(user2.getId()).get()); // get user2 } + @Test + void cacheable() { + User user = new User("cache_92", "Dave", "Wilson"); + cacheManager.getCache("mySpringCache").clear(); + userRepository.save(user); + long t0 = System.currentTimeMillis(); + List users = userRepository.getByFirstname(user.getFirstname()); + assert (System.currentTimeMillis() - t0 > 1000 * 5); + t0 = System.currentTimeMillis(); + users = userRepository.getByFirstname(user.getFirstname()); + assert (System.currentTimeMillis() - t0 < 100); + } + @Test void cacheEvict() { CacheUser user1 = new CacheUser(UUID.randomUUID().toString(), "first1", "last1"); @@ -98,4 +131,22 @@ class CouchbaseCacheIntegrationTests extends JavaIntegrationTests { assertEquals(user1, cache.get(user1.getId()).get()); // user1.getId() is still user1 } + @Test // this test FAILS (local empty (i.e. fast) Couchbase installation) + public void clearFail() { + cache.put("KEY", "VALUE"); // no delay between put and clear, entry will not be + cache.clear(); // will not be indexed when clear() executes + assertNotNull(cache.get("KEY")); // will still find entry, clear failed to delete + } + + @Test // this WORKS + public void clearWithDelayOk() throws InterruptedException { + cache.put("KEY", "VALUE"); + Thread.sleep(50); // give main index time to update + cache.clear(); + assertNull(cache.get("KEY")); + } + + @Test + public void noOpt() {} + } diff --git a/src/test/java/org/springframework/data/couchbase/domain/Config.java b/src/test/java/org/springframework/data/couchbase/domain/Config.java index ba5258b2..9e72e582 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/Config.java +++ b/src/test/java/org/springframework/data/couchbase/domain/Config.java @@ -58,7 +58,7 @@ import com.couchbase.client.java.json.JacksonTransformers; @EnableReactiveCouchbaseRepositories @EnableCouchbaseAuditing(dateTimeProviderRef = "dateTimeProviderRef") @EnableReactiveCouchbaseAuditing(dateTimeProviderRef = "dateTimeProviderRef") - +@EnableCaching public class Config extends AbstractCouchbaseConfiguration { String bucketname = "travel-sample"; String username = "Administrator"; diff --git a/src/test/java/org/springframework/data/couchbase/domain/UserRepository.java b/src/test/java/org/springframework/data/couchbase/domain/UserRepository.java index 229ae00c..31b5eab3 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/UserRepository.java +++ b/src/test/java/org/springframework/data/couchbase/domain/UserRepository.java @@ -19,7 +19,7 @@ package org.springframework.data.couchbase.domain; import java.util.List; import java.util.stream.Stream; -import com.couchbase.client.java.query.QueryScanConsistency; +import org.springframework.cache.annotation.Cacheable; import org.springframework.data.couchbase.repository.CouchbaseRepository; import org.springframework.data.couchbase.repository.Query; import org.springframework.data.couchbase.repository.ScanConsistency; @@ -27,6 +27,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import com.couchbase.client.java.json.JsonArray; +import com.couchbase.client.java.query.QueryScanConsistency; /** * User Repository for tests @@ -35,7 +36,7 @@ import com.couchbase.client.java.json.JsonArray; * @author Michael Reiche */ @Repository -@ScanConsistency(query=QueryScanConsistency.REQUEST_PLUS) +@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS) public interface UserRepository extends CouchbaseRepository { List findByFirstname(String firstname); @@ -57,4 +58,13 @@ public interface UserRepository extends CouchbaseRepository { List findByIdIsNotNullAndFirstnameEquals(String firstname); List findByVersionEqualsAndFirstnameEquals(Long version, String firstname); + + // simulate a slow operation + @Cacheable("mySpringCache") + default List getByFirstname(String firstname) { + try { + Thread.sleep(1000 * 5); + } catch (InterruptedException ie) {} + return findByFirstname(firstname); + } }