/*
* #%L
* Wisdom-Framework
* %%
* Copyright (C) 2013 - 2014 Wisdom Framework
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package org.wisdom.framework.transaction.impl;
import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.wisdom.framework.transaction.Propagation;
import javax.transaction.*;
import javax.transaction.xa.XAException;
import static org.assertj.core.api.Assertions.assertThat;
public class PropagationManagerTest {
TransactionManager manager;
PropagationManager propagation;
@Before
public void setUp() throws XAException {
manager = new TransactionManagerImpl(10);
propagation = new PropagationManager(manager);
}
@After
public void tearDown() throws SystemException {
if (manager.getTransaction() != null && manager.getStatus() != Status.STATUS_NO_TRANSACTION) {
manager.rollback();
}
}
@Test
public void testRequires() throws NotSupportedException, RollbackException, SystemException,
HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException {
assertThat(manager.getTransaction()).isNull();
propagation.onEntry(Propagation.REQUIRES, 0, "route");
assertThat(manager.getTransaction()).isNotNull();
Transaction transaction = manager.getTransaction();
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.REQUIRES, "route", callback);
assertThat(callback.transaction).isNotNull().isEqualTo(transaction);
assertThat(callback.committed).isTrue();
assertThat(callback.rolledBack).isFalse();
}
@Test
public void testRequiresWithRunningTransaction() throws NotSupportedException, RollbackException, SystemException,
HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException {
assertThat(manager.getTransaction()).isNull();
manager.begin();
Transaction transaction = manager.getTransaction();
assertThat(manager.getTransaction()).isNotNull();
propagation.onEntry(Propagation.REQUIRES, 0, "route");
assertThat(manager.getTransaction()).isNotNull();
assertThat(transaction).isEqualTo(manager.getTransaction());
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.REQUIRES, "route", callback);
assertThat(callback.transaction).isNull();
assertThat(callback.committed).isFalse();
assertThat(callback.rolledBack).isFalse();
transaction.rollback();
}
@Test
public void testRequiresWithRollback() throws NotSupportedException, RollbackException, SystemException,
HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException {
assertThat(manager.getTransaction()).isNull();
propagation.onEntry(Propagation.REQUIRES, 0, "route");
assertThat(manager.getTransaction()).isNotNull();
Transaction transaction = manager.getTransaction();
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
MyTransactionCallback callback = new MyTransactionCallback();
transaction.setRollbackOnly();
propagation.onExit(Propagation.REQUIRES, "route", callback);
assertThat(callback.transaction).isNotNull().isEqualTo(transaction);
assertThat(callback.committed).isFalse();
assertThat(callback.rolledBack).isTrue();
}
@Test(expected = IllegalStateException.class)
public void testMandatoryWithoutTransaction() throws NotSupportedException, RollbackException, SystemException,
HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException {
assertThat(manager.getTransaction()).isNull();
propagation.onEntry(Propagation.MANDATORY, 0, "route");
}
@Test
public void testMandatoryWithTransaction() throws NotSupportedException, RollbackException, SystemException,
HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException {
assertThat(manager.getTransaction()).isNull();
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onEntry(Propagation.MANDATORY, 0, "route");
assertThat(manager.getTransaction()).isEqualTo(transaction);
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.MANDATORY, "route", callback);
assertThat(callback.transaction).isNull();
assertThat(callback.committed).isFalse();
assertThat(callback.rolledBack).isFalse();
transaction.commit();
}
@Test(expected = IllegalStateException.class)
public void testNeverWithTransaction() throws NotSupportedException, RollbackException, SystemException,
HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException {
manager.begin();
propagation.onEntry(Propagation.NEVER, 0, "route");
}
@Test
public void testNeverWithoutTransaction() throws NotSupportedException, RollbackException, SystemException,
HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException {
propagation.onEntry(Propagation.NEVER, 0, "route");
propagation.onExit(Propagation.NEVER, "route", null);
}
@Test
public void testNotSupportedWithRunningTransaction() throws NotSupportedException, RollbackException,
SystemException, HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException {
assertThat(manager.getTransaction()).isNull();
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onEntry(Propagation.NOT_SUPPORTED, 0, "route");
// Transaction suspended.
assertThat(manager.getTransaction()).isNull();
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.NOT_SUPPORTED, "route", callback);
assertThat(callback.transaction).isNull();
assertThat(callback.committed).isFalse();
assertThat(callback.rolledBack).isFalse();
// Transaction resumed.
assertThat(transaction).isEqualTo(manager.getTransaction());
}
@Test(expected = IllegalStateException.class)
public void testNotSupportedWithRunningTransactionAndANewTransactionCreatedInBetween()
throws SystemException, NotSupportedException, RollbackException, HeuristicRollbackException,
HeuristicMixedException, InvalidTransactionException {
assertThat(manager.getTransaction()).isNull();
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onEntry(Propagation.NOT_SUPPORTED, 0, "route");
// Transaction suspended.
assertThat(manager.getTransaction()).isNull();
manager.begin();
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.NOT_SUPPORTED, "route", callback);
}
@Test
public void testNotSupportedWithRunningTransactionAndAnotherTransactionCreatedAndCommitted()
throws SystemException, NotSupportedException, RollbackException, HeuristicRollbackException,
HeuristicMixedException, InvalidTransactionException {
assertThat(manager.getTransaction()).isNull();
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onEntry(Propagation.NOT_SUPPORTED, 0, "route");
// Transaction suspended.
assertThat(manager.getTransaction()).isNull();
manager.begin();
manager.commit();
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.NOT_SUPPORTED, "route", callback);
assertThat(callback.transaction).isNull();
assertThat(callback.committed).isFalse();
assertThat(callback.rolledBack).isFalse();
// Transaction resumed.
assertThat(transaction).isEqualTo(manager.getTransaction());
}
@Test
public void testNotSupportedWithoutTransaction() throws NotSupportedException, RollbackException, SystemException,
HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException {
assertThat(manager.getTransaction()).isNull();
propagation.onEntry(Propagation.NOT_SUPPORTED, 0, "route");
assertThat(manager.getTransaction()).isNull();
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.NOT_SUPPORTED, "route", callback);
assertThat(callback.transaction).isNull();
assertThat(callback.committed).isFalse();
assertThat(callback.rolledBack).isFalse();
assertThat(manager.getTransaction()).isNull();
}
@Test
public void testSupportedWithoutTransaction() throws SystemException,
HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException, RollbackException, NotSupportedException {
assertThat(manager.getTransaction()).isNull();
propagation.onEntry(Propagation.SUPPORTED, 0, "route");
assertThat(manager.getTransaction()).isNull();
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.SUPPORTED, "route", callback);
assertThat(callback.transaction).isNull();
assertThat(callback.committed).isFalse();
assertThat(callback.rolledBack).isFalse();
assertThat(manager.getTransaction()).isNull();
}
@Test
public void testSupportedWithRunningTransaction() throws SystemException, NotSupportedException, RollbackException,
HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException {
assertThat(manager.getTransaction()).isNull();
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onEntry(Propagation.SUPPORTED, 0, "route");
assertThat(manager.getTransaction()).isEqualTo(transaction);
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.SUPPORTED, "route", callback);
assertThat(callback.transaction).isNull();
assertThat(callback.committed).isFalse();
assertThat(callback.rolledBack).isFalse();
assertThat(manager.getTransaction()).isEqualTo(transaction);
}
@Test
public void testRequireNewWithoutTransaction() throws HeuristicRollbackException, HeuristicMixedException,
InvalidTransactionException, SystemException, RollbackException, NotSupportedException {
assertThat(manager.getTransaction()).isNull();
propagation.onEntry(Propagation.REQUIRES_NEW, 0, "route");
assertThat(manager.getTransaction()).isNotNull();
Transaction transaction = manager.getTransaction();
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.REQUIRES_NEW, "route", callback);
assertThat(callback.transaction).isNotNull().isEqualTo(transaction);
assertThat(callback.committed).isTrue();
assertThat(callback.rolledBack).isFalse();
}
@Test
public void testRequireNewWithRunningTransaction() throws HeuristicRollbackException, HeuristicMixedException,
InvalidTransactionException, SystemException, RollbackException, NotSupportedException {
assertThat(manager.getTransaction()).isNull();
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onEntry(Propagation.REQUIRES_NEW, 0, "route");
// Check we have another transaction.
assertThat(manager.getTransaction()).isNotNull().isNotEqualTo(transaction);
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
Transaction inner = manager.getTransaction();
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.REQUIRES_NEW, "route", callback);
assertThat(callback.transaction).isNotNull().isEqualTo(inner);
assertThat(callback.committed).isTrue();
assertThat(callback.rolledBack).isFalse();
assertThat(transaction).isEqualTo(manager.getTransaction());
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
}
@Test
public void testRequireNewWithRunningTransactionAndRollback() throws HeuristicRollbackException,
HeuristicMixedException,
InvalidTransactionException, SystemException, RollbackException, NotSupportedException {
assertThat(manager.getTransaction()).isNull();
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onEntry(Propagation.REQUIRES_NEW, 0, "route");
// Check we have another transaction.
assertThat(manager.getTransaction()).isNotNull().isNotEqualTo(transaction);
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
Transaction inner = manager.getTransaction();
inner.setRollbackOnly();
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.REQUIRES_NEW, "route", callback);
assertThat(callback.transaction).isNotNull().isEqualTo(inner);
assertThat(callback.committed).isFalse();
assertThat(callback.rolledBack).isTrue();
assertThat(transaction).isEqualTo(manager.getTransaction());
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
}
@Test
public void testNestedRequiresNew() throws HeuristicRollbackException, HeuristicMixedException,
InvalidTransactionException, SystemException, RollbackException, NotSupportedException {
assertThat(manager.getTransaction()).isNull();
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onEntry(Propagation.REQUIRES_NEW, 0, "route");
// Check we have another transaction.
assertThat(manager.getTransaction()).isNotNull().isNotEqualTo(transaction);
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
Transaction inner = manager.getTransaction();
propagation.onEntry(Propagation.REQUIRES_NEW, 0, "route-nested");
assertThat(manager.getTransaction()).isNotNull().isNotEqualTo(transaction).isNotEqualTo(inner);
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
Transaction inner2 = manager.getTransaction();
MyTransactionCallback callback = new MyTransactionCallback();
propagation.onExit(Propagation.REQUIRES_NEW, "route-nested", callback);
assertThat(callback.transaction).isNotNull().isEqualTo(inner2);
assertThat(callback.committed).isTrue();
assertThat(callback.rolledBack).isFalse();
callback = new MyTransactionCallback();
propagation.onExit(Propagation.REQUIRES_NEW, "route", callback);
assertThat(callback.transaction).isNotNull().isEqualTo(inner);
assertThat(callback.committed).isTrue();
assertThat(callback.rolledBack).isFalse();
assertThat(transaction).isEqualTo(manager.getTransaction());
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
}
@Test
public void testOnErrorWithDefault() throws HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException, SystemException {
propagation.onError(new NullPointerException(),
Propagation.SUPPORTED,
new Class[] {},
new Class[] {}, "route", null);
}
@Test
public void testOnErrorWithDefaultAndTransaction() throws HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException, SystemException, NotSupportedException {
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onError(new NullPointerException(),
Propagation.MANDATORY,
new Class[] {},
new Class[] {}, "route", null);
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_MARKED_ROLLBACK);
}
@Test
public void testOnErrorWithNoRollbackAndTransaction() throws HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException, SystemException, NotSupportedException {
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onError(new NullPointerException(),
Propagation.MANDATORY,
new Class[] {NullPointerException.class},
new Class[] {}, "route", null);
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
}
@Test
public void testOnErrorWithRollbackOnlyAndTransaction() throws HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException, SystemException, NotSupportedException {
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onError(new NullPointerException(),
Propagation.MANDATORY,
new Class[] {IllegalStateException.class},
new Class[] {NullPointerException.class}, "route", null);
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_MARKED_ROLLBACK);
}
@Test
public void testOnErrorWithOtherRollbackOnlyAndTransaction() throws HeuristicRollbackException, HeuristicMixedException, InvalidTransactionException, SystemException, NotSupportedException {
manager.begin();
Transaction transaction = manager.getTransaction();
propagation.onError(new NullPointerException(),
Propagation.MANDATORY,
new Class[] {},
new Class[] {IllegalStateException.class}, "route", null);
assertThat(transaction.getStatus()).isEqualTo(Status.STATUS_ACTIVE);
}
private class MyTransactionCallback implements TransactionCallback {
public Transaction transaction;
public boolean committed;
public boolean rolledBack;
@Override
public void transactionCommitted(Transaction transaction) {
this.transaction = transaction;
committed = true;
}
@Override
public void transactionRolledBack(Transaction transaction) {
this.transaction = transaction;
rolledBack = true;
}
}
}