diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/AbstractTransactionNodeApi.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/AbstractTransactionNodeApi.java index 041a7a42de91d1bb58fa8cb70e941eeea4077767..0c9abf65c2540a697252c3e6adc1823adba7ec1a 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/AbstractTransactionNodeApi.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/AbstractTransactionNodeApi.java @@ -74,4 +74,9 @@ public abstract class AbstractTransactionNodeApi implements ApplicationListener< } } + public TransactionConfiguration getTransactionConfiguration() + { + return transactionConfiguration; + } + } diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/TransactionCoordinatorApi.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/TransactionCoordinatorApi.java index d17f3345f0a4cdd4ff3dae4be45d99026ff3d47c..cc43e04d29e3e3eeca2ff36fcb8ff215ab0c68a2 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/TransactionCoordinatorApi.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/TransactionCoordinatorApi.java @@ -6,8 +6,11 @@ import java.lang.reflect.Method; import java.net.URI; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.UUID; +import javax.annotation.PostConstruct; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -15,6 +18,8 @@ import ch.ethz.sis.afsapi.api.OperationsAPI; import ch.ethz.sis.afsclient.client.AfsClient; import ch.ethz.sis.openbis.generic.asapi.v3.ITransactionCoordinatorApi; import ch.ethz.sis.openbis.generic.asapi.v3.ITransactionParticipantApi; +import ch.ethz.sis.transaction.ISessionTokenProvider; +import ch.ethz.sis.transaction.ITransactionLog; import ch.ethz.sis.transaction.ITransactionParticipant; import ch.ethz.sis.transaction.TransactionCoordinator; import ch.ethz.sis.transaction.TransactionLog; @@ -27,14 +32,33 @@ public class TransactionCoordinatorApi extends AbstractTransactionNodeApi implem private static final String TRANSACTION_LOG_FOLDER_NAME = "coordinator"; - private final TransactionCoordinator transactionCoordinator; + private final IApplicationServerInternalApi applicationServerApi; + + private final IOpenBisSessionManager sessionManager; + + private final String logFolderName; + + private TransactionCoordinator transactionCoordinator; @Autowired public TransactionCoordinatorApi(final TransactionConfiguration transactionConfiguration, IApplicationServerInternalApi applicationServerApi, IOpenBisSessionManager sessionManager) + { + this(transactionConfiguration, applicationServerApi, sessionManager, TRANSACTION_LOG_FOLDER_NAME); + } + + public TransactionCoordinatorApi(final TransactionConfiguration transactionConfiguration, IApplicationServerInternalApi applicationServerApi, + IOpenBisSessionManager sessionManager, String logFolderName) { super(transactionConfiguration); + this.applicationServerApi = applicationServerApi; + this.sessionManager = sessionManager; + this.logFolderName = logFolderName; + } + @PostConstruct + public void init() + { if (transactionConfiguration.isEnabled()) { List<ITransactionParticipant> participants = Arrays.asList( @@ -43,27 +67,37 @@ public class TransactionCoordinatorApi extends AbstractTransactionNodeApi implem new AfsServerParticipant(applicationServerApi, transactionConfiguration.getAfsServerUrl(), transactionConfiguration.getAfsServerTimeoutInSeconds())); - this.transactionCoordinator = new TransactionCoordinator( - transactionConfiguration.getCoordinatorKey(), - transactionConfiguration.getInteractiveSessionKey(), - new ApplicationServerSessionTokenProvider(sessionManager), - participants, - new TransactionLog(new File(transactionConfiguration.getTransactionLogFolderPath()), TRANSACTION_LOG_FOLDER_NAME), - transactionConfiguration.getTransactionTimeoutInSeconds(), - transactionConfiguration.getTransactionCountLimit()); + this.transactionCoordinator = + createCoordinator(transactionConfiguration.getCoordinatorKey(), transactionConfiguration.getInteractiveSessionKey(), + new ApplicationServerSessionTokenProvider(sessionManager), participants, + new TransactionLog(new File(transactionConfiguration.getTransactionLogFolderPath()), logFolderName), + transactionConfiguration.getTransactionTimeoutInSeconds(), + transactionConfiguration.getTransactionCountLimit()); } else { this.transactionCoordinator = null; } } - @Override protected void recoverTransactionsFromTransactionLog() + protected TransactionCoordinator createCoordinator(final String transactionCoordinatorKey, final String interactiveSessionKey, + final ISessionTokenProvider sessionTokenProvider, final List<ITransactionParticipant> participants, final ITransactionLog transactionLog, + int transactionTimeoutInSeconds, int transactionCountLimit) + { + return new TransactionCoordinator( + transactionCoordinatorKey, + interactiveSessionKey, + sessionTokenProvider, + participants, + transactionLog, transactionTimeoutInSeconds, transactionCountLimit); + } + + @Override public void recoverTransactionsFromTransactionLog() { checkTransactionsEnabled(); transactionCoordinator.recoverTransactionsFromTransactionLog(); } - @Override protected void finishFailedOrAbandonedTransactions() + @Override public void finishFailedOrAbandonedTransactions() { checkTransactionsEnabled(); transactionCoordinator.finishFailedOrAbandonedTransactions(); @@ -95,6 +129,12 @@ public class TransactionCoordinatorApi extends AbstractTransactionNodeApi implem transactionCoordinator.rollbackTransaction(transactionId, sessionToken, interactiveSessionKey); } + public Map<UUID, TransactionCoordinator.Transaction> getTransactionMap() + { + checkTransactionsEnabled(); + return transactionCoordinator.getTransactionMap(); + } + @Override public int getMajorVersion() { return 1; diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/TransactionParticipantApi.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/TransactionParticipantApi.java index 0528738048c746aef752262dacf4be017f94cbbd..290709fa5406aa6b98f04e1cc20119c14f8a655f 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/TransactionParticipantApi.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/TransactionParticipantApi.java @@ -7,8 +7,11 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.List; +import java.util.Map; import java.util.UUID; +import javax.annotation.PostConstruct; + import org.apache.log4j.Logger; import org.hibernate.Session; import org.springframework.beans.factory.annotation.Autowired; @@ -20,7 +23,10 @@ import org.springframework.transaction.support.DefaultTransactionDefinition; import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; import ch.ethz.sis.openbis.generic.asapi.v3.ITransactionCoordinatorApi; import ch.ethz.sis.openbis.generic.asapi.v3.ITransactionParticipantApi; +import ch.ethz.sis.transaction.AbstractTransaction; import ch.ethz.sis.transaction.IDatabaseTransactionProvider; +import ch.ethz.sis.transaction.ISessionTokenProvider; +import ch.ethz.sis.transaction.ITransactionLog; import ch.ethz.sis.transaction.ITransactionOperationExecutor; import ch.ethz.sis.transaction.TransactionLog; import ch.ethz.sis.transaction.TransactionParticipant; @@ -38,7 +44,21 @@ public class TransactionParticipantApi extends AbstractTransactionNodeApi implem private static final String TRANSACTION_LOG_FOLDER_NAME = "participant-application-server"; - private final TransactionParticipant transactionParticipant; + private final PlatformTransactionManager transactionManager; + + private final IDAOFactory daoFactory; + + private final DatabaseConfigurationContext databaseContext; + + private final IApplicationServerApi applicationServerApi; + + private final IOpenBisSessionManager sessionManager; + + private final String participantId; + + private final String logFolderName; + + private TransactionParticipant transactionParticipant; @Autowired public TransactionParticipantApi(final TransactionConfiguration transactionConfiguration, final PlatformTransactionManager transactionManager, @@ -50,15 +70,25 @@ public class TransactionParticipantApi extends AbstractTransactionNodeApi implem } public TransactionParticipantApi(final TransactionConfiguration transactionConfiguration, final PlatformTransactionManager transactionManager, - final IDAOFactory daoFactory, final DatabaseConfigurationContext databaseContext, final IApplicationServerApi applicationServerApi, - final IOpenBisSessionManager sessionManager, - final String participantId, final String logFolderName) + final IDAOFactory daoFactory, final DatabaseConfigurationContext databaseContext, final IApplicationServerApi applicationServerApi, final + IOpenBisSessionManager sessionManager, final String participantId, final String logFolderName) { super(transactionConfiguration); + this.transactionManager = transactionManager; + this.daoFactory = daoFactory; + this.databaseContext = databaseContext; + this.applicationServerApi = applicationServerApi; + this.sessionManager = sessionManager; + this.participantId = participantId; + this.logFolderName = logFolderName; + } + @PostConstruct + public void init() + { if (transactionConfiguration.isEnabled()) { - this.transactionParticipant = new TransactionParticipant( + this.transactionParticipant = createParticipant( participantId, transactionConfiguration.getCoordinatorKey(), transactionConfiguration.getInteractiveSessionKey(), @@ -75,6 +105,25 @@ public class TransactionParticipantApi extends AbstractTransactionNodeApi implem } } + protected TransactionParticipant createParticipant(final String participantId, final String transactionCoordinatorKey, + final String interactiveSessionKey, final ISessionTokenProvider sessionTokenProvider, + final IDatabaseTransactionProvider databaseTransactionProvider, + final ITransactionOperationExecutor operationExecutor, final ITransactionLog transactionLog, final int transactionTimeoutInSeconds, + final int transactionCountLimit) + { + return new TransactionParticipant( + participantId, + transactionCoordinatorKey, + interactiveSessionKey, + sessionTokenProvider, + databaseTransactionProvider, + operationExecutor, + transactionLog, + transactionTimeoutInSeconds, + transactionCountLimit + ); + } + @Override protected void recoverTransactionsFromTransactionLog() { checkTransactionsEnabled(); @@ -146,6 +195,12 @@ public class TransactionParticipantApi extends AbstractTransactionNodeApi implem return transactionParticipant.recoverTransactions(interactiveSessionKey, transactionCoordinatorKey); } + public Map<UUID, TransactionParticipant.Transaction> getTransactionMap() + { + checkTransactionsEnabled(); + return transactionParticipant.getTransactionMap(); + } + @Override public int getMajorVersion() { return 1; @@ -340,9 +395,4 @@ public class TransactionParticipantApi extends AbstractTransactionNodeApi implem } } - public TransactionParticipant getTransactionParticipant() - { - return transactionParticipant; - } - } diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTransactionTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTransactionTest.java index 224a4ddea84bfe7db4386eb5f26eb4c75e961a65..ba3b3eae29304e9f37cb7977814cfefcbdff96af 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTransactionTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTransactionTest.java @@ -1,8 +1,8 @@ package ch.ethz.sis.openbis.systemtest.asapi.v3; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; -import java.io.File; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; @@ -23,14 +23,16 @@ import org.springframework.transaction.PlatformTransactionManager; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ICodeHolder; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IIdentifierHolder; -import ch.ethz.sis.openbis.generic.server.asapi.v3.ApplicationServerSessionTokenProvider; import ch.ethz.sis.openbis.generic.server.asapi.v3.TransactionConfiguration; +import ch.ethz.sis.openbis.generic.server.asapi.v3.TransactionCoordinatorApi; import ch.ethz.sis.openbis.generic.server.asapi.v3.TransactionParticipantApi; import ch.ethz.sis.transaction.AbstractTransaction; import ch.ethz.sis.transaction.IDatabaseTransactionProvider; +import ch.ethz.sis.transaction.ISessionTokenProvider; +import ch.ethz.sis.transaction.ITransactionLog; +import ch.ethz.sis.transaction.ITransactionOperationExecutor; import ch.ethz.sis.transaction.ITransactionParticipant; import ch.ethz.sis.transaction.TransactionCoordinator; -import ch.ethz.sis.transaction.TransactionLog; import ch.ethz.sis.transaction.TransactionParticipant; import ch.ethz.sis.transaction.TransactionStatus; import ch.systemsx.cisd.common.logging.LogCategory; @@ -44,21 +46,21 @@ public class AbstractTransactionTest extends AbstractTest private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, AbstractTransactionTest.class); - public static final String TEST_COORDINATOR_KEY = "test-transaction-coordinator-key"; + public static final String TEST_COORDINATOR_KEY = "system-test-transaction-coordinator-key"; - public static final String TEST_INTERACTIVE_SESSION_KEY = "test-interactive-session-key"; + public static final String TEST_INTERACTIVE_SESSION_KEY = "system-test-interactive-session-key"; - public static final String TEST_PARTICIPANT_1_ID = "test-participant-1"; + public static final String TEST_PARTICIPANT_1_ID = "system-test-participant-1"; - public static final String TEST_PARTICIPANT_2_ID = "test-participant-2"; + public static final String TEST_PARTICIPANT_2_ID = "system-test-participant-2"; - public static final String TRANSACTION_LOG_ROOT_FOLDER = "targets/transaction-logs"; + public static final String TRANSACTION_LOG_ROOT_FOLDER = "targets/system-test-transaction-logs"; - public static final String TRANSACTION_LOG_COORDINATOR_FOLDER = "test-coordinator"; + public static final String TRANSACTION_LOG_COORDINATOR_FOLDER = "system-test-coordinator"; - public static final String TRANSACTION_LOG_PARTICIPANT_1_FOLDER = "test-participant-1"; + public static final String TRANSACTION_LOG_PARTICIPANT_1_FOLDER = "system-test-participant-1"; - public static final String TRANSACTION_LOG_PARTICIPANT_2_FOLDER = "test-participant-2"; + public static final String TRANSACTION_LOG_PARTICIPANT_2_FOLDER = "system-test-participant-2"; public static final String OPERATION_CREATE_SPACES = "createSpaces"; @@ -70,9 +72,6 @@ public class AbstractTransactionTest extends AbstractTest public static final String CODE_PREFIX = "TRANSACTION_TEST_"; - @Autowired - public TransactionConfiguration transactionConfiguration; - @Autowired public PlatformTransactionManager transactionManager; @@ -85,29 +84,28 @@ public class AbstractTransactionTest extends AbstractTest @Autowired public IOpenBisSessionManager sessionManager; - public TransactionCoordinator createCoordinator(List<ITransactionParticipant> participants, int transactionTimeoutInSeconds, - int transactionCountLimit) + public TestTransactionCoordinatorApi createCoordinator(TransactionConfiguration configuration, List<ITransactionParticipant> participants, + String logFolderName) { - return new TransactionCoordinator(TEST_COORDINATOR_KEY, TEST_INTERACTIVE_SESSION_KEY, - new ApplicationServerSessionTokenProvider(sessionManager), - participants, new TransactionLog(new File(TRANSACTION_LOG_ROOT_FOLDER), TRANSACTION_LOG_COORDINATOR_FOLDER), - transactionTimeoutInSeconds, transactionCountLimit); + TestTransactionCoordinatorApi coordinatorApi = new TestTransactionCoordinatorApi(configuration, participants, logFolderName); + coordinatorApi.init(); + return coordinatorApi; } - public TestTransactionParticipant createParticipant(TransactionConfiguration configuration, String participantId, String logFolderName) + public TestTransactionParticipantApi createParticipant(TransactionConfiguration configuration, String participantId, String logFolderName) { - return new TestTransactionParticipant( - new TransactionParticipantApi(configuration, transactionManager, daoFactory, databaseContext, v3api, sessionManager, participantId, - logFolderName)); + TestTransactionParticipantApi participantApi = new TestTransactionParticipantApi(configuration, participantId, logFolderName); + participantApi.init(); + return participantApi; } - public TransactionConfiguration createConfiguration(final int transactionTimeoutInSeconds, final int transactionCountLimit) + public TransactionConfiguration createConfiguration(final boolean enabled, final int transactionTimeoutInSeconds, final int transactionCountLimit) { return new TransactionConfiguration() { @Override public boolean isEnabled() { - return true; + return enabled; } public int getTransactionTimeoutInSeconds() @@ -117,22 +115,22 @@ public class AbstractTransactionTest extends AbstractTest public int getFinishTransactionsIntervalInSeconds() { - return transactionConfiguration.getFinishTransactionsIntervalInSeconds(); + return 3600; } public String getInteractiveSessionKey() { - return transactionConfiguration.getInteractiveSessionKey(); + return TEST_INTERACTIVE_SESSION_KEY; } public String getCoordinatorKey() { - return transactionConfiguration.getCoordinatorKey(); + return TEST_COORDINATOR_KEY; } public String getTransactionLogFolderPath() { - return transactionConfiguration.getTransactionLogFolderPath(); + return TRANSACTION_LOG_ROOT_FOLDER; } public int getTransactionCountLimit() @@ -142,22 +140,22 @@ public class AbstractTransactionTest extends AbstractTest public String getApplicationServerUrl() { - return transactionConfiguration.getApplicationServerUrl(); + return null; } public int getApplicationServerTimeoutInSeconds() { - return transactionConfiguration.getApplicationServerTimeoutInSeconds(); + return -1; } public String getAfsServerUrl() { - return transactionConfiguration.getAfsServerUrl(); + return null; } public int getAfsServerTimeoutInSeconds() { - return transactionConfiguration.getAfsServerTimeoutInSeconds(); + return -1; } }; } @@ -190,7 +188,32 @@ public class AbstractTransactionTest extends AbstractTest } } - public static class TestTransactionParticipant implements ITransactionParticipant + public class TestTransactionCoordinatorApi extends TransactionCoordinatorApi + { + + private final List<ITransactionParticipant> testParticipants; + + public TestTransactionCoordinatorApi(final TransactionConfiguration transactionConfiguration, + final List<ITransactionParticipant> participants, final String logFolderName) + { + super(transactionConfiguration, v3api, sessionManager, logFolderName); + this.testParticipants = participants; + } + + @Override protected TransactionCoordinator createCoordinator(final String transactionCoordinatorKey, + final String interactiveSessionKey, final ISessionTokenProvider sessionTokenProvider, + final List<ITransactionParticipant> participants, final ITransactionLog transactionLog, final int transactionTimeoutInSeconds, + final int transactionCountLimit) + { + return new TransactionCoordinator(transactionCoordinatorKey, + interactiveSessionKey, sessionTokenProvider, this.testParticipants, + transactionLog, transactionTimeoutInSeconds, + transactionCountLimit); + } + + } + + public class TestTransactionParticipantApi extends TransactionParticipantApi { // Map the original transaction id coming from the coordinator to a unique transaction id for each participant, @@ -202,76 +225,85 @@ public class AbstractTransactionTest extends AbstractTest private boolean mapTransactions = false; - private final TransactionParticipant participant; - - private final TestDatabaseTransactionProvider databaseTransactionProvider; + private TestDatabaseTransactionProvider testDatabaseTransactionProvider; - public TestTransactionParticipant(TransactionParticipantApi participantApi) + public TestTransactionParticipantApi(final TransactionConfiguration transactionConfiguration, final String participantId, + final String logFolderName) { - // replace the original database transaction provider with a test counterpart that allows to throw test exceptions - this.participant = participantApi.getTransactionParticipant(); - this.databaseTransactionProvider = - new TestDatabaseTransactionProvider(participantApi.getTransactionParticipant().getDatabaseTransactionProvider()); - this.participant.setDatabaseTransactionProvider(databaseTransactionProvider); + super(transactionConfiguration, transactionManager, daoFactory, databaseContext, v3api, sessionManager, participantId, logFolderName); } - public TestDatabaseTransactionProvider getDatabaseTransactionProvider() + @Override protected TransactionParticipant createParticipant(final String participantId, final String transactionCoordinatorKey, + final String interactiveSessionKey, final ISessionTokenProvider sessionTokenProvider, + final IDatabaseTransactionProvider databaseTransactionProvider, final ITransactionOperationExecutor operationExecutor, + final ITransactionLog transactionLog, final int transactionTimeoutInSeconds, final int transactionCountLimit) { - return this.databaseTransactionProvider; + this.testDatabaseTransactionProvider = new TestDatabaseTransactionProvider(databaseTransactionProvider); + return new TransactionParticipant( + participantId, + transactionCoordinatorKey, + interactiveSessionKey, + sessionTokenProvider, + this.testDatabaseTransactionProvider, + operationExecutor, + transactionLog, + transactionTimeoutInSeconds, + transactionCountLimit + ); } - @Override public String getParticipantId() + public TestDatabaseTransactionProvider getDatabaseTransactionProvider() { - return participant.getParticipantId(); + return this.testDatabaseTransactionProvider; } @Override public void beginTransaction(final UUID transactionId, final String sessionToken, final String interactiveSessionKey, final String transactionCoordinatorKey) { - this.participant.beginTransaction(mapOriginalToInternalId(transactionId), sessionToken, interactiveSessionKey, + super.beginTransaction(mapOriginalToInternalId(transactionId), sessionToken, interactiveSessionKey, transactionCoordinatorKey); } @Override public <T> T executeOperation(final UUID transactionId, final String sessionToken, final String interactiveSessionKey, final String operationName, final Object[] operationArguments) { - return participant.executeOperation(mapOriginalToInternalId(transactionId), sessionToken, interactiveSessionKey, operationName, + return super.executeOperation(mapOriginalToInternalId(transactionId), sessionToken, interactiveSessionKey, operationName, operationArguments); } @Override public void prepareTransaction(final UUID transactionId, final String sessionToken, final String interactiveSessionKey, final String transactionCoordinatorKey) { - participant.prepareTransaction(mapOriginalToInternalId(transactionId), sessionToken, interactiveSessionKey, transactionCoordinatorKey); + super.prepareTransaction(mapOriginalToInternalId(transactionId), sessionToken, interactiveSessionKey, transactionCoordinatorKey); } @Override public void commitTransaction(final UUID transactionId, final String sessionToken, final String interactiveSessionKey) { - participant.commitTransaction(mapOriginalToInternalId(transactionId), sessionToken, interactiveSessionKey); + super.commitTransaction(mapOriginalToInternalId(transactionId), sessionToken, interactiveSessionKey); } @Override public void commitRecoveredTransaction(final UUID transactionId, final String interactiveSessionKey, final String transactionCoordinatorKey) { - participant.commitRecoveredTransaction(mapOriginalToInternalId(transactionId), interactiveSessionKey, transactionCoordinatorKey); + super.commitRecoveredTransaction(mapOriginalToInternalId(transactionId), interactiveSessionKey, transactionCoordinatorKey); } @Override public void rollbackTransaction(final UUID transactionId, final String sessionToken, final String interactiveSessionKey) { - participant.rollbackTransaction(mapOriginalToInternalId(transactionId), sessionToken, interactiveSessionKey); + super.rollbackTransaction(mapOriginalToInternalId(transactionId), sessionToken, interactiveSessionKey); } @Override public void rollbackRecoveredTransaction(final UUID transactionId, final String interactiveSessionKey, final String transactionCoordinatorKey) { - participant.rollbackRecoveredTransaction(mapOriginalToInternalId(transactionId), interactiveSessionKey, transactionCoordinatorKey); + super.rollbackRecoveredTransaction(mapOriginalToInternalId(transactionId), interactiveSessionKey, transactionCoordinatorKey); } @Override public List<UUID> recoverTransactions(final String interactiveSessionKey, final String transactionCoordinatorKey) { List<UUID> transactionIds = new ArrayList<>(); - for (UUID internalTransactionId : participant.recoverTransactions(interactiveSessionKey, transactionCoordinatorKey)) + for (UUID internalTransactionId : super.recoverTransactions(interactiveSessionKey, transactionCoordinatorKey)) { transactionIds.add(mapInternalToOriginalId(internalTransactionId)); } @@ -281,22 +313,22 @@ public class AbstractTransactionTest extends AbstractTest public void recoverTransactionsFromTransactionLog() { - participant.recoverTransactionsFromTransactionLog(); + super.recoverTransactionsFromTransactionLog(); } public void finishFailedOrAbandonedTransactions() { - participant.finishFailedOrAbandonedTransactions(); + super.finishFailedOrAbandonedTransactions(); } - public Map<UUID, ? extends AbstractTransaction> getTransactionMap() + public Map<UUID, TransactionParticipant.Transaction> getTransactionMap() { - Map<UUID, AbstractTransaction> transactionMap = new HashMap<>(); + Map<UUID, TransactionParticipant.Transaction> transactionMap = new HashMap<>(); - for (Map.Entry<UUID, ? extends AbstractTransaction> entry : this.participant.getTransactionMap().entrySet()) + for (Map.Entry<UUID, ? extends AbstractTransaction> entry : super.getTransactionMap().entrySet()) { TransactionParticipant.Transaction internalTransaction = (TransactionParticipant.Transaction) entry.getValue(); - AbstractTransaction originalTransaction = + TransactionParticipant.Transaction originalTransaction = new TransactionParticipant.Transaction(mapInternalToOriginalId(internalTransaction.getTransactionId()), internalTransaction.getSessionToken()); originalTransaction.setTransactionStatus(internalTransaction.getTransactionStatus()); @@ -347,7 +379,7 @@ public class AbstractTransactionTest extends AbstractTest public void close() { - for (TransactionParticipant.Transaction transaction : participant.getTransactionMap().values()) + for (TransactionParticipant.Transaction transaction : super.getTransactionMap().values()) { try { @@ -442,6 +474,18 @@ public class AbstractTransactionTest extends AbstractTest } + public static void assertTransactionsDisabled(Runnable action) + { + try + { + action.run(); + fail(); + } catch (Exception e) + { + assertEquals(e.getMessage(), "Transactions are disabled in service.properties file."); + } + } + public static void assertTransactions(Map<UUID, ? extends AbstractTransaction> actualTransactions, TestTransaction... expectedTransactions) { Map<String, String> actualTransactionsMap = new TreeMap<>(); diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Transaction1PCTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Transaction1PCTest.java index 3144b589b46f62f53d69c8ab9d8f180534553087..39d5f632538697f072d5a0770c9b187cad9f02e8 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Transaction1PCTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Transaction1PCTest.java @@ -33,22 +33,42 @@ import ch.systemsx.cisd.common.test.AssertionUtil; public class Transaction1PCTest extends AbstractTransactionTest { - private TestTransactionParticipant participant; + private TestTransactionParticipantApi participant; @BeforeMethod private void beforeMethod() { FileUtilities.deleteRecursively(new File(TRANSACTION_LOG_ROOT_FOLDER, TRANSACTION_LOG_PARTICIPANT_1_FOLDER)); - participant = createParticipant(transactionConfiguration, TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); + participant = createParticipant(createConfiguration(true, 60, 10), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); } @AfterMethod private void afterMethod() throws Exception { - rollbackPreparedDatabaseTransactions(); - deleteCreatedSpacesAndProjects(); + if (participant.getTransactionConfiguration().isEnabled()) + { + rollbackPreparedDatabaseTransactions(); + deleteCreatedSpacesAndProjects(); + + participant.close(); + } + } - participant.close(); + @Test + public void testTransactionsDisabled() + { + participant = createParticipant(createConfiguration(false, 60, 10), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); + + assertTransactionsDisabled(() -> participant.recoverTransactionsFromTransactionLog()); + assertTransactionsDisabled(() -> participant.finishFailedOrAbandonedTransactions()); + assertTransactionsDisabled(() -> participant.getTransactionMap()); + assertTransactionsDisabled(() -> participant.beginTransaction(null, null, null, null)); + assertTransactionsDisabled(() -> participant.executeOperation(null, null, null, null, null)); + assertTransactionsDisabled(() -> participant.prepareTransaction(null, null, null, null)); + assertTransactionsDisabled(() -> participant.commitTransaction(null, null, null)); + assertTransactionsDisabled(() -> participant.commitRecoveredTransaction(null, null, null)); + assertTransactionsDisabled(() -> participant.rollbackTransaction(null, null, null)); + assertTransactionsDisabled(() -> participant.rollbackRecoveredTransaction(null, null, null)); } @Test @@ -103,7 +123,7 @@ public class Transaction1PCTest extends AbstractTransactionTest @Test public void testExecuteOperationTimesOut() throws Exception { - participant = createParticipant(createConfiguration(1, 10), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); + participant = createParticipant(createConfiguration(true, 1, 10), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); assertTransactions(participant.getTransactionMap()); @@ -531,7 +551,7 @@ public class Transaction1PCTest extends AbstractTransactionTest @Test public void testTooManyTransactions() { - participant = createParticipant(createConfiguration(60, 2), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); + participant = createParticipant(createConfiguration(true, 60, 2), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); assertTransactions(participant.getTransactionMap()); @@ -625,8 +645,8 @@ public class Transaction1PCTest extends AbstractTransactionTest @Test public void testRecovery() { - TestTransactionParticipant participantBeforeCrash = - createParticipant(transactionConfiguration, TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); + TestTransactionParticipantApi participantBeforeCrash = + createParticipant(createConfiguration(true, 60, 10), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); // "commit" and "rollback" should fail RuntimeException commitException = new RuntimeException("Test commit exception"); @@ -682,8 +702,8 @@ public class Transaction1PCTest extends AbstractTransactionTest new TestTransaction(transactionId2, TransactionStatus.BEGIN_FINISHED)); // new participant - TestTransactionParticipant participantAfterCrash = - createParticipant(transactionConfiguration, TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); + TestTransactionParticipantApi participantAfterCrash = + createParticipant(createConfiguration(true, 60, 10), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); assertTransactions(participantAfterCrash.getTransactionMap()); diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Transaction2PCTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Transaction2PCTest.java index 10e2fb7b8f0a1e84848ee8aca3b4d3c4c825a14b..07c3329c77092983277795ccfba28f136c7ae871 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Transaction2PCTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Transaction2PCTest.java @@ -27,9 +27,8 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.fetchoptions.SpaceFetchOpt import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.ISpaceId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.SpaceSearchCriteria; -import ch.ethz.sis.transaction.ITransactionParticipant; import ch.ethz.sis.transaction.AbstractTransaction; -import ch.ethz.sis.transaction.TransactionCoordinator; +import ch.ethz.sis.transaction.ITransactionParticipant; import ch.ethz.sis.transaction.TransactionOperationException; import ch.ethz.sis.transaction.TransactionStatus; import ch.systemsx.cisd.common.concurrent.MessageChannel; @@ -39,11 +38,11 @@ import ch.systemsx.cisd.common.test.AssertionUtil; public class Transaction2PCTest extends AbstractTransactionTest { - private TransactionCoordinator coordinator; + private TestTransactionCoordinatorApi coordinator; - private TestTransactionParticipant participant1; + private TestTransactionParticipantApi participant1; - private TestTransactionParticipant participant2; + private TestTransactionParticipantApi participant2; private UUID coordinatorTrId; @@ -72,38 +71,57 @@ public class Transaction2PCTest extends AbstractTransactionTest final UUID participant2Tr2Id = UUID.randomUUID(); final UUID participant2Tr3Id = UUID.randomUUID(); - participant1 = createParticipant(transactionConfiguration, TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); + participant1 = createParticipant(createConfiguration(true, 60, 10), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); participant1.setTestTransactionMapping( Map.of(coordinatorTrId, participant1TrId, coordinatorTr2Id, participant1Tr2Id, coordinatorTr3Id, participant1Tr3Id)); - participant2 = createParticipant(transactionConfiguration, TEST_PARTICIPANT_2_ID, TRANSACTION_LOG_PARTICIPANT_2_FOLDER); + participant2 = createParticipant(createConfiguration(true, 60, 10), TEST_PARTICIPANT_2_ID, TRANSACTION_LOG_PARTICIPANT_2_FOLDER); participant2.setTestTransactionMapping( Map.of(coordinatorTrId, participant2TrId, coordinatorTr2Id, participant2Tr2Id, coordinatorTr3Id, participant2Tr3Id)); - coordinator = createCoordinator(Arrays.asList(participant1, participant2), 60, 10); + coordinator = + createCoordinator(createConfiguration(true, 60, 10), Arrays.asList(participant1, participant2), TRANSACTION_LOG_COORDINATOR_FOLDER); } @AfterMethod private void afterMethod() throws Exception { - rollbackPreparedDatabaseTransactions(); + if (coordinator.getTransactionConfiguration().isEnabled()) + { + rollbackPreparedDatabaseTransactions(); - String sessionToken = v3api.loginAsSystem(); + String sessionToken = v3api.loginAsSystem(); - for (AbstractTransaction transaction : coordinator.getTransactionMap().values()) - { - try - { - coordinator.rollbackTransaction(transaction.getTransactionId(), sessionToken, TEST_INTERACTIVE_SESSION_KEY); - } catch (Exception ignored) + for (AbstractTransaction transaction : coordinator.getTransactionMap().values()) { + try + { + coordinator.rollbackTransaction(transaction.getTransactionId(), sessionToken, TEST_INTERACTIVE_SESSION_KEY); + } catch (Exception ignored) + { + } } - } - deleteCreatedSpacesAndProjects(); + deleteCreatedSpacesAndProjects(); - participant1.close(); - participant2.close(); + participant1.close(); + participant2.close(); + } + } + + @Test + public void testTransactionsDisabled() + { + coordinator = + createCoordinator(createConfiguration(false, 60, 10), Arrays.asList(participant1, participant2), TRANSACTION_LOG_COORDINATOR_FOLDER); + + assertTransactionsDisabled(() -> coordinator.recoverTransactionsFromTransactionLog()); + assertTransactionsDisabled(() -> coordinator.finishFailedOrAbandonedTransactions()); + assertTransactionsDisabled(() -> coordinator.getTransactionMap()); + assertTransactionsDisabled(() -> coordinator.beginTransaction(null, null, null)); + assertTransactionsDisabled(() -> coordinator.executeOperation(null, null, null, null, null, null)); + assertTransactionsDisabled(() -> coordinator.commitTransaction(null, null, null)); + assertTransactionsDisabled(() -> coordinator.rollbackTransaction(null, null, null)); } @Test @@ -199,7 +217,8 @@ public class Transaction2PCTest extends AbstractTransactionTest @Test public void testExecuteOperationTimesOut() throws Exception { - coordinator = createCoordinator(Arrays.asList(participant1, participant2), 1, 10); + coordinator = + createCoordinator(createConfiguration(true, 1, 10), Arrays.asList(participant1, participant2), TRANSACTION_LOG_COORDINATOR_FOLDER); assertTransactions(coordinator.getTransactionMap()); assertTransactions(participant1.getTransactionMap()); @@ -736,7 +755,8 @@ public class Transaction2PCTest extends AbstractTransactionTest @Test public void testTooManyTransactions() { - coordinator = createCoordinator(Arrays.asList(participant1, participant2), 60, 2); + coordinator = + createCoordinator(createConfiguration(true, 60, 2), Arrays.asList(participant1, participant2), TRANSACTION_LOG_COORDINATOR_FOLDER); assertTransactions(coordinator.getTransactionMap()); assertTransactions(participant1.getTransactionMap()); @@ -822,7 +842,8 @@ public class Transaction2PCTest extends AbstractTransactionTest @Test public void testRecoveryOfCoordinatorWithTransactionToRollback() { - TransactionCoordinator coordinatorBeforeCrash = createCoordinator(Arrays.asList(participant1, participant2), 60, 10); + TestTransactionCoordinatorApi coordinatorBeforeCrash = + createCoordinator(createConfiguration(true, 60, 10), Arrays.asList(participant1, participant2), TRANSACTION_LOG_COORDINATOR_FOLDER); assertTransactions(coordinatorBeforeCrash.getTransactionMap()); assertTransactions(participant1.getTransactionMap()); @@ -839,7 +860,8 @@ public class Transaction2PCTest extends AbstractTransactionTest OPERATION_CREATE_SPACES, new Object[] { sessionToken, Collections.singletonList(spaceCreation) }); // new coordinator - TransactionCoordinator coordinatorAfterCrash = createCoordinator(Arrays.asList(participant1, participant2), 60, 10); + TestTransactionCoordinatorApi coordinatorAfterCrash = + createCoordinator(createConfiguration(true, 60, 10), Arrays.asList(participant1, participant2), TRANSACTION_LOG_COORDINATOR_FOLDER); assertTransactions(coordinatorAfterCrash.getTransactionMap()); assertTransactions(participant1.getTransactionMap(), new TestTransaction(coordinatorTrId, TransactionStatus.BEGIN_FINISHED)); @@ -877,7 +899,8 @@ public class Transaction2PCTest extends AbstractTransactionTest throw exception; }); - TransactionCoordinator coordinatorBeforeCrash = createCoordinator(Arrays.asList(participant1, participant2), 60, 10); + TestTransactionCoordinatorApi coordinatorBeforeCrash = + createCoordinator(createConfiguration(true, 60, 10), Arrays.asList(participant1, participant2), TRANSACTION_LOG_COORDINATOR_FOLDER); assertTransactions(coordinatorBeforeCrash.getTransactionMap()); assertTransactions(participant1.getTransactionMap()); @@ -900,7 +923,8 @@ public class Transaction2PCTest extends AbstractTransactionTest assertTransactions(participant2.getTransactionMap()); // new coordinator - TransactionCoordinator coordinatorAfterCrash = createCoordinator(Arrays.asList(participant1, participant2), 60, 10); + TestTransactionCoordinatorApi coordinatorAfterCrash = + createCoordinator(createConfiguration(true, 60, 10), Arrays.asList(participant1, participant2), TRANSACTION_LOG_COORDINATOR_FOLDER); // "commit" for both participants should succeed participant1.getDatabaseTransactionProvider().setCommitAction(null); @@ -938,7 +962,8 @@ public class Transaction2PCTest extends AbstractTransactionTest participants.add(participant1); participants.add(participant2); - TransactionCoordinator coordinator = createCoordinator(participants, 60, 10); + TestTransactionCoordinatorApi coordinator = + createCoordinator(createConfiguration(true, 60, 10), participants, TRANSACTION_LOG_COORDINATOR_FOLDER); assertTransactions(coordinator.getTransactionMap()); assertTransactions(participant1.getTransactionMap()); @@ -959,8 +984,8 @@ public class Transaction2PCTest extends AbstractTransactionTest assertTransactions(participant2.getTransactionMap()); // replace original participant with a new instance - TestTransactionParticipant participant1AfterCrash = - createParticipant(transactionConfiguration, TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); + TestTransactionParticipantApi participant1AfterCrash = + createParticipant(createConfiguration(true, 60, 10), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); participant1AfterCrash.setTestTransactionMapping(participant1.getTestTransactionMapping()); participants.set(0, participant1AfterCrash); @@ -1020,7 +1045,8 @@ public class Transaction2PCTest extends AbstractTransactionTest participants.add(participant1); participants.add(participant2); - TransactionCoordinator coordinator = createCoordinator(participants, 60, 10); + TestTransactionCoordinatorApi coordinator = + createCoordinator(createConfiguration(true, 60, 10), participants, TRANSACTION_LOG_COORDINATOR_FOLDER); assertTransactions(coordinator.getTransactionMap()); assertTransactions(participant1.getTransactionMap()); @@ -1049,8 +1075,8 @@ public class Transaction2PCTest extends AbstractTransactionTest assertTransactions(participant1.getTransactionMap(), new TestTransaction(coordinatorTrId, TransactionStatus.COMMIT_STARTED)); assertTransactions(participant2.getTransactionMap()); - TestTransactionParticipant participant1AfterCrash = - createParticipant(transactionConfiguration, TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); + TestTransactionParticipantApi participant1AfterCrash = + createParticipant(createConfiguration(true, 60, 10), TEST_PARTICIPANT_1_ID, TRANSACTION_LOG_PARTICIPANT_1_FOLDER); participant1AfterCrash.setTestTransactionMapping(Map.of(coordinatorTrId, participant1TrId)); // replace original participant with a new instance participants.set(0, participant1AfterCrash);