Skip to content
Snippets Groups Projects
Commit a7cc8344 authored by piotr.kupczyk@id.ethz.ch's avatar piotr.kupczyk@id.ethz.ch
Browse files

SSDM-13578 : 2PT : Database and V3 Implementation - make coordinator testable

parent ccd8ea20
No related branches found
No related tags found
1 merge request!40SSDM-13578 : 2PT : Database and V3 Implementation - include the new AFS "free"...
package ch.ethz.sis.openbis.generic.server.asapi.v3;
public interface ITransactionCoordinatorParticipant
{
void beginTransaction(final String transactionId);
void prepareTransaction(final String transactionId);
void commitTransaction(final String transactionId);
void rollbackTransaction(final String transactionId);
}
package ch.ethz.sis.openbis.generic.server.asapi.v3;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
......@@ -26,41 +28,51 @@ public class TransactionCoordinator implements ITransactionCoordinator
private static final long TIMEOUT = 10000000;
private IApplicationServerApiWithTransactions applicationServerApi;
private final List<ITransactionCoordinatorParticipant> participants = new ArrayList<>();
private IApplicationServerApiWithTransactions applicationServerApi2;
public TransactionCoordinator()
{
}
public TransactionCoordinator(List<ITransactionCoordinatorParticipant> participants)
{
this.participants.addAll(participants);
}
@PostConstruct
public void init()
{
applicationServerApi = HttpInvokerUtils.createServiceStub(IApplicationServerApiWithTransactions.class,
APPLICATION_SERVER_URL + "/openbis/openbis" + IApplicationServerApi.SERVICE_URL, TIMEOUT,
new InvocationFactoryWithTransactionAttributes());
applicationServerApi2 = HttpInvokerUtils.createServiceStub(IApplicationServerApiWithTransactions.class,
APPLICATION_SERVER_URL_2 + "/openbis/openbis" + IApplicationServerApi.SERVICE_URL, TIMEOUT,
new InvocationFactoryWithTransactionAttributes());
this.participants.add(new ApplicationServerApiParticipant(APPLICATION_SERVER_URL, TIMEOUT));
this.participants.add(new ApplicationServerApiParticipant(APPLICATION_SERVER_URL_2, TIMEOUT));
}
@Override public void beginTransaction(final String transactionId)
{
applicationServerApi.beginTransaction(transactionId);
applicationServerApi2.beginTransaction(transactionId);
for (ITransactionCoordinatorParticipant participant : participants)
{
participant.beginTransaction(transactionId);
}
}
@Override public void commitTransaction(final String transactionId)
{
applicationServerApi.prepareTransaction(transactionId);
applicationServerApi2.prepareTransaction(transactionId);
for (ITransactionCoordinatorParticipant participant : participants)
{
participant.prepareTransaction(transactionId);
}
applicationServerApi.commitTransaction(transactionId);
applicationServerApi2.commitTransaction(transactionId);
for (ITransactionCoordinatorParticipant participant : participants)
{
participant.commitTransaction(transactionId);
}
}
@Override public void rollbackTransaction(final String transactionId)
{
applicationServerApi.rollbackTransaction(transactionId);
applicationServerApi2.rollbackTransaction(transactionId);
for (ITransactionCoordinatorParticipant participant : participants)
{
participant.rollbackTransaction(transactionId);
}
}
@Override public int getMajorVersion()
......@@ -73,6 +85,50 @@ public class TransactionCoordinator implements ITransactionCoordinator
return 0;
}
private interface IApplicationServerApiWithTransactions extends IApplicationServerApi
{
void beginTransaction(String transactionId);
void prepareTransaction(String transactionId);
void commitTransaction(String transactionId);
void rollbackTransaction(String transactionId);
}
private static class ApplicationServerApiParticipant implements ITransactionCoordinatorParticipant
{
private final IApplicationServerApiWithTransactions applicationServerApi;
public ApplicationServerApiParticipant(String applicationServerUrl, long timeout)
{
applicationServerApi = HttpInvokerUtils.createServiceStub(IApplicationServerApiWithTransactions.class,
applicationServerUrl + "/openbis/openbis" + IApplicationServerApi.SERVICE_URL, timeout,
new InvocationFactoryWithTransactionAttributes());
}
@Override public void beginTransaction(final String transactionId)
{
applicationServerApi.beginTransaction(transactionId);
}
@Override public void prepareTransaction(final String transactionId)
{
applicationServerApi.prepareTransaction(transactionId);
}
@Override public void commitTransaction(final String transactionId)
{
applicationServerApi.commitTransaction(transactionId);
}
@Override public void rollbackTransaction(final String transactionId)
{
applicationServerApi.rollbackTransaction(transactionId);
}
}
private static class InvocationFactoryWithTransactionAttributes extends DefaultRemoteInvocationFactory
{
@Override public RemoteInvocation createRemoteInvocation(final MethodInvocation methodInvocation)
......@@ -99,15 +155,4 @@ public class TransactionCoordinator implements ITransactionCoordinator
}
}
private interface IApplicationServerApiWithTransactions extends IApplicationServerApi
{
void beginTransaction(String transactionId);
void prepareTransaction(String transactionId);
void commitTransaction(String transactionId);
void rollbackTransaction(String transactionId);
}
}
package ch.ethz.sis.openbis.generic.server.asapi.v3;
import java.util.List;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class TransactionCoordinatorTest
{
public static final String TEST_TRANSACTION_ID = "test-id";
private Mockery mockery;
private ITransactionCoordinatorParticipant participant1;
private ITransactionCoordinatorParticipant participant2;
@BeforeMethod
protected void beforeMethod()
{
mockery = new Mockery();
participant1 = mockery.mock(ITransactionCoordinatorParticipant.class, "participant1");
participant2 = mockery.mock(ITransactionCoordinatorParticipant.class, "participant2");
}
@AfterMethod
protected void afterMethod()
{
mockery.assertIsSatisfied();
}
@Test
public void testBeginTransactionAllParticipantsSucceed()
{
TransactionCoordinator coordinator = new TransactionCoordinator(List.of(participant1, participant2));
mockery.checking(new Expectations()
{
{
one(participant1).beginTransaction(with(TEST_TRANSACTION_ID));
one(participant2).beginTransaction(with(TEST_TRANSACTION_ID));
}
});
coordinator.beginTransaction(TEST_TRANSACTION_ID);
}
@Test
public void testBeginTransactionSomeParticipantFails()
{
TransactionCoordinator coordinator = new TransactionCoordinator(List.of(participant1, participant2));
mockery.checking(new Expectations()
{
{
one(participant1).beginTransaction(with(TEST_TRANSACTION_ID));
one(participant2).beginTransaction(with(TEST_TRANSACTION_ID));
will(throwException(new RuntimeException()));
one(participant1).rollbackTransaction(with(TEST_TRANSACTION_ID));
one(participant2).rollbackTransaction(with(TEST_TRANSACTION_ID));
}
});
coordinator.beginTransaction(TEST_TRANSACTION_ID);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment