package org.infinispan.notifications.cachelistener.cluster; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import java.util.Collection; import javax.transaction.HeuristicMixedException; import javax.transaction.HeuristicRollbackException; import javax.transaction.NotSupportedException; import javax.transaction.RollbackException; import javax.transaction.SystemException; import javax.transaction.TransactionManager; import org.infinispan.Cache; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.distribution.MagicKey; import org.infinispan.notifications.cachelistener.event.CacheEntryEvent; import org.infinispan.notifications.cachelistener.event.Event; import org.testng.annotations.Test; /** * This is a base class defining tests that are common across transactional tests when dealing with a cluster listener * * @author wburns * @since 4.0 */ @Test(groups = "functional") public abstract class AbstractClusterListenerTxTest extends AbstractClusterListenerTest { protected AbstractClusterListenerTxTest(CacheMode cacheMode) { super(true, cacheMode); } // Checks the given events to see if an entry was marked as being created for the provided key and value // Note this will have to iterate over all the events until one is found, since it is possible to get the events in // non-deterministic order since they aren't from the same node protected void verifyCreation(Collection<CacheEntryEvent> events, Object key, Object expectedValue) { boolean found = false; for (CacheEntryEvent event : events) { if (Event.Type.CACHE_ENTRY_CREATED == event.getType() && key.equals(event.getKey()) && expectedValue.equals(event.getValue())) { found = true; break; } } assertTrue(found, "No entry was created in provided events " + events + " matching key " + key + " and value " + expectedValue); } @Test public void testBatchedCommitOriginatorNotLocal() throws SystemException, NotSupportedException, HeuristicRollbackException, HeuristicMixedException, RollbackException { Cache<Object, String> cache0 = cache(0, CACHE_NAME); Cache<Object, String> cache1 = cache(1, CACHE_NAME); Cache<Object, String> cache2 = cache(2, CACHE_NAME); ClusterListener clusterListener = new ClusterListener(); cache0.addListener(clusterListener); MagicKey key1 = new MagicKey(cache1, cache2); MagicKey key2 = new MagicKey(cache2, cache1); TransactionManager tm = cache2.getAdvancedCache().getTransactionManager(); tm.begin(); cache2.put(key1, FIRST_VALUE); assertEquals(clusterListener.events.size(), 0); cache2.put(key2, SECOND_VALUE); assertEquals(clusterListener.events.size(), 0); tm.commit(); assertEquals(clusterListener.events.size(), 2); verifyCreation(clusterListener.events, key1, FIRST_VALUE); verifyCreation(clusterListener.events, key2, SECOND_VALUE); } @Test public void testBatchedCommitKeyNotLocalLocal() throws HeuristicRollbackException, RollbackException, HeuristicMixedException, SystemException, NotSupportedException { Cache<Object, String> cache0 = cache(0, CACHE_NAME); Cache<Object, String> cache1 = cache(1, CACHE_NAME); Cache<Object, String> cache2 = cache(2, CACHE_NAME); ClusterListener clusterListener = new ClusterListener(); cache0.addListener(clusterListener); MagicKey key1 = new MagicKey(cache1, cache2); MagicKey key2 = new MagicKey(cache2, cache1); TransactionManager tm = cache2.getAdvancedCache().getTransactionManager(); tm.begin(); cache0.put(key1, FIRST_VALUE); assertEquals(clusterListener.events.size(), 0); cache0.put(key2, SECOND_VALUE); assertEquals(clusterListener.events.size(), 0); tm.commit(); assertEquals(clusterListener.events.size(), 2); verifyCreation(clusterListener.events, key1, FIRST_VALUE); verifyCreation(clusterListener.events, key2, SECOND_VALUE); } @Test public void testBatchedCommitLocal() throws HeuristicRollbackException, RollbackException, HeuristicMixedException, SystemException, NotSupportedException { Cache<Object, String> cache0 = cache(0, CACHE_NAME); Cache<Object, String> cache1 = cache(1, CACHE_NAME); Cache<Object, String> cache2 = cache(2, CACHE_NAME); ClusterListener clusterListener = new ClusterListener(); cache0.addListener(clusterListener); MagicKey key1 = new MagicKey(cache0); MagicKey key2 = new MagicKey(cache1, cache0); TransactionManager tm = cache2.getAdvancedCache().getTransactionManager(); tm.begin(); cache0.put(key1, FIRST_VALUE); assertEquals(clusterListener.events.size(), 0); cache0.put(key2, SECOND_VALUE); assertEquals(clusterListener.events.size(), 0); tm.commit(); assertEquals(clusterListener.events.size(), 2); verifyCreation(clusterListener.events, key1, FIRST_VALUE); verifyCreation(clusterListener.events, key2, SECOND_VALUE); } @Test public void testRolledBackNotLocal() throws SystemException, NotSupportedException { Cache<Object, String> cache0 = cache(0, CACHE_NAME); Cache<Object, String> cache1 = cache(1, CACHE_NAME); Cache<Object, String> cache2 = cache(2, CACHE_NAME); ClusterListener clusterListener = new ClusterListener(); cache0.addListener(clusterListener); MagicKey key1 = new MagicKey(cache1, cache2); MagicKey key2 = new MagicKey(cache2, cache1); TransactionManager tm = cache2.getAdvancedCache().getTransactionManager(); tm.begin(); cache2.put(key1, FIRST_VALUE); assertEquals(clusterListener.events.size(), 0); cache2.put(key2, SECOND_VALUE); assertEquals(clusterListener.events.size(), 0); tm.rollback(); assertEquals(clusterListener.events.size(), 0); } @Test public void testRolledBackOriginatorNotLocal() throws SystemException, NotSupportedException { Cache<Object, String> cache0 = cache(0, CACHE_NAME); Cache<Object, String> cache1 = cache(1, CACHE_NAME); Cache<Object, String> cache2 = cache(2, CACHE_NAME); ClusterListener clusterListener = new ClusterListener(); cache0.addListener(clusterListener); MagicKey key1 = new MagicKey(cache0); MagicKey key2 = new MagicKey(cache1, cache0); TransactionManager tm = cache2.getAdvancedCache().getTransactionManager(); tm.begin(); cache2.put(key1, FIRST_VALUE); assertEquals(clusterListener.events.size(), 0); cache2.put(key2, SECOND_VALUE); assertEquals(clusterListener.events.size(), 0); tm.rollback(); assertEquals(clusterListener.events.size(), 0); } @Test public void testRolledBackLocal() throws SystemException, NotSupportedException { Cache<Object, String> cache0 = cache(0, CACHE_NAME); Cache<Object, String> cache1 = cache(1, CACHE_NAME); Cache<Object, String> cache2 = cache(2, CACHE_NAME); ClusterListener clusterListener = new ClusterListener(); cache0.addListener(clusterListener); MagicKey key1 = new MagicKey(cache0); MagicKey key2 = new MagicKey(cache1, cache0); TransactionManager tm = cache2.getAdvancedCache().getTransactionManager(); tm.begin(); cache0.put(key1, FIRST_VALUE); assertEquals(clusterListener.events.size(), 0); cache0.put(key2, SECOND_VALUE); assertEquals(clusterListener.events.size(), 0); tm.rollback(); assertEquals(clusterListener.events.size(), 0); } @Test public void testMultipleKeysSameOwnerBatchNotified() throws SystemException, NotSupportedException, HeuristicRollbackException, HeuristicMixedException, RollbackException { Cache<Object, String> cache0 = cache(0, CACHE_NAME); Cache<Object, String> cache1 = cache(1, CACHE_NAME); Cache<Object, String> cache2 = cache(2, CACHE_NAME); ClusterListener clusterListener = new ClusterListener(); cache0.addListener(clusterListener); MagicKey key1 = new MagicKey(cache1); MagicKey key2 = new MagicKey(cache1); TransactionManager tm = cache2.getAdvancedCache().getTransactionManager(); tm.begin(); cache2.put(key1, FIRST_VALUE); assertEquals(clusterListener.events.size(), 0); cache2.put(key2, SECOND_VALUE); assertEquals(clusterListener.events.size(), 0); tm.commit(); assertEquals(clusterListener.events.size(), 2); verifyCreation(clusterListener.events, key1, FIRST_VALUE); verifyCreation(clusterListener.events, key2, SECOND_VALUE); } }