/* * JBoss, Home of Professional Open Source. * Copyright 2015, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file 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. */ package com.arjuna.ats.jta.distributed.spi; import com.arjuna.ats.arjuna.common.RecoveryEnvironmentBean; import com.arjuna.ats.internal.jts.ORBManager; import com.arjuna.ats.jta.common.JTAEnvironmentBean; import com.arjuna.ats.jta.common.jtaPropertyManager; import com.arjuna.ats.jta.distributed.JndiProvider; import com.arjuna.ats.jta.utils.JNDIManager; import com.arjuna.common.internal.util.propertyservice.BeanPopulator; import com.arjuna.orbportability.common.OrbPortabilityEnvironmentBean; import com.arjuna.orbportability.internal.utils.PostInitLoader; import org.jboss.tm.TransactionManagerLocator; import org.jboss.tm.listener.EventType; import org.jboss.tm.listener.TransactionListenerRegistry; import org.jboss.tm.listener.TransactionListenerRegistryLocator; import org.jboss.tm.usertx.UserTransactionRegistry; import org.jboss.tm.usertx.client.ServerVMClientUserTransaction; import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; import javax.naming.InitialContext; import javax.transaction.*; import java.util.*; import com.arjuna.orbportability.OA; import com.arjuna.orbportability.ORB; import com.arjuna.orbportability.RootOA; import org.omg.CORBA.ORBPackage.InvalidName; import static org.junit.Assert.*; import static org.junit.Assert.assertTrue; public class SPIUnitTest { private static InitialContext initialContext; private static ORB myORB = null; private static RootOA myOA = null; private static void initORB() throws InvalidName { myORB = ORB.getInstance("test"); myOA = OA.getRootOA(myORB); myORB.initORB(new String[]{}, null); myOA.initOA(); ORBManager.setORB(myORB); ORBManager.setPOA(myOA); new PostInitLoader(PostInitLoader.generateORBPropertyName("com.arjuna.orbportability.orb"), myORB); } public static void initJTS() throws Exception { initORB(); JTAEnvironmentBean jtaEnvironmentBean = jtaPropertyManager.getJTAEnvironmentBean(); jtaEnvironmentBean.setTransactionManagerClassName(com.arjuna.ats.jbossatx.jts.TransactionManagerDelegate.class.getName()); JNDIManager.bindJTATransactionManagerImplementation(initialContext); jtaEnvironmentBean.setTransactionSynchronizationRegistryClassName(com.arjuna.ats.internal.jta.transaction.jts.TransactionSynchronizationRegistryImple.class.getName()); JNDIManager.bindJTATransactionSynchronizationRegistryImplementation(initialContext); final com.arjuna.ats.jbossatx.jts.TransactionManagerService service = new com.arjuna.ats.jbossatx.jts.TransactionManagerService(); final ServerVMClientUserTransaction userTransaction = new ServerVMClientUserTransaction(service.getTransactionManager()); jtaEnvironmentBean.setUserTransaction(userTransaction); JNDIManager.bindJTAUserTransactionImplementation(initialContext); UserTransactionRegistry userTransactionRegistry = new UserTransactionRegistry(); userTransactionRegistry.addProvider(userTransaction); } private UserTransaction getUserTransaction() { return jtaPropertyManager.getJTAEnvironmentBean().getUserTransaction(); } private TransactionManager getTransactionManager() { return jtaPropertyManager.getJTAEnvironmentBean().getTransactionManager(); } @BeforeClass public static void setUp() throws Exception { Hashtable props = JndiProvider.start(); initialContext = new InitialContext(props); initJTS(); BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).setRecoveryBackoffPeriod(1); } @After public void cleanThread() { TransactionManager tm = TransactionManagerLocator.locateTransactionManager(); try { Transaction txn = tm.getTransaction(); if (txn != null) txn.rollback(); } catch (SystemException e) { } catch (Error error) { } } @Test public void testListener() { TransactionManager tm = TransactionManagerLocator.locateTransactionManager(); Transaction prevTxn = null; try { TransactionListenerRegistry tlr = TransactionListenerRegistryLocator.getTransactionListenerRegistry(); TxListener listener = new TxListener(tlr); try { prevTxn = tm.suspend(); } catch (SystemException e) { } catch (Error e) { System.out.printf("Error %s%n", e.getMessage()); } tm.begin(); tlr.addListener(tm.getTransaction(), listener, EnumSet.allOf(EventType.class)); tm.commit(); if (!listener.hasEvents()) throw new RuntimeException("listener did not get any events"); } catch (Throwable e) { throw new RuntimeException("TransactionListenerRegistry test failure: ", e); } finally { if (prevTxn != null) { try { tm.resume(prevTxn); } catch (InvalidTransactionException | SystemException e) { throw new RuntimeException("testListener resume failed: ", e); } } } } @Test(expected = RollbackException.class) public void testTimeout() throws Exception { final int timeout = 2; UserTransaction txn = getUserTransaction(); txn.setTransactionTimeout(timeout); txn.begin(); Thread.sleep(timeout * 1000 + 1000); txn.commit(); fail("committing a timed out transaction should have thrown a RollbackException"); } @Test public void testTransaction() throws Exception { UserTransaction txn = getUserTransaction(); txn.begin(); assertNotNull(txn); assertEquals(Status.STATUS_ACTIVE, txn.getStatus()); txn.commit(); // the transaction should have been disassociated assertEquals(Status.STATUS_NO_TRANSACTION, txn.getStatus()); txn.begin(); txn.commit(); assertEquals(Status.STATUS_NO_TRANSACTION, txn.getStatus()); } @Test public void testSynchronization() throws Exception { TestSynchronization synch = new TestSynchronization() ; UserTransaction txn = getUserTransaction(); TransactionManager transactionManager = getTransactionManager(); txn.begin(); transactionManager.getTransaction().registerSynchronization(synch); txn.commit(); assertTrue(synch.beforeCalled); assertTrue(synch.afterCalled); } class TestSynchronization implements Synchronization { boolean beforeCalled = false; boolean afterCalled = false; @Override public void beforeCompletion() { beforeCalled = true; } @Override public void afterCompletion(int i) { afterCalled = true; } } }