package org.infinispan.jcache;
import static org.infinispan.test.TestingUtil.withCacheManager;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.cache.Cache;
import javax.cache.configuration.Factory;
import javax.cache.configuration.FactoryBuilder;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.Duration;
import javax.cache.expiry.ExpiryPolicy;
import javax.cache.integration.CompletionListenerFuture;
import org.infinispan.AdvancedCache;
import org.infinispan.commons.util.CollectionFactory;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.container.DataContainer;
import org.infinispan.jcache.embedded.JCacheManager;
import org.infinispan.jcache.util.InMemoryJCacheLoader;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.persistence.dummy.DummyInMemoryStore;
import org.infinispan.persistence.dummy.DummyInMemoryStoreConfigurationBuilder;
import org.infinispan.test.AbstractInfinispanTest;
import org.infinispan.test.CacheManagerCallable;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.infinispan.util.ControlledTimeService;
import org.infinispan.util.TimeService;
import org.testng.annotations.Test;
/**
* Tests JCache behavior when plugged with cache loaders.
*
* @author Galder ZamarreƱo
* @since 6.0
*/
@Test(groups = "functional", testName = "jcache.JCacheLoaderTest")
public class JCacheLoaderTest extends AbstractInfinispanTest {
public void testLoadAllWithJCacheLoader(Method m) {
final String cacheName = m.getName();
// GlobalConfigurationBuilder globalBuilder = new GlobalConfigurationBuilder();
// globalBuilder.asyncTransportExecutor().addProperty("maxThreads", "1");
withCacheManager(new CacheManagerCallable(
TestCacheManagerFactory.createCacheManager(false)) {
@Override
public void call() {
JCacheManager jCacheManager = createJCacheManager(cm, this);
InMemoryJCacheLoader<Integer, String> cacheLoader = new InMemoryJCacheLoader<Integer, String>();
cacheLoader.store(1, "v1").store(2, "v2");
MutableConfiguration<Integer, String> cfg = new MutableConfiguration<Integer, String>();
// JDK6 fails to compile when calling FactoryBuilder.factoryOf() :(
cfg.setCacheLoaderFactory(new FactoryBuilder.SingletonFactory(cacheLoader));
Cache<Integer, String> cache = jCacheManager.createCache(cacheName, cfg);
assertEquals(0, cacheLoader.getLoadCount());
CompletionListenerFuture future = new CompletionListenerFuture();
cache.loadAll(CollectionFactory.makeSet(1, 2), true, future);
futureGet(future);
assertEquals(2, cacheLoader.getLoadCount());
}
});
}
public void testLoadAllWithInfinispanCacheLoader() {
withCacheManager(new CacheManagerCallable(
TestCacheManagerFactory.createCacheManager(false)) {
@Override
public void call() {
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.persistence()
.addStore(DummyInMemoryStoreConfigurationBuilder.class)
.storeName(this.getClass().getName());
cm.defineConfiguration("dummyStore", builder.build());
JCacheManager jCacheManager = createJCacheManager(cm, this);
Cache<Integer, String> cache = jCacheManager.getCache("dummyStore");
// Load initial data in cache store
int numEntries = loadInitialData(cm);
DummyInMemoryStore dummyStore = TestingUtil.getFirstWriter(cm.getCache("dummyStore"));
// Load all from cache store
CompletionListenerFuture future = new CompletionListenerFuture();
Set<Integer> keys = Collections.singleton(1);
cache.loadAll(keys, false, future);
futureGet(future); // wait for key to be loaded
assertTrue(future.isDone());
assertEquals(numEntries, dummyStore.stats().get("load").intValue());
// Load from memory
assertEquals("v1", cache.get(1));
// Load again from cache store, overriding in-memory contents
future = new CompletionListenerFuture();
cache.loadAll(keys, true, future);
futureGet(future); // wait for key to be loaded
assertTrue(future.isDone());
assertEquals(numEntries * 2, dummyStore.stats().get("load").intValue());
}
});
}
public void testLoadEntryWithExpiration(Method m) {
final String cacheName = m.getName();
withCacheManager(new CacheManagerCallable(
TestCacheManagerFactory.createCacheManager(false)) {
@Override
public void call() {
ControlledTimeService timeService = new ControlledTimeService();
TestingUtil.replaceComponent(cm, TimeService.class, timeService, true);
JCacheManager jCacheManager = createJCacheManager(cm, this);
InMemoryJCacheLoader<Integer, String> cacheLoader = new InMemoryJCacheLoader<Integer, String>();
cacheLoader.store(1, "v1").store(2, "v2");
MutableConfiguration<Integer, String> cfg = new MutableConfiguration<Integer, String>();
final long lifespan = 3000;
cfg.setReadThrough(true);
cfg.setExpiryPolicyFactory(new Factory<ExpiryPolicy>() {
@Override
public ExpiryPolicy create() {
return new ExpiryPolicy() {
@Override
public Duration getExpiryForCreation() {
return new Duration(TimeUnit.MILLISECONDS, lifespan);
}
@Override
public Duration getExpiryForAccess() {
return null;
}
@Override
public Duration getExpiryForUpdate() {
return Duration.ZERO;
}
};
}
});
// JDK6 fails to compile when calling FactoryBuilder.factoryOf() :(
cfg.setCacheLoaderFactory(new FactoryBuilder.SingletonFactory(cacheLoader));
Cache<Integer, String> cache = jCacheManager.createCache(cacheName, cfg);
assertEquals("v2", cache.get(2));
assertEquals("v1", cache.get(1));
timeService.advance(lifespan + 100);
DataContainer<Integer, String> dc = cache.unwrap(AdvancedCache.class).getDataContainer();
assertEquals(null, dc.get(2));
assertEquals(null, dc.get(1));
}
});
}
private Void futureGet(CompletionListenerFuture future) {
try {
return future.get();
} catch (Throwable t) {
throw new AssertionError(t);
}
}
private static int loadInitialData(EmbeddedCacheManager cm) {
TestingUtil.writeToAllStores(1, "v1", cm.getCache("dummyStore"));
return 1;
}
private static JCacheManager createJCacheManager(EmbeddedCacheManager cm, Object creator) {
return new JCacheManager(URI.create(creator.getClass().getName()), cm, null);
}
}