Fetching all keys from Partitioned Coherent Cache - caching

I am doing a project and my requirement is to basically implement a Coherence Cache Dashboard. The basic idea is to fetch all the keys stored in the Coherent Cache. Is there a command or any other way to fetch all cache keys from distributed coherent cache?
public void printAllCache(){
Cache<String, String> cache = cacheManager.getCache(CACHENAME,
String.class, String.class);
Iterator<Cache.Entry<String,String>> allCacheEntries= cache.iterator();
while(allCacheEntries.hasNext()){
Cache.Entry<String,String> currentEntry = allCacheEntries.next();
System.out.println("Key: "+currentEntry.getKey()+" Value: "+
currentEntry.getValue());
}
return returnProperties;
}
By doing this, i can iterate over cache keys created by the current cache manager. But, how can I find keys created by other cache managers in a partitioned coherent cache?

This is a simple command:
NamedCache<String, String> cache = CacheFactory.getCache(CACHENAME, String.class, String.class);
Set<String> keys = cache.keySet();

Related

How to get all data from Java Spring Cache

i need toknow how to retrieve or where to see al data stored in my cache.
#Configuration
#EnableCaching
public class CachingConf {
#Bean
public CacheManager cacheManager() {
Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.SECONDS)
.maximumSize(1000);
CaffeineCacheManager cacheManager = new CaffeineCacheManager("hr");
cacheManager.setCaffeine(cacheBuilder);
return cacheManager;
}
}
private final CacheManager cacheManager;
public CacheFilter(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
#Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
final var cache = cacheManager.getCache("hr");
......
I want to somehow see all data in my cache stored but the cache does not have get all or something like tht.Any advices guys?
The spring cache abstraction does not provide a method to get all the entries in a cache. But luckily they provide a method to get the underlying native cache abstraction which is Caffeine cache in your case.
The Caffeine cache has a method called asMap() to return a map view containing all the entries stored in the cache.
So combining them together will give you the following :
var cache = cacheManager.getCache("hr");
com.github.benmanes.caffeine.cache.Cache<Object, Object> nativeCache = (com.github.benmanes.caffeine.cache.Cache<Object, Object>)cache.getNativeCache();
ConcurrentMap<K, V> map = nativeCache.asMap();
//Loop through the map here to access all the entries in the cache
Please note that it is a quick and effective fix but it will make your codes couple to Caffeine . If you mind , you can configure the spring cache to use JCache and configure JCache to use Caffeine cache (see this) . As JCache API implements Iterable<Cache.Entry<K, V>>, it allow you to iterate all of its entries :
var cache = cacheManager.getCache("hr");
javax.cache<Object, Object> nativeCache = (javax.cache<Object, Object>)cache.getNativeCache();
for(Cache.Entry<Object,Object> entry : nativeCache){
//access the entries here.
}

Is it possible to index a simple infinispan cache?

I want to index my cache to have better response time for my serachs in the cache.
Here how I implemented the infinispan cache :
private Cache createCache(String cacheName) {
try {
final Configuration configuration = new ConfigurationBuilder()
.indexing()
.addIndexedEntity(MyEntity.class)
.simpleCache(true)
.statistics().enable()
.build();
cacheManager.defineConfiguration(cacheName, configuration);
}catch (RuntimeException ex){
}
return cacheManager.getCache(cacheName);
}
But I got he following exception :
ISPN000436: Cache 'MyCache' has been requested, but no matching cache configuration exists
Any idea about the reason of error ?
Simple caches cannot enable indexing. See: https://infinispan.org/docs/stable/titles/configuring/configuring.html#simple-caches_caches

Does Google Guava Cache do deduplication when refreshing value of the same key

I implemented a non-blocking cache using Google Guava, there's only one key in the cache, and value for the key is only refreshed asynchronously (by overriding reload()).
My question is that does Guava cache handle de-duplication if the first reload() task hasn't finished, and a new get() request comes in.
//Cache is defined like below
this.cache = CacheBuilder
.newBuilder()
.maximumSize(1)
.refreshAfterWrite(10, TimeUnit.MINUTES)
.recordStats()
.build(loader);
//reload is overwritten asynchronously
#Override
public ListenableFuture<Map<String, CertificateInfo>> reload(final String key, Map<String, CertificateInfo> prevMap) throws IOException {
LOGGER.info("Refreshing certificate cache.");
ListenableFutureTask<Map<String, CertificateInfo>> task = ListenableFutureTask.create(new Callable<Map<String, CertificateInfo>>() {
#Override
public Map<String, CertificateInfo> call() throws Exception {
return actuallyLoad();
}
});
executor.execute(task);
return task;
}
Yes, see the documentation for LoadingCache.get(K) (and it sibling, Cache.get(K, Runnable)):
If another call to get(K) or getUnchecked(K) is currently loading the value for key, simply waits for that thread to finish and returns its loaded value.
So if a cache entry is currently being computed (or reloaded/recomputed), other threads that try to retrieve that entry will simply wait for the computation to finish - they will not kick off their own redundant refresh.

Difference Between cacheNames and Key in #cachable

I am new to caching and Spring, I can't work out the difference between cacheNames and Key in below example taken from Spring Docs:
#Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
As I understand cache is simply a key-value pair stored in memory. So in the above example on first invocation the returned Book value will be stored in cache using the value of isbn parameter as key. On subsequent invocations where isbn value is the same as it was first requested the Book stored in cache will be returned. This Book in cache will be found using the Key. So what is cacheNames?
Am I correct in saying cache is stored as key values like this:
isbn111111 ---> Book,
isbn122222 ---> Book2,
isbn123333 ---> Book3
Thanks in advance.
CacheName is more like group of cache key. When you open this class
org.springframework.cache.interceptor.AbstractCacheResolver
you will find this method to find cache by cacheName
#Override
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
Collection<String> cacheNames = getCacheNames(context);
if (cacheNames == null) {
return Collections.emptyList();
}
Collection<Cache> result = new ArrayList<>(cacheNames.size());
for (String cacheName : cacheNames) {
Cache cache = getCacheManager().getCache(cacheName);
if (cache == null) {
throw new IllegalArgumentException("Cannot find cache named '" +
cacheName + "' for " + context.getOperation());
}
result.add(cache);
}
return result;
}
So later in org.springframework.cache.interceptor.CacheAspectSupport spring will get value by cache key from that cache object
private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
// Special handling of synchronized invocation
if (contexts.isSynchronized()) {
CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();
if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {
Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);
Cache cache = context.getCaches().iterator().next();
try {
return wrapCacheValue(method, cache.get(key, () -> unwrapReturnValue(invokeOperation(invoker))));
}
catch (Cache.ValueRetrievalException ex) {
// The invoker wraps any Throwable in a ThrowableWrapper instance so we
// can just make sure that one bubbles up the stack.
throw (CacheOperationInvoker.ThrowableWrapper) ex.getCause();
}
}
//...other logic
The cacheNames are the names of the caches itself, where the data is stored. You can have multiple caches, e.g. for different entity types different caches, or depending on replication needs etc.
One significance of cacheNames would be helping with default key generation for #Cacheable used when explicit keys aren't passed to method. Its very unclear from Spring documentation on what would be seriously wrong or inaccurate if cacheNames is not supplied at Class level or Method level when using Spring Cache.
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/cache/annotation/CacheConfig.html#cacheNames--

Use ehcache to implement a multimap

Is it possible to use ehcache to implement a multimap? I would like to store duplicate keys that store different values and expire after a given time. Ehcache can easily handle the expiration of elements, but I am not aware of a configuration to allow duplicate keys.
Ehcache does not support duplicate keys. You could always cache a collection of values as long as a single expiration for all values makes sense.
you can use infinispan in this
#Test
public void testMultimapCache() throws Exception {
EmbeddedCacheManager cacheManager = new DefaultCacheManager(Environment.openClasspathResource("/infinispan.xml"));
MultimapCacheManager<String, Object> multimapCacheManager = EmbeddedMultimapCacheManagerFactory.from(cacheManager);
MultimapCache<String, Object> cache = multimapCacheManager.get("test");
cache.put("a", new Integer(1));
cache.put("a", new Integer(2));
cache.put("a", new Integer(3));
cache.put("a", new Integer(4));
cache.put("a", new Integer(1));
System.out.println(cache.get("a").get());
// [1, 2, 3, 4]
}

Resources