/* * JBoss, Home of Professional Open Source * Copyright 2009 Red Hat Inc. and/or its affiliates and other * contributors as indicated by the @author tags. All rights reserved. * See the copyright.txt in the distribution for a full listing of * individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ /* * * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.infinispan.replication; import org.infinispan.AdvancedCache; import org.infinispan.CacheException; import org.infinispan.commands.VisitableCommand; import org.infinispan.config.Configuration; import org.infinispan.context.InvocationContext; import org.infinispan.interceptors.base.CommandInterceptor; import org.infinispan.marshall.NotSerializableException; import org.infinispan.test.MultipleCacheManagersTest; import org.infinispan.test.TestingUtil; import org.infinispan.transaction.lookup.DummyTransactionManagerLookup; import org.infinispan.transaction.tm.DummyTransactionManager; import org.infinispan.util.concurrent.IsolationLevel; import org.infinispan.util.concurrent.TimeoutException; import org.testng.annotations.Test; import javax.transaction.NotSupportedException; import javax.transaction.RollbackException; import javax.transaction.SystemException; import javax.transaction.TransactionManager; import java.io.Serializable; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.fail; @Test(groups = "functional", testName = "replication.ReplicationExceptionTest") public class ReplicationExceptionTest extends MultipleCacheManagersTest { protected void createCacheManagers() throws Throwable { Configuration configuration = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC,true) .fluent() .locking() .isolationLevel(IsolationLevel.REPEATABLE_READ) .lockAcquisitionTimeout(60000l) .transaction().transactionManagerLookup(new DummyTransactionManagerLookup()) .build(); createClusteredCaches(2, "syncReplCache", configuration); waitForClusterToForm("syncReplCache"); Configuration noTx = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC,false) .fluent() .locking() .isolationLevel(IsolationLevel.REPEATABLE_READ) .lockAcquisitionTimeout(60000l).build(); defineConfigurationOnAllManagers("syncReplCacheNoTx", noTx); Configuration replAsync = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC,true); defineConfigurationOnAllManagers("asyncReplCache", replAsync); Configuration replAsyncNoTx = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC,false); defineConfigurationOnAllManagers("asyncReplCacheNoTx", replAsyncNoTx); Configuration replQueue = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC,true) .fluent() .clustering() .async() .useReplQueue(true) .transaction().transactionManagerLookup(new DummyTransactionManagerLookup()) .build(); defineConfigurationOnAllManagers("replQueueCache", replQueue); Configuration asyncMarshall = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC,true) .fluent() .clustering() .async() .asyncMarshalling(true) .transaction().transactionManagerLookup(new DummyTransactionManagerLookup()) .build(); defineConfigurationOnAllManagers("asyncMarshallCache", asyncMarshall); } private TransactionManager beginTransaction() throws SystemException, NotSupportedException { AdvancedCache cache1 = cache(0, "syncReplCache").getAdvancedCache(); TransactionManager mgr = TestingUtil.getTransactionManager(cache1); mgr.begin(); return mgr; } public void testNonSerializableRepl() throws Exception { doNonSerializableReplTest("syncReplCacheNoTx"); } public void testNonSerializableAsyncRepl() throws Exception { doNonSerializableReplTest("asyncReplCacheNoTx"); } public void testNonSerializableReplQueue() throws Exception { doNonSerializableReplTest("replQueueCache"); } public void testNonSerializableAsyncMarshalling() throws Exception { doNonSerializableReplTest("asyncMarshallCache"); } private void doNonSerializableReplTest(String cacheName) { AdvancedCache cache1 = cache(0, cacheName).getAdvancedCache(); AdvancedCache cache2 = cache(1, cacheName).getAdvancedCache(); try { cache1.put("test", new ContainerData()); // We should not come here. assertNotNull("NonSerializableData should not be null on cache2", cache2.get("test")); } catch (RuntimeException runtime) { Throwable t = runtime.getCause(); if (runtime instanceof NotSerializableException || t instanceof NotSerializableException || t.getCause() instanceof NotSerializableException) { System.out.println("received NotSerializableException - as expected"); } else { throw runtime; } } } public void testNonSerializableReplWithTx() throws Exception { AdvancedCache cache1 = cache(0, "syncReplCache").getAdvancedCache(); AdvancedCache cache2 = cache(1, "syncReplCache").getAdvancedCache(); TransactionManager tm; try { tm = beginTransaction(); cache1.put("test", new ContainerData()); tm.commit(); // We should not come here. assertNotNull("NonSerializableData should not be null on cache2", cache2.get("test")); } catch (RollbackException rollback) { System.out.println("received RollbackException - as expected"); } catch (Exception e) { // We should also examine that it is indeed throwing a NonSerilaizable exception. fail(e.toString()); } } @Test(groups = "functional", expectedExceptions = { CacheException.class }) public void testSyncReplTimeout() { AdvancedCache cache1 = cache(0, "syncReplCache").getAdvancedCache(); AdvancedCache cache2 = cache(1, "syncReplCache").getAdvancedCache(); cache2.addInterceptor(new CommandInterceptor() { @Override protected Object handleDefault(InvocationContext ctx, VisitableCommand cmd) throws Throwable { // Add a delay Thread.sleep(100); return super.handleDefault(ctx, cmd); } }, 0); cache1.getConfiguration().setSyncReplTimeout(10); cache2.getConfiguration().setSyncReplTimeout(10); TestingUtil.blockUntilViewsReceived(10000, cache1, cache2); cache1.put("k", "v"); } @Test(groups = "functional", expectedExceptions = { CacheException.class }) public void testLockAcquisitionTimeout() throws Exception { AdvancedCache cache1 = cache(0, "syncReplCache").getAdvancedCache(); AdvancedCache cache2 = cache(1, "syncReplCache").getAdvancedCache(); cache1.getConfiguration().setLockAcquisitionTimeout(10); cache2.getConfiguration().setLockAcquisitionTimeout(10); TestingUtil.blockUntilViewsReceived(10000, cache1, cache2); // get a lock on cache 2 and hold on to it. DummyTransactionManager tm = (DummyTransactionManager) TestingUtil.getTransactionManager(cache2); tm.begin(); cache2.put("block", "block"); assert tm.getTransaction().runPrepare(); tm.suspend(); cache1.put("block", "v"); } static class NonSerializabeData { int i; } public static class ContainerData implements Serializable { int i; NonSerializabeData non_serializable_data; private static final long serialVersionUID = -8322197791060897247L; public ContainerData() { i = 99; non_serializable_data = new NonSerializabeData(); } } }