package org.jboss.narayana.rest.integration.test.functional;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.jboss.jbossts.star.util.TxLinkNames;
import org.jboss.jbossts.star.util.TxMediaType;
import org.jboss.jbossts.star.util.TxStatus;
import org.jboss.jbossts.star.util.TxSupport;
import org.jboss.narayana.rest.integration.ParticipantInformation;
import org.jboss.narayana.rest.integration.ParticipantResource;
import org.jboss.narayana.rest.integration.ParticipantsContainer;
import org.jboss.narayana.rest.integration.api.Aborted;
import org.jboss.narayana.rest.integration.api.Participant;
import org.jboss.narayana.rest.integration.api.Prepared;
import org.jboss.narayana.rest.integration.api.ReadOnly;
import org.jboss.narayana.rest.integration.test.common.LoggingParticipant;
import org.jboss.resteasy.plugins.server.netty.NettyJaxrsServer;
import org.jboss.resteasy.spi.ResteasyDeployment;
import org.jboss.resteasy.test.TestPortProvider;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.arjuna.ats.arjuna.common.Uid;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Link;
import javax.ws.rs.core.Response;
/**
*
* @author <a href="mailto:gytis@redhat.com">Gytis Trikleris</a>
*
*/
public final class ParticipantResourceTestCase {
private static final String APPLICATION_ID = "org.jboss.narayana.rest.integration.test.functional.ParticipantResourceTestCase";
private static final String BASE_URL = "http://localhost:" + TestPortProvider.getPort();
private static final String PARTICIPANT_URL = BASE_URL + "/" + ParticipantResource.BASE_PATH_SEGMENT;
private static NettyJaxrsServer NETTY;
private String participantId;
@BeforeClass
public static void beforeClass() {
List<String> resourceClasses = new ArrayList<String>();
resourceClasses.add("org.jboss.narayana.rest.integration.ParticipantResource");
ResteasyDeployment resteasyDeployment = new ResteasyDeployment();
resteasyDeployment.setResourceClasses(resourceClasses);
NETTY = new NettyJaxrsServer();
NETTY.setDeployment(resteasyDeployment);
NETTY.setPort(TestPortProvider.getPort());
NETTY.start();
}
@AfterClass
public static void afterClass() {
NETTY.stop();
}
@Before
public void before() {
participantId = new Uid().toString();
ParticipantsContainer.getInstance().clear();
}
@Test
@SuppressWarnings("rawtypes")
public void testRequestsToNotRegisteredParticipant() throws Exception {
Response simpleResponse = getParticipantTerminator(participantId);
Assert.assertEquals(404, simpleResponse.getStatus());
Response stringResponse = getParticipantStatus(participantId);
Assert.assertEquals(404, stringResponse.getStatus());
stringResponse = prepareParticipant(participantId);
Assert.assertEquals(404, stringResponse.getStatus());
simpleResponse = forgetParticipantHeuristic(participantId);
Assert.assertEquals(404, simpleResponse.getStatus());
}
@Test
@SuppressWarnings("rawtypes")
public void testGetTerminator() throws Exception {
registerParticipant(participantId, new LoggingParticipant(new ReadOnly()));
Response response = getParticipantTerminator(participantId);
Assert.assertEquals(200, response.getStatus());
Link link = response.getLink(TxLinkNames.TERMINATOR);
Assert.assertNotNull(link);
Assert.assertEquals(PARTICIPANT_URL + "/" + participantId, link.getUri().toString());
}
@Test
public void testGetStatus() throws Exception {
registerParticipant(participantId, new LoggingParticipant(new ReadOnly()));
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
participantInformation.setStatus(TxStatus.TransactionPrepared.name());
Response response = getParticipantStatus(participantId);
Assert.assertEquals(200, response.getStatus());
Assert.assertTrue(TxStatus.isPrepare(TxSupport.getStatus(response.readEntity(String.class))));
participantInformation.setStatus(TxStatus.TransactionCommitted.name());
response = ClientBuilder.newClient().target(PARTICIPANT_URL + "/" + participantId).request().get();
Assert.assertTrue(TxStatus.isCommit(TxSupport.getStatus(response.readEntity(String.class))));
}
@Test
public void testPrepareOutcomePrepared() throws Exception {
final LoggingParticipant participant = new LoggingParticipant(new Prepared());
registerParticipant(participantId, participant);
Response stringResponse = prepareParticipant(participantId);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
Assert.assertEquals(200, stringResponse.getStatus());
Assert.assertEquals(TxStatus.TransactionPrepared.name(), TxSupport.getStatus(stringResponse.readEntity(String.class)));
Assert.assertEquals(TxStatus.TransactionPrepared.name(), participantInformation.getStatus());
Assert.assertEquals(Arrays.asList(new String[] { "prepare" }), participant.getInvocations());
}
@Test
public void testPrepareOutcomeAborted() throws Exception {
final LoggingParticipant participant = new LoggingParticipant(new Aborted());
registerParticipant(participantId, participant);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
Response stringResponse = prepareParticipant(participantId);
Assert.assertEquals(409, stringResponse.getStatus());
Assert.assertEquals(TxStatus.TransactionRolledBack.name(), TxSupport.getStatus(stringResponse.readEntity(String.class)));
Assert.assertEquals(TxStatus.TransactionRolledBack.name(), participantInformation.getStatus());
Assert.assertEquals(Arrays.asList(new String[] { "prepare", "rollback" }), participant.getInvocations());
Assert.assertNull(ParticipantsContainer.getInstance().getParticipantInformation(participantId));
}
@Test
public void testPrepareOutcomeReadOnly() throws Exception {
final LoggingParticipant participant = new LoggingParticipant(new ReadOnly());
registerParticipant(participantId, participant);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
Response stringResponse = prepareParticipant(participantId);
Assert.assertEquals(200, stringResponse.getStatus());
Assert.assertEquals(TxStatus.TransactionReadOnly.name(), TxSupport.getStatus(stringResponse.readEntity(String.class)));
Assert.assertEquals(TxStatus.TransactionReadOnly.name(), participantInformation.getStatus());
Assert.assertEquals(Arrays.asList(new String[] { "prepare" }), participant.getInvocations());
Assert.assertNull(ParticipantsContainer.getInstance().getParticipantInformation(participantId));
}
@Test
public void testPreparePreparedTransaction() throws Exception {
final LoggingParticipant participant = new LoggingParticipant(new Prepared());
registerParticipant(participantId, participant);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
participantInformation.setStatus(TxStatus.TransactionPrepared.name());
Response stringResponse = prepareParticipant(participantId);
Assert.assertEquals(412, stringResponse.getStatus());
}
@Test
public void testCommit() throws Exception {
LoggingParticipant participant = new LoggingParticipant(new Prepared());
registerParticipant(participantId, participant);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
participantInformation.setStatus(TxStatus.TransactionPrepared.name());
Response stringResponse = commitParticipant(participantInformation.getId());
Assert.assertEquals(200, stringResponse.getStatus());
Assert.assertEquals(TxStatus.TransactionCommitted.name(), participantInformation.getStatus());
Assert.assertEquals(Arrays.asList(new String[] { "commit" }), participant.getInvocations());
Assert.assertNull(ParticipantsContainer.getInstance().getParticipantInformation(participantId));
}
@Test
public void testCommitWithoutPrepare() throws Exception {
LoggingParticipant participant = new LoggingParticipant(new Prepared());
registerParticipant(participantId, participant);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
Response stringResponse = commitParticipant(participantInformation.getId());
Assert.assertEquals(412, stringResponse.getStatus());
}
@Test
public void testCommitOnePhase() throws Exception {
LoggingParticipant participant = new LoggingParticipant(new Prepared());
registerParticipant(participantId, participant);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
Response stringResponse = commitParticipantInOnePhase(participantInformation.getId());
Assert.assertEquals(200, stringResponse.getStatus());
Assert.assertEquals(TxStatus.TransactionCommittedOnePhase.name(), participantInformation.getStatus());
Assert.assertEquals(Arrays.asList(new String[] { "commitOnePhase" }), participant.getInvocations());
Assert.assertNull(ParticipantsContainer.getInstance().getParticipantInformation(participantId));
}
@Test
public void testCommitOnePhaseAfterPrepare() throws Exception {
LoggingParticipant participant = new LoggingParticipant(new Prepared());
registerParticipant(participantId, participant);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
participantInformation.setStatus(TxStatus.TransactionPrepared.name());
Response stringResponse = commitParticipantInOnePhase(participantInformation.getId());
Assert.assertEquals(412, stringResponse.getStatus());
}
@Test
public void testRollback() throws Exception {
LoggingParticipant participant = new LoggingParticipant(new Prepared());
registerParticipant(participantId, participant);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
Response stringResponse = rollbackParticipant(participantInformation.getId());
Assert.assertEquals(200, stringResponse.getStatus());
Assert.assertEquals(TxStatus.TransactionRolledBack.name(), participantInformation.getStatus());
Assert.assertEquals(Arrays.asList(new String[] { "rollback" }), participant.getInvocations());
Assert.assertNull(ParticipantsContainer.getInstance().getParticipantInformation(participantId));
}
@Test
public void testRollbackAfterPrepare() throws Exception {
LoggingParticipant participant = new LoggingParticipant(new Prepared());
registerParticipant(participantId, participant);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
participantInformation.setStatus(TxStatus.TransactionPrepared.name());
Response stringResponse = rollbackParticipant(participantInformation.getId());
Assert.assertEquals(200, stringResponse.getStatus());
Assert.assertEquals(TxStatus.TransactionRolledBack.name(), participantInformation.getStatus());
Assert.assertEquals(Arrays.asList(new String[] { "rollback" }), participant.getInvocations());
Assert.assertNull(ParticipantsContainer.getInstance().getParticipantInformation(participantId));
}
@Test
@SuppressWarnings("rawtypes")
public void testForgetHeuristic() throws Exception {
LoggingParticipant participant = new LoggingParticipant(new Prepared());
registerParticipant(participantId, participant);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
participantInformation.setStatus(TxStatus.TransactionHeuristicRollback.name());
Response simpleResponse = forgetParticipantHeuristic(participantId);
Assert.assertEquals(200, simpleResponse.getStatus());
Assert.assertNull(ParticipantsContainer.getInstance().getParticipantInformation(participantId));
}
@Test
@SuppressWarnings("rawtypes")
public void testForgetHeuristicWithoutHeuristic() throws Exception {
LoggingParticipant participant = new LoggingParticipant(new Prepared());
registerParticipant(participantId, participant);
Response simpleResponse = forgetParticipantHeuristic(participantId);
ParticipantInformation participantInformation = ParticipantsContainer.getInstance().getParticipantInformation(
participantId);
Assert.assertEquals(412, simpleResponse.getStatus());
Assert.assertEquals(TxStatus.TransactionActive.name(), participantInformation.getStatus());
}
private void registerParticipant(final String participantId, final Participant participant)
throws MalformedURLException {
ParticipantInformation participantInformation = new ParticipantInformation(participantId, APPLICATION_ID, "",
participant);
participantInformation.setStatus(TxStatus.TransactionActive.name());
ParticipantsContainer.getInstance().addParticipantInformation(participantId, participantInformation);
}
@SuppressWarnings("rawtypes")
private Response getParticipantTerminator(final String participantId) throws Exception {
return ClientBuilder.newClient().target(PARTICIPANT_URL + "/" + participantId).request().head();
}
private Response getParticipantStatus(final String participantId) throws Exception {
return ClientBuilder.newClient().target(PARTICIPANT_URL + "/" + participantId).request().get();
}
private Response prepareParticipant(final String participantId) throws Exception {
return ClientBuilder.newClient().target(PARTICIPANT_URL + "/" + participantId).request().put(
Entity.entity(TxSupport.toStatusContent(TxStatus.TransactionPrepared.name()), TxMediaType.TX_STATUS_MEDIA_TYPE));
}
private Response commitParticipant(final String participantId) throws Exception {
return ClientBuilder.newClient().target(PARTICIPANT_URL + "/" + participantId).request().put(
Entity.entity(
TxSupport.toStatusContent(TxStatus.TransactionCommitted.name()),
TxMediaType.TX_STATUS_MEDIA_TYPE));
}
private Response commitParticipantInOnePhase(final String participantId) throws Exception {
return ClientBuilder.newClient().target(PARTICIPANT_URL + "/" + participantId).request().put(
Entity.entity(
TxSupport.toStatusContent(TxStatus.TransactionCommittedOnePhase.name()),
TxMediaType.TX_STATUS_MEDIA_TYPE));
}
private Response rollbackParticipant(final String participantId) throws Exception {
return ClientBuilder.newClient().target(PARTICIPANT_URL + "/" + participantId).request().put(
Entity.entity(
TxSupport.toStatusContent(TxStatus.TransactionRolledBack.name()),
TxMediaType.TX_STATUS_MEDIA_TYPE));
}
@SuppressWarnings("rawtypes")
private Response forgetParticipantHeuristic(final String participantId) throws Exception {
return ClientBuilder.newClient().target(PARTICIPANT_URL + "/" + participantId).request().delete();
}
}