/**
*
* 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.codehaus.activemq;
import org.codehaus.activemq.message.XidStub;
import org.codehaus.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.7 $
*/
public abstract class JmsXATransactionTestSupport extends TestSupport {
protected ConnectionFactory connectionFactory;
protected Connection connection;
protected Session session;
protected MessageConsumer consumer;
protected MessageProducer producer;
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);
}
abstract protected JmsResourceProvider getJmsResourceProvider();
protected void setUp() throws Exception {
super.setUp();
openConnection();
}
protected void restart() throws JMSException {
closeConnection();
openConnection();
}
protected void openConnection() throws JMSException {
JmsResourceProvider p = getJmsResourceProvider();
connectionFactory = p.createConnectionFactory();
connection = p.createConnection(connectionFactory);
System.out.println("Created connection: " + connection);
session = p.createSession(connection);
System.out.println("Created session: " + session);
Destination destination = p.createDestination(session, "FOO");
System.out.println("Created destination: " + destination + " of type: " + destination.getClass());
producer = p.createProducer(session, destination);
System.out.println("Created producer: " + producer);
consumer = p.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.");
}
}