/*
* JBoss, Home of Professional Open Source
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.messaging.jms;
import javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.management.ObjectName;
/**
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
*
* $Id$
*/
public class TransactedSessionTest extends JMSTestCase
{
// Constants -----------------------------------------------------
// Static --------------------------------------------------------
// Attributes ----------------------------------------------------
// Constructors --------------------------------------------------
public TransactedSessionTest(String name)
{
super(name);
}
// Public --------------------------------------------------------
public void testSimpleRollback() throws Exception
{
// send a message
Connection conn = null;
try
{
conn = cf.createConnection();
Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
s.createProducer(queue1).send(s.createTextMessage("one"));
s.close();
s = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageConsumer c = s.createConsumer(queue1);
conn.start();
Message m = c.receive(1000);
assertNotNull(m);
assertEquals("one", ((TextMessage)m).getText());
assertFalse(m.getJMSRedelivered());
assertEquals(1, m.getIntProperty("JMSXDeliveryCount"));
s.rollback();
// get the message again
m = c.receive(1000);
assertNotNull(m);
assertTrue(m.getJMSRedelivered());
assertEquals(2, m.getIntProperty("JMSXDeliveryCount"));
conn.close();
ObjectName on = new ObjectName("jboss.messaging.destination:service=Queue,name=Queue1");
Integer i = getMessageCountForQueue("Queue1");
assertEquals(1, i.intValue());
}
finally
{
if (conn != null)
{
conn.close();
}
removeAllMessages(queue1.getQueueName(), true, 0);
}
}
public void testRedeliveredFlagTopic() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session sessSend = conn.createSession(true, Session.SESSION_TRANSACTED);
Session sess1 = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageConsumer consumer1 = sess1.createConsumer(topic1);
MessageProducer producer = sessSend.createProducer(topic1);
Message mSent = sessSend.createTextMessage("igloo");
producer.send(mSent);
sessSend.commit();
conn.start();
TextMessage mRec1 = (TextMessage)consumer1.receive(2000);
assertNotNull(mRec1);
assertEquals("igloo", mRec1.getText());
assertFalse(mRec1.getJMSRedelivered());
sess1.rollback(); //causes redelivery for session
mRec1 = (TextMessage)consumer1.receive(2000);
assertEquals("igloo", mRec1.getText());
assertTrue(mRec1.getJMSRedelivered());
sess1.commit();
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/** Test redelivery works ok for Topic */
public void testRedeliveredTopic() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageProducer producer = sess.createProducer(topic1);
MessageConsumer consumer = sess.createConsumer(topic1);
conn.start();
Message mSent = sess.createTextMessage("igloo");
producer.send(mSent);
sess.commit();
TextMessage mRec = (TextMessage)consumer.receive(2000);
assertEquals("igloo", mRec.getText());
assertFalse(mRec.getJMSRedelivered());
sess.rollback();
mRec = (TextMessage)consumer.receive(2000);
assertNotNull(mRec);
assertEquals("igloo", mRec.getText());
assertTrue(mRec.getJMSRedelivered());
sess.commit();
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
public void testReceivedRollbackTopic() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageProducer producer = sess.createProducer(topic1);
MessageConsumer consumer = sess.createConsumer(topic1);
conn.start();
TextMessage mSent = sess.createTextMessage("igloo");
producer.send(mSent);
sess.commit();
TextMessage mRec = (TextMessage)consumer.receive(2000);
assertEquals("igloo", mRec.getText());
sess.commit();
mSent.setText("rollback");
producer.send(mSent);
sess.commit();
mRec = (TextMessage)consumer.receive(2000);
sess.rollback();
TextMessage mRec2 = (TextMessage)consumer.receive(2000);
sess.commit();
assertNotNull(mRec2);
assertEquals(mRec.getText(), mRec2.getText());
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/**
* Send some messages in transacted session. Don't commit.
* Verify message are not received by consumer.
*/
public void testSendNoCommitTopic() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageProducer producer = producerSess.createProducer(topic1);
Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = consumerSess.createConsumer(topic1);
conn.start();
final int NUM_MESSAGES = 10;
//Send some messages
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
Message m = consumer.receive(500);
assertNull(m);
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/**
* Send some messages in transacted session. Commit.
* Verify message are received by consumer.
*/
public void testSendCommitTopic() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageProducer producer = producerSess.createProducer(topic1);
Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = consumerSess.createConsumer(topic1);
conn.start();
final int NUM_MESSAGES = 10;
//Send some messages
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
producerSess.commit();
int count = 0;
while (true)
{
Message m = consumer.receive(500);
if (m == null) break;
count++;
}
assertEquals(NUM_MESSAGES, count);
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/**
* Send some messages.
* Receive them in a transacted session.
* Commit the receiving session
* Close the connection
* Create a new connection, session and consumer - verify messages are not redelivered
*/
public void testAckCommitTopic() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = producerSess.createProducer(topic1);
Session consumerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageConsumer consumer = consumerSess.createConsumer(topic1);
conn.start();
final int NUM_MESSAGES = 10;
//Send some messages
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
int count = 0;
while (true)
{
Message m = consumer.receive(500);
if (m == null) break;
count++;
}
assertEquals(NUM_MESSAGES, count);
consumerSess.commit();
conn.stop();
consumer.close();
conn.close();
conn = cf.createConnection();
consumerSess = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE);
consumer = consumerSess.createConsumer(queue1);
conn.start();
Message m = consumer.receive(500);
assertNull(m);
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/*
* Send some messages in a transacted session.
* Rollback the session.
* Verify messages aren't received by consumer.
*/
public void testSendRollbackTopic() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageProducer producer = producerSess.createProducer(topic1);
Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = consumerSess.createConsumer(topic1);
conn.start();
final int NUM_MESSAGES = 10;
//Send some messages
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
producerSess.rollback();
Message m = consumer.receive(500);
assertNull(m);
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/**
* Make sure redelivered flag is set on redelivery via rollback
*/
public void testRedeliveredQueue() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageProducer producer = sess.createProducer(queue1);
MessageConsumer consumer = sess.createConsumer(queue1);
conn.start();
Message mSent = sess.createTextMessage("igloo");
producer.send(mSent);
sess.commit();
TextMessage mRec = (TextMessage)consumer.receive(2000);
assertEquals("igloo", mRec.getText());
assertFalse(mRec.getJMSRedelivered());
sess.rollback();
mRec = (TextMessage)consumer.receive(2000);
assertEquals("igloo", mRec.getText());
assertTrue(mRec.getJMSRedelivered());
sess.commit();
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/**
* Make sure redelivered flag is set on redelivery via rollback, different setup: we close the
* rolled back session and we receive the message whose acknowledgment was cancelled on a new
* session.
*/
public void testRedeliveredQueue2() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session sendSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer prod = sendSession.createProducer(queue1);
prod.send(sendSession.createTextMessage("a message"));
conn.close();
conn = cf.createConnection();
Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageConsumer cons = sess.createConsumer(queue1);
conn.start();
TextMessage tm = (TextMessage)cons.receive(1000);
assertNotNull(tm);
assertEquals("a message", tm.getText());
assertFalse(tm.getJMSRedelivered());
assertEquals(1, tm.getIntProperty("JMSXDeliveryCount"));
log.info("rolling back");
sess.rollback();
log.info("closing");
sess.close();
log.info("Closed");
Session sess2 = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
cons = sess2.createConsumer(queue1);
tm = (TextMessage)cons.receive(1000);
assertEquals("a message", tm.getText());
assertEquals(2, tm.getIntProperty("JMSXDeliveryCount"));
assertTrue(tm.getJMSRedelivered());
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
public void testReceivedRollbackQueue() throws Exception
{
Connection conn = cf.createConnection();
Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageProducer producer = sess.createProducer(queue1);
MessageConsumer consumer = sess.createConsumer(queue1);
conn.start();
TextMessage mSent = sess.createTextMessage("igloo");
producer.send(mSent);
log.trace("sent1");
sess.commit();
TextMessage mRec = (TextMessage)consumer.receive(1000);
assertNotNull(mRec);
log.trace("Got 1");
assertNotNull(mRec);
assertEquals("igloo", mRec.getText());
sess.commit();
mSent.setText("rollback");
producer.send(mSent);
sess.commit();
log.trace("Receiving 2");
mRec = (TextMessage)consumer.receive(1000);
assertNotNull(mRec);
log.trace("Received 2");
assertNotNull(mRec);
assertEquals("rollback", mRec.getText());
sess.rollback();
TextMessage mRec2 = (TextMessage)consumer.receive(1000);
assertNotNull(mRec2);
assertEquals("rollback", mRec2.getText());
sess.commit();
assertEquals(mRec.getText(), mRec2.getText());
conn.close();
}
/**
* Send some messages in transacted session. Don't commit.
* Verify message are not received by consumer.
*/
public void testSendNoCommitQueue() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE);
MessageProducer producer = producerSess.createProducer(queue1);
Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = consumerSess.createConsumer(queue1);
conn.start();
final int NUM_MESSAGES = 10;
//Send some messages
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
log.info("Sent messages");
checkEmpty(queue1);
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/**
* Send some messages in transacted session. Commit.
* Verify message are received by consumer.
*/
public void testSendCommitQueue() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE);
MessageProducer producer = producerSess.createProducer(queue1);
Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = consumerSess.createConsumer(queue1);
conn.start();
final int NUM_MESSAGES = 10;
//Send some messages
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
producerSess.commit();
int count = 0;
while (true)
{
Message m = consumer.receive(500);
if (m == null) break;
count++;
}
assertEquals(NUM_MESSAGES, count);
}
finally
{
if (conn != null)
{
conn.close();
}
removeAllMessages(queue1.getQueueName(), true, 0);
}
}
/**
* Test IllegateStateException is thrown if commit is called on a non-transacted session
*/
public void testCommitIllegalState() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
boolean thrown = false;
try
{
producerSess.commit();
}
catch (javax.jms.IllegalStateException e)
{
thrown = true;
}
assertTrue(thrown);
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/**
* Send some messages.
* Receive them in a transacted session.
* Do not commit the receiving session.
* Close the connection
* Create a new connection, session and consumer - verify messages are redelivered
*
*/
public void testAckNoCommitQueue() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = producerSess.createProducer(queue1);
Session consumerSess = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = consumerSess.createConsumer(queue1);
conn.start();
final int NUM_MESSAGES = 10;
//Send some messages
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
int count = 0;
while (true)
{
Message m = consumer.receive(500);
if (m == null) break;
count++;
}
assertEquals(NUM_MESSAGES, count);
conn.stop();
log.info("closing consumer");
consumer.close();
log.info("closed consumer");
log.info("closing connection");
conn.close();
log.info("closed connection");
conn = cf.createConnection();
consumerSess = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE);
consumer = consumerSess.createConsumer(queue1);
conn.start();
count = 0;
log.info("Receiving...");
while (true)
{
Message m = consumer.receive(500);
if (m == null) break;
count++;
}
log.info("Done receive");
assertEquals(NUM_MESSAGES, count);
}
finally
{
if (conn != null)
{
conn.close();
}
removeAllMessages(queue1.getQueueName(), true, 0);
}
}
/**
* Send some messages.
* Receive them in a transacted session.
* Commit the receiving session
* Close the connection
* Create a new connection, session and consumer - verify messages are not redelivered
*/
public void testAckCommitQueue() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = producerSess.createProducer(queue1);
Session consumerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
MessageConsumer consumer = consumerSess.createConsumer(queue1);
conn.start();
final int NUM_MESSAGES = 10;
//Send some messages
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
int count = 0;
while (true)
{
Message m = consumer.receive(500);
if (m == null) break;
count++;
}
assertEquals(NUM_MESSAGES, count);
log.info("Comitting sesion");
consumerSess.commit();
log.info("Committed session");
conn.stop();
consumer.close();
conn.close();
conn = cf.createConnection();
consumerSess = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE);
consumer = consumerSess.createConsumer(queue1);
conn.start();
Message m = consumer.receive(500);
assertNull(m);
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/*
* Send some messages in a transacted session.
* Rollback the session.
* Verify messages aren't received by consumer.
*/
public void testSendRollbackQueue() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = producerSess.createProducer(queue1);
Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = consumerSess.createConsumer(queue1);
conn.start();
final int NUM_MESSAGES = 10;
//Send some messages
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
producerSess.rollback();
Message m = consumer.receive(500);
assertNull(m);
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/*
* Test IllegateStateException is thrown if rollback is
* called on a non-transacted session
*
*/
public void testRollbackIllegalState() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
boolean thrown = false;
try
{
producerSess.rollback();
}
catch (javax.jms.IllegalStateException e)
{
thrown = true;
}
assertTrue(thrown);
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
/*
* Send some messages.
* Receive them in a transacted session.
* Rollback the receiving session
* Close the connection
* Create a new connection, session and consumer - verify messages are redelivered
*
*/
public void testAckRollbackQueue() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = producerSess.createProducer(queue1);
Session consumerSess = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = consumerSess.createConsumer(queue1);
conn.start();
final int NUM_MESSAGES = 10;
//Send some messages
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
int count = 0;
while (true)
{
Message m = consumer.receive(500);
if (m == null) break;
count++;
}
assertEquals(NUM_MESSAGES, count);
consumerSess.rollback();
conn.stop();
consumer.close();
conn.close();
conn = cf.createConnection();
consumerSess = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE);
consumer = consumerSess.createConsumer(queue1);
conn.start();
count = 0;
while (true)
{
Message m = consumer.receive(500);
if (m == null) break;
count++;
}
assertEquals(NUM_MESSAGES, count);
}
finally
{
if (conn != null)
{
conn.close();
}
removeAllMessages(queue1.getQueueName(), true, 0);
}
}
/*
* Send multiple messages in multiple contiguous sessions
*/
public void testSendMultipleQueue() throws Exception
{
Connection conn = null;
try
{
conn = cf.createConnection();
Session producerSess = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = producerSess.createProducer(queue1);
Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = consumerSess.createConsumer(queue1);
conn.start();
final int NUM_MESSAGES = 10;
final int NUM_TX = 10;
//Send some messages
for (int j = 0; j < NUM_TX; j++)
{
for (int i = 0; i < NUM_MESSAGES; i++)
{
Message m = producerSess.createMessage();
producer.send(m);
}
producerSess.commit();
}
int count = 0;
while (true)
{
Message m = consumer.receive(500);
if (m == null) break;
count++;
m.acknowledge();
}
assertEquals(NUM_MESSAGES * NUM_TX, count);
}
finally
{
if (conn != null)
{
conn.close();
}
}
}
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
// Private -------------------------------------------------------
// Inner classes -------------------------------------------------
}