/**
*
* Copyright 2004 Protique Ltd
*
* 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.
*
**/
package org.activemq.test;
import org.activemq.ActiveMQConnectionFactory;
import org.activemq.TestSupport;
import org.activemq.util.IndentPrinter;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.XASession;
import javax.transaction.xa.XAResource;
import java.util.ArrayList;
/**
* @version $Revision: 1.1.1.1 $
*/
public abstract class JmsXATransactionTestSupport extends TestSupport {
static boolean firstRun;
protected ConnectionFactory connectionFactory;
protected Connection connection;
protected Session session;
protected MessageConsumer consumer;
protected MessageProducer producer;
private JmsResourceProvider provider;
private MessageProducer producer2;
private Destination destination;
public JmsXATransactionTestSupport() {
super();
}
public JmsXATransactionTestSupport(String name) {
super(name);
}
public void testSendOutsideXATransaction() throws Exception {
try {
producer.send(session.createTextMessage("First Message"));
fail("Using an XA session outside of a transaction should throw an exception.");
}
catch (JMSException e) {
// normal
}
}
public void testSendRollback() throws Exception {
XAResource resource = ((XASession) session).getXAResource();
Message[] outbound = new Message[]{
session.createTextMessage("First Message"),
session.createTextMessage("Second Message")
};
XidStub xid1 = new XidStub(new byte[]{1, 2, 3, 4, 5});
resource.start(xid1, XAResource.TMNOFLAGS);
producer.send(outbound[0]);
resource.end(xid1, XAResource.TMSUCCESS);
resource.commit(xid1, true);
XidStub xid2 = new XidStub(new byte[]{2, 2, 3, 4, 5});
resource.start(xid2, XAResource.TMNOFLAGS);
producer.send(session.createTextMessage("I'm going to get rolled back."));
resource.end(xid2, XAResource.TMSUCCESS);
resource.rollback(xid2);
XidStub xid3 = new XidStub(new byte[]{3, 2, 3, 4, 5});
resource.start(xid3, XAResource.TMNOFLAGS);
producer.send(outbound[1]);
resource.end(xid3, XAResource.TMSUCCESS);
if (resource.prepare(xid3) == XAResource.XA_OK) {
resource.commit(xid3, false);
}
ArrayList messages = new ArrayList();
XidStub xid4 = new XidStub(new byte[]{4, 2, 3, 4, 5});
resource.start(xid4, XAResource.TMNOFLAGS);
messages.add(consumer.receive(1000));
messages.add(consumer.receive(1000));
resource.end(xid4, XAResource.TMSUCCESS);
resource.commit(xid4, true);
Message inbound[] = new Message[messages.size()];
messages.toArray(inbound);
assertTextMessagesEqual("Rollback did not work.", outbound, inbound);
}
public void testSendPrepareRecoverRollback() throws Exception {
XAResource resource = ((XASession) session).getXAResource();
Message[] outbound = new Message[]{
session.createTextMessage("First Message"),
session.createTextMessage("Second Message")
};
XidStub xid2 = new XidStub(new byte[]{1, 2, 3, 4, 6});
resource.start(xid2, XAResource.TMNOFLAGS);
producer.send(session.createTextMessage("I'm going to get rolled back."));
resource.end(xid2, XAResource.TMSUCCESS);
assertEquals(XAResource.XA_OK, resource.prepare(xid2));
XidStub xid3 = new XidStub(new byte[]{2, 2, 3, 4, 6});
resource.start(xid3, XAResource.TMNOFLAGS);
producer.send(outbound[1]);
resource.end(xid3, XAResource.TMSUCCESS);
assertEquals(XAResource.XA_OK, resource.prepare(xid3));
restart();
resource = ((XASession) session).getXAResource();
// lets commit a transaction
resource.commit(xid3, false);
// lets try rollback a transaction
resource.rollback(xid2);
}
public void testXAWith2Sessions() throws Exception {
Session session2 = provider.createSession(connection);
System.out.println("Created session: " + session2);
producer2 = provider.createProducer(session2, destination);
System.out.println("Created producer: " + producer2);
XAResource resource1 = ((XASession) session).getXAResource();
XAResource resource2 = ((XASession) session2).getXAResource();
Message[] outbound = new Message[]{
session.createTextMessage("First Message!"),
session.createTextMessage("Second Message!")
};
XidStub xid1 = new XidStub(new byte[]{1, 2, 3, 4, 5});
resource1.start(xid1, XAResource.TMNOFLAGS);
resource2.start(xid1, XAResource.TMNOFLAGS);
producer.send(outbound[0]);
producer2.send(outbound[1]);
resource1.end(xid1, XAResource.TMSUCCESS);
resource2.end(xid1, XAResource.TMSUCCESS);
resource1.commit(xid1, true);
ArrayList messages = new ArrayList();
XidStub xid4 = new XidStub(new byte[]{4, 2, 3, 4, 5});
resource1.start(xid4, XAResource.TMNOFLAGS);
messages.add(consumer.receive(1000));
messages.add(consumer.receive(1000));
resource1.end(xid4, XAResource.TMSUCCESS);
resource1.commit(xid4, true);
Message inbound[] = new Message[messages.size()];
messages.toArray(inbound);
assertTextMessagesEqual("Failed.", outbound, inbound);
}
abstract protected JmsResourceProvider getJmsResourceProvider();
protected void setUp() throws Exception {
if( !firstRun ) {
TestSupport.removeMessageStore();
firstRun=true;
}
super.setUp();
openConnection();
}
protected void restart() throws JMSException {
try {
closeConnection();
openConnection();
} catch (JMSException e) {
e.printStackTrace();
throw e;
}
}
protected void openConnection() throws JMSException {
provider = getJmsResourceProvider();
connectionFactory = provider.createConnectionFactory();
connection = provider.createConnection(connectionFactory);
System.out.println("Created connection: " + connection);
session = provider.createSession(connection);
System.out.println("Created session: " + session);
destination = provider.createDestination(session, "QUEUE."+getName()+"."+System.currentTimeMillis());
System.out.println("Created destination: " + destination + " of type: " + destination.getClass());
producer = provider.createProducer(session, destination);
System.out.println("Created producer: " + producer);
consumer = provider.createConsumer(session, destination);
System.out.println("Created consumer: " + consumer);
connection.start();
}
protected void tearDown() throws Exception {
System.out.println("Test Done. Stats");
((ActiveMQConnectionFactory) connectionFactory).getFactoryStats().dump(new IndentPrinter());
closeConnection();
}
private void closeConnection() throws JMSException {
System.out.println("Closing down connection");
connection.stop();
connection.close();
System.out.println("Connection closed.");
}
}