package org.infinispan.persistence;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.infinispan.api.mvcc.LockAssert.assertNoLocks;
import static org.infinispan.test.TestingUtil.k;
import static org.infinispan.test.TestingUtil.v;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.fail;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import org.infinispan.AdvancedCache;
import org.infinispan.Cache;
import org.infinispan.commons.marshall.StreamingMarshaller;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.container.DataContainer;
import org.infinispan.container.entries.InternalCacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.eviction.EvictionStrategy;
import org.infinispan.lifecycle.ComponentStatus;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.marshall.core.MarshalledEntry;
import org.infinispan.marshall.core.MarshalledEntryImpl;
import org.infinispan.persistence.dummy.DummyInMemoryStoreConfigurationBuilder;
import org.infinispan.persistence.spi.AdvancedCacheLoader;
import org.infinispan.persistence.spi.AdvancedCacheWriter;
import org.infinispan.persistence.spi.AdvancedLoadWriteStore;
import org.infinispan.persistence.spi.CacheLoader;
import org.infinispan.persistence.spi.PersistenceException;
import org.infinispan.test.AbstractInfinispanTest;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.infinispan.transaction.TransactionMode;
import org.infinispan.util.concurrent.IsolationLevel;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* Tests the interceptor chain and surrounding logic
*
* @author Manik Surtani
*/
@Test(groups = "functional", testName = "persistence.CacheLoaderFunctionalTest")
public class CacheLoaderFunctionalTest extends AbstractInfinispanTest {
private static final Log log = LogFactory.getLog(CacheLoaderFunctionalTest.class);
Cache<String, String> cache;
AdvancedLoadWriteStore<String, String> store;
AdvancedCacheWriter<String, String> writer;
TransactionManager tm;
ConfigurationBuilder cfg;
EmbeddedCacheManager cm;
StreamingMarshaller sm;
long lifespan = 60000000; // very large lifespan so nothing actually expires
@BeforeMethod(alwaysRun = true)
public void setUp() {
cfg = getConfiguration();
configure(cfg);
cm = TestCacheManagerFactory.createCacheManager(cfg);
cache = getCache(cm);
store = TestingUtil.getFirstLoader(cache);
writer = TestingUtil.getFirstLoader(cache);
tm = TestingUtil.getTransactionManager(cache);
sm = cache.getAdvancedCache().getComponentRegistry().getCacheMarshaller();
}
protected ConfigurationBuilder getConfiguration() {
ConfigurationBuilder cfg = new ConfigurationBuilder();
cfg.persistence()
.addStore(DummyInMemoryStoreConfigurationBuilder.class)
.storeName(this.getClass().getName()) // in order to use the same store
.transaction().transactionMode(TransactionMode.TRANSACTIONAL);
return cfg;
}
protected Cache<String, String> getCache(EmbeddedCacheManager cm) {
return cm.getCache();
}
protected Cache<String, String> getCache(EmbeddedCacheManager cm, String name) {
return cm.getCache(name);
}
protected void configure(ConfigurationBuilder cb) { }
@AfterMethod(alwaysRun = true)
public void tearDown() throws PersistenceException {
writer.clear();
TestingUtil.killCacheManagers(cm);
cache = null;
cm = null;
cfg = null;
tm = null;
store = null;
}
private void assertInCacheAndStore(String key, Object value) throws PersistenceException {
assertInCacheAndStore(key, value, -1);
}
private void assertInCacheAndStore(String key, Object value, long lifespanMillis) throws PersistenceException {
assertInCacheAndStore(cache, store, key, value, lifespanMillis);
}
private <K> void assertInCacheAndStore(Cache<? super K, ?> cache, CacheLoader store, K key, Object value) throws PersistenceException {
assertInCacheAndStore(cache, store, key, value, -1);
}
private <K> void assertInCacheAndStore(Cache<? super K, ?> cache, CacheLoader loader, K key, Object value, long lifespanMillis) throws PersistenceException {
InternalCacheEntry se = cache.getAdvancedCache().getDataContainer().get(key);
testStoredEntry(se.getValue(), value, se.getLifespan(), lifespanMillis, "Cache", key);
MarshalledEntry load = loader.load(key);
testStoredEntry(load.getValue(), value, load.getMetadata() == null ? -1 : load.getMetadata().lifespan(), lifespanMillis, "Store", key);
}
private void testStoredEntry(Object value, Object expectedValue, long lifespan, long expectedLifespan, String src, Object key) {
assertEquals("Wrong value on " + src, expectedValue, value);
assertEquals("Wrong lifespan on " + src, expectedLifespan, lifespan);
}
private static <K> void assertNotInCacheAndStore(Cache<? super K, ?> cache, CacheLoader<? super K, ?> store, K... keys) throws PersistenceException {
for (K key : keys) {
assertFalse("Cache should not contain key " + key, cache.getAdvancedCache().getDataContainer().containsKey(key));
assertFalse("Store should not contain key " + key, store.contains(key));
}
}
private void assertNotInCacheAndStore(String... keys) throws PersistenceException {
assertNotInCacheAndStore(cache, store, keys);
}
private void assertInStoreNotInCache(String... keys) throws PersistenceException {
assertInStoreNotInCache(cache, store, keys);
}
private static <K> void assertInStoreNotInCache(Cache<? super K, ?> cache, CacheLoader<? super K, ?> store, K... keys) throws PersistenceException {
for (K key : keys) {
assertFalse("Cache should not contain key " + key, cache.getAdvancedCache().getDataContainer().containsKey(key));
assertTrue("Store should contain key " + key, store.contains(key));
}
}
private void assertInCacheAndNotInStore(String... keys) throws PersistenceException {
assertInCacheAndNotInStore(cache, store, keys);
}
private static <K> void assertInCacheAndNotInStore(Cache<? super K, ?> cache, CacheLoader<? super K, ?> store, K... keys) throws PersistenceException {
for (K key : keys) {
assert cache.getAdvancedCache().getDataContainer().containsKey(key) : "Cache should not contain key " + key;
assertFalse("Store should contain key " + key, store.contains(key));
}
}
public void testStoreAndRetrieve() throws PersistenceException {
assertNotInCacheAndStore("k1", "k2", "k3", "k4", "k5", "k6", "k7");
cache.put("k1", "v1");
cache.put("k2", "v2", lifespan, MILLISECONDS);
cache.putAll(Collections.singletonMap("k3", "v3"));
cache.putAll(Collections.singletonMap("k4", "v4"), lifespan, MILLISECONDS);
cache.putIfAbsent("k5", "v5");
cache.putIfAbsent("k6", "v6", lifespan, MILLISECONDS);
cache.putIfAbsent("k5", "v5-SHOULD-NOT-PUT");
cache.putIfAbsent("k6", "v6-SHOULD-NOT-PUT", lifespan, MILLISECONDS);
cache.putForExternalRead("k7", "v7");
cache.putForExternalRead("k7", "v7-SHOULD-NOT-PUT");
for (int i = 1; i < 8; i++) {
// even numbers have lifespans
if (i % 2 == 1)
assertInCacheAndStore("k" + i, "v" + i);
else
assertInCacheAndStore("k" + i, "v" + i, lifespan);
}
assert !cache.remove("k1", "some rubbish");
for (int i = 1; i < 8; i++) {
// even numbers have lifespans
if (i % 2 == 1)
assertInCacheAndStore("k" + i, "v" + i);
else
assertInCacheAndStore("k" + i, "v" + i, lifespan);
}
log.debugf("cache.get(\"k1\") = %s", cache.get("k1"));
boolean removed = cache.remove("k1", "v1");
assertTrue(removed);
log.debugf("cache.get(\"k1\") = %s", cache.get("k1"));
assertEquals("v2", cache.remove("k2"));
assertNotInCacheAndStore("k1", "k2");
for (int i = 3; i < 8; i++) {
// even numbers have lifespans
if (i % 2 == 1)
assertInCacheAndStore("k" + i, "v" + i);
else
assertInCacheAndStore("k" + i, "v" + i, lifespan);
}
cache.clear();
assertNotInCacheAndStore("k1", "k2", "k3", "k4", "k5", "k6", "k7");
}
public void testReplaceMethods() throws PersistenceException {
assertNotInCacheAndStore("k1", "k2", "k3", "k4");
cache.replace("k1", "v1-SHOULD-NOT-STORE");
assertNoLocks(cache);
cache.replace("k2", "v2-SHOULD-NOT-STORE", lifespan, MILLISECONDS);
assertNoLocks(cache);
assertNotInCacheAndStore("k1", "k2", "k3", "k4");
cache.put("k1", "v1");
assertNoLocks(cache);
cache.put("k2", "v2");
assertNoLocks(cache);
cache.put("k3", "v3");
assertNoLocks(cache);
cache.put("k4", "v4");
assertNoLocks(cache);
for (int i = 1; i < 5; i++) assertInCacheAndStore("k" + i, "v" + i);
cache.replace("k1", "v1-SHOULD-NOT-STORE", "v1-STILL-SHOULD-NOT-STORE");
assertNoLocks(cache);
cache.replace("k2", "v2-SHOULD-NOT-STORE", "v2-STILL-SHOULD-NOT-STORE", lifespan, MILLISECONDS);
assertNoLocks(cache);
for (int i = 1; i < 5; i++) assertInCacheAndStore("k" + i, "v" + i);
cache.replace("k1", "v1-REPLACED");
assertNoLocks(cache);
cache.replace("k2", "v2-REPLACED", lifespan, MILLISECONDS);
assertInCacheAndStore("k2", "v2-REPLACED", lifespan);
assertNoLocks(cache);
cache.replace("k3", "v3", "v3-REPLACED");
assertNoLocks(cache);
cache.replace("k4", "v4", "v4-REPLACED", lifespan, MILLISECONDS);
assertNoLocks(cache);
for (int i = 1; i < 5; i++) {
// even numbers have lifespans
if (i % 2 == 1)
assertInCacheAndStore("k" + i, "v" + i + "-REPLACED");
else
assertInCacheAndStore("k" + i, "v" + i + "-REPLACED", lifespan);
}
assertNoLocks(cache);
}
public void testLoading() throws PersistenceException {
assertNotInCacheAndStore("k1", "k2", "k3", "k4");
for (int i = 1; i < 5; i++) writer.write(new MarshalledEntryImpl("k" + i, "v" + i, null, sm));
for (int i = 1; i < 5; i++) assertEquals("v" + i, cache.get("k" + i));
// make sure we have no stale locks!!
assertNoLocks(cache);
for (int i = 1; i < 5; i++) cache.evict("k" + i);
// make sure we have no stale locks!!
assertNoLocks(cache);
assertEquals("v1", cache.putIfAbsent("k1", "v1-SHOULD-NOT-STORE"));
assertEquals("v2", cache.remove("k2"));
assertEquals("v3", cache.replace("k3", "v3-REPLACED"));
assertTrue(cache.replace("k4", "v4", "v4-REPLACED"));
// make sure we have no stale locks!!
assertNoLocks(cache);
int size = cache.size();
assertEquals("Expected the cache to contain 3 elements but contained " + cache.entrySet(), 3, size);
for (int i = 1; i < 5; i++) cache.evict("k" + i);
// make sure we have no stale locks!!
assertNoLocks(cache);
assertEquals(0, cache.getAdvancedCache().getDataContainer().size()); // cache size ops will not trigger a load
cache.clear(); // this should propagate to the loader though
assertNotInCacheAndStore("k1", "k2", "k3", "k4");
// make sure we have no stale locks!!
assertNoLocks(cache);
}
public void testPreloading() throws Exception {
ConfigurationBuilder preloadingCfg = new ConfigurationBuilder();
preloadingCfg.read(cfg.build());
preloadingCfg.persistence().clearStores().addStore(DummyInMemoryStoreConfigurationBuilder.class).preload(true).storeName(this.getClass().getName() + "preloadingCache");
doPreloadingTest(preloadingCfg.build(), "preloadingCache");
}
public void testPreloadingWithoutAutoCommit() throws Exception {
ConfigurationBuilder preloadingCfg = new ConfigurationBuilder();
preloadingCfg.read(cfg.build());
preloadingCfg.persistence().clearStores().addStore(DummyInMemoryStoreConfigurationBuilder.class).preload(true).storeName(this.getClass().getName() + "preloadingCache_2");
preloadingCfg.transaction().autoCommit(false);
doPreloadingTest(preloadingCfg.build(), "preloadingCache_2");
}
public void testPreloadingWithEvictionAndOneMaxEntry() throws Exception {
ConfigurationBuilder preloadingCfg = new ConfigurationBuilder();
preloadingCfg.read(cfg.build());
preloadingCfg.persistence().clearStores().addStore(DummyInMemoryStoreConfigurationBuilder.class).preload(true).storeName(this.getClass().getName() + "preloadingCache_3");
preloadingCfg.eviction().strategy(EvictionStrategy.LIRS).maxEntries(1);
doPreloadingTestWithEviction(preloadingCfg.build(), "preloadingCache_3");
}
public void testPreloadingWithEviction() throws Exception {
ConfigurationBuilder preloadingCfg = new ConfigurationBuilder();
preloadingCfg.read(cfg.build());
preloadingCfg.persistence().clearStores().addStore(DummyInMemoryStoreConfigurationBuilder.class).preload(true).storeName(this.getClass().getName() + "preloadingCache_4");
preloadingCfg.eviction().strategy(EvictionStrategy.LIRS).maxEntries(3);
doPreloadingTestWithEviction(preloadingCfg.build(), "preloadingCache_4");
}
@Test(groups = "unstable")
public void testPurgeOnStartup() throws PersistenceException {
ConfigurationBuilder purgingCfg = new ConfigurationBuilder();
purgingCfg.read(cfg.build());
purgingCfg.persistence().clearStores().addStore(DummyInMemoryStoreConfigurationBuilder.class)
.storeName("purgingCache").purgeOnStartup(true);
cm.defineConfiguration("purgingCache", purgingCfg.build());
Cache<String, String> purgingCache = getCache(cm, "purgingCache");
AdvancedCacheLoader purgingLoader = (AdvancedCacheLoader) TestingUtil.getCacheLoader(purgingCache);
assertNotInCacheAndStore(purgingCache, purgingLoader, "k1", "k2", "k3", "k4");
purgingCache.put("k1", "v1");
purgingCache.put("k2", "v2", lifespan, MILLISECONDS);
purgingCache.put("k3", "v3");
purgingCache.put("k4", "v4", lifespan, MILLISECONDS);
for (int i = 1; i < 5; i++) {
if (i % 2 == 1)
assertInCacheAndStore(purgingCache, purgingLoader, "k" + i, "v" + i);
else
assertInCacheAndStore(purgingCache, purgingLoader, "k" + i, "v" + i, lifespan);
}
DataContainer c = purgingCache.getAdvancedCache().getDataContainer();
assertEquals(4, c.size());
purgingCache.stop();
assertEquals(0, c.size());
purgingCache.start();
purgingLoader = (AdvancedCacheLoader) TestingUtil.getCacheLoader(purgingCache);
c = purgingCache.getAdvancedCache().getDataContainer();
assertEquals(0, c.size());
assertNotInCacheAndStore(purgingCache, purgingLoader, "k1", "k2", "k3", "k4");
}
public void testTransactionalWrites() throws Exception {
assertEquals(ComponentStatus.RUNNING, cache.getStatus());
assertNotInCacheAndStore("k1", "k2");
tm.begin();
cache.put("k1", "v1");
cache.put("k2", "v2", lifespan, MILLISECONDS);
Transaction t = tm.suspend();
assertNotInCacheAndStore("k1", "k2");
tm.resume(t);
tm.commit();
assertInCacheAndStore("k1", "v1");
assertInCacheAndStore("k2", "v2", lifespan);
tm.begin();
cache.remove("k1");
cache.remove("k2");
t = tm.suspend();
assertInCacheAndStore("k1", "v1");
assertInCacheAndStore("k2", "v2", lifespan);
tm.resume(t);
tm.commit();
assertNotInCacheAndStore("k1", "k2");
tm.begin();
cache.put("k1", "v1");
cache.put("k2", "v2", lifespan, MILLISECONDS);
t = tm.suspend();
assertNotInCacheAndStore("k1", "k2");
tm.resume(t);
tm.rollback();
assertNotInCacheAndStore("k1", "k2");
cache.put("k1", "v1");
cache.put("k2", "v2", lifespan, MILLISECONDS);
assertInCacheAndStore("k1", "v1");
assertInCacheAndStore("k2", "v2", lifespan);
tm.begin();
cache.remove("k1");
cache.remove("k2");
t = tm.suspend();
assertInCacheAndStore("k1", "v1");
assertInCacheAndStore("k2", "v2", lifespan);
tm.resume(t);
tm.rollback();
assertInCacheAndStore("k1", "v1");
assertInCacheAndStore("k2", "v2", lifespan);
}
public void testTransactionalReplace(Method m) throws Exception {
assertEquals(ComponentStatus.RUNNING, cache.getStatus());
assertNotInCacheAndStore(k(m, 1));
assertNotInCacheAndStore(k(m, 2));
cache.put(k(m, 2), v(m));
tm.begin();
cache.put(k(m, 1), v(m, 1));
cache.replace(k(m, 2), v(m, 1));
Transaction t = tm.suspend();
assertNotInCacheAndStore(k(m, 1));
assertInCacheAndStore(k(m, 2), v(m));
tm.resume(t);
tm.commit();
assertInCacheAndStore(k(m, 1), v(m, 1));
assertInCacheAndStore(k(m, 2), v(m, 1));
}
public void testEvictAndRemove() throws PersistenceException {
assertNotInCacheAndStore("k1", "k2");
cache.put("k1", "v1");
cache.put("k2", "v2", lifespan, MILLISECONDS);
cache.evict("k1");
cache.evict("k2");
assertEquals("v1", cache.remove("k1"));
assertEquals("v2", cache.remove("k2"));
}
public void testLoadingToMemory() throws PersistenceException {
assertNotInCacheAndStore("k1", "k2");
store.write(new MarshalledEntryImpl("k1", "v1", null, sm));
store.write(new MarshalledEntryImpl("k2", "v2", null, sm));
assertInStoreNotInCache("k1", "k2");
assertEquals("v1", cache.get("k1"));
assertEquals("v2", cache.get("k2"));
assertInCacheAndStore("k1", "v1");
assertInCacheAndStore("k2", "v2");
store.delete("k1");
store.delete("k2");
assertInCacheAndNotInStore("k1", "k2");
assertEquals("v1", cache.get("k1"));
assertEquals("v2", cache.get("k2"));
}
public void testSkipLocking(Method m) {
String name = m.getName();
AdvancedCache<String, String> advancedCache = cache.getAdvancedCache();
advancedCache.put("k-" + name, "v-" + name);
advancedCache.withFlags(Flag.SKIP_LOCKING).put("k-" + name, "v2-" + name);
}
public void testDuplicatePersistence(Method m) throws Exception {
String key = "k-" + m.getName();
String value = "v-" + m.getName();
cache.put(key, value);
assertEquals(value, cache.get(key));
cache.stop();
cache.start();
// A new writer is created after restart
writer = TestingUtil.getFirstLoader(cache);
tm.begin();
cache.containsKey(key); // Necessary call to force locks being acquired in advance
cache.getAdvancedCache().withFlags(Flag.FORCE_WRITE_LOCK).get(key);
cache.put(key, value);
tm.commit();
assertEquals(value, cache.get(key));
}
public void testNullFoundButLoaderReceivedValueLaterInTransaction() throws SystemException, NotSupportedException {
assertNotInCacheAndStore("k1");
tm.begin();
try {
assertNull(cache.get("k1"));
// Now simulate that someone else wrote to the store while during our tx
store.write(new MarshalledEntryImpl("k1", "v1", null, sm));
IsolationLevel level = cache.getCacheConfiguration().locking().isolationLevel();
switch(level) {
case READ_COMMITTED:
assertEquals("v1", cache.get("k1"));
break;
case REPEATABLE_READ:
assertNull(cache.get("k1"));
break;
default:
fail("Unsupported isolation " + level + " - please change test to add desired outcome for isolation level");
}
} finally {
tm.rollback();
}
}
public void testValuesForCacheLoader() {
cache.putIfAbsent("k1", "v1");
List<String> copy1 = copyValues(cache);
assertEquals(1, copy1.size());
assertEquals("v1", copy1.get(0));
cache.putIfAbsent("k2", "v2");
List<String> copy2 = copyValues(cache);
assertEquals(2, copy2.size());
assertEquals(Arrays.asList("v1", "v2"), copy2);
}
private List<String> copyValues(Cache<?, String> cache) {
return new ArrayList<>(cache.values());
}
protected void doPreloadingTest(Configuration preloadingCfg, String cacheName) throws Exception {
assertTrue("Preload not enabled for preload test", preloadingCfg.persistence().preload());
cm.defineConfiguration(cacheName, preloadingCfg);
Cache<String, String> preloadingCache = getCache(cm, cacheName);
AdvancedCacheLoader preloadingCacheLoader = (AdvancedCacheLoader) TestingUtil.getCacheLoader(preloadingCache);
assert preloadingCache.getCacheConfiguration().persistence().preload();
assertNotInCacheAndStore(preloadingCache, preloadingCacheLoader, "k1", "k2", "k3", "k4");
preloadingCache.getAdvancedCache().getTransactionManager().begin();
preloadingCache.put("k1", "v1");
preloadingCache.put("k2", "v2", lifespan, MILLISECONDS);
preloadingCache.put("k3", "v3");
preloadingCache.put("k4", "v4", lifespan, MILLISECONDS);
preloadingCache.getAdvancedCache().getTransactionManager().commit();
for (int i = 1; i < 5; i++) {
if (i % 2 == 1)
assertInCacheAndStore(preloadingCache, preloadingCacheLoader, "k" + i, "v" + i);
else
assertInCacheAndStore(preloadingCache, preloadingCacheLoader, "k" + i, "v" + i, lifespan);
}
DataContainer c = preloadingCache.getAdvancedCache().getDataContainer();
assertEquals(4, c.size());
preloadingCache.stop();
assertEquals(0, c.size());
preloadingCache.start();
// The old store's marshaller is not working any more
preloadingCacheLoader = (AdvancedCacheLoader) TestingUtil.getCacheLoader(preloadingCache);
assert preloadingCache.getCacheConfiguration().persistence().preload();
c = preloadingCache.getAdvancedCache().getDataContainer();
assertEquals(4, c.size());
for (int i = 1; i < 5; i++) {
if (i % 2 == 1)
assertInCacheAndStore(preloadingCache, preloadingCacheLoader, "k" + i, "v" + i);
else
assertInCacheAndStore(preloadingCache, preloadingCacheLoader, "k" + i, "v" + i, lifespan);
}
}
protected void doPreloadingTestWithEviction(Configuration preloadingCfg, String cacheName) throws Exception {
assertTrue("Preload not enabled for preload with eviction test", preloadingCfg.persistence().preload());
assertTrue("Eviction not enabled for preload with eviction test", preloadingCfg.eviction().strategy().isEnabled());
cm.defineConfiguration(cacheName, preloadingCfg);
final Cache<String, String> preloadingCache = getCache(cm, cacheName);
final long expectedEntriesInContainer = Math.min(4l, preloadingCfg.eviction().maxEntries());
AdvancedCacheLoader preloadingCacheLoader = (AdvancedCacheLoader) TestingUtil.getCacheLoader(preloadingCache);
assertTrue("Preload not enabled in cache configuration",
preloadingCache.getCacheConfiguration().persistence().preload());
assertNotInCacheAndStore(preloadingCache, preloadingCacheLoader, "k1", "k2", "k3", "k4");
preloadingCache.getAdvancedCache().getTransactionManager().begin();
preloadingCache.put("k1", "v1");
preloadingCache.put("k2", "v2", lifespan, MILLISECONDS);
preloadingCache.put("k3", "v3");
preloadingCache.put("k4", "v4", lifespan, MILLISECONDS);
preloadingCache.getAdvancedCache().getTransactionManager().commit();
DataContainer c = preloadingCache.getAdvancedCache().getDataContainer();
assertEquals("Wrong number of entries in data container", expectedEntriesInContainer, c.size());
for (int i = 1; i < 5; i++) {
final String key = "k" + i;
final Object value = "v" + i;
final long lifespan = i % 2 == 1 ? -1 : this.lifespan;
boolean found = false;
InternalCacheEntry se = preloadingCache.getAdvancedCache().getDataContainer().get(key);
MarshalledEntry load = preloadingCacheLoader.load(key);
if (se != null) {
testStoredEntry(se.getValue(), value, se.getLifespan(), lifespan, "Cache", key);
found = true;
}
if (load != null) {
testStoredEntry(load.getValue(), value, load.getMetadata().lifespan(), lifespan, "Store", key);
found = true;
}
assertTrue("Key not found.", found);
}
preloadingCache.stop();
assertEquals("DataContainer still has entries after stop", 0, c.size());
preloadingCache.start();
// The old store's marshaller is not working any more
preloadingCacheLoader = (AdvancedCacheLoader) TestingUtil.getCacheLoader(preloadingCache);
assertTrue("Preload not enabled in cache configuration",
preloadingCache.getCacheConfiguration().persistence().preload());
c = preloadingCache.getAdvancedCache().getDataContainer();
assertEquals("Wrong number of entries in data container", expectedEntriesInContainer, c.size());
for (int i = 1; i < 5; i++) {
final String key = "k" + i;
final Object value = "v" + i;
final long lifespan = i % 2 == 1 ? -1 : this.lifespan;
boolean found = false;
InternalCacheEntry se = preloadingCache.getAdvancedCache().getDataContainer().get(key);
MarshalledEntry load = preloadingCacheLoader.load(key);
if (se != null) {
testStoredEntry(se.getValue(), value, se.getLifespan(), lifespan, "Cache", key);
found = true;
}
if (load != null) {
testStoredEntry(load.getValue(), value, load.getMetadata().lifespan(), lifespan, "Store", key);
found = true;
}
assertTrue("Key not found.", found);
}
}
}