/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file 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.jbossmessaging.test;
import javax.jms.BytesMessage;
import javax.jms.DeliveryMode;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.naming.Context;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.jboss.logging.Logger;
import org.jboss.test.JBossJMSTestCase;
import org.jboss.test.util.jms.JMSDestinationsUtil;
/**
* Rollback tests
*
* @author <a href="mailto:richard.achmatowicz@jboss.com">Richard Achmatowicz</a>
* @author
* @version $Revision: 105321 $
*/
public class UnackedUnitTestCase extends JBossJMSTestCase
{
// Provider specific
static String TOPIC_FACTORY = "ConnectionFactory";
static String QUEUE_FACTORY = "ConnectionFactory";
static String TEST_QUEUE = "queue/testQueue";
static String TEST_TOPIC = "topic/testTopic";
static String TEST_DURABLE_TOPIC = "topic/testDurableTopic";
static byte[] PAYLOAD = new byte[10];
static Context context;
static QueueConnection queueConnection;
static TopicConnection topicConnection;
static TopicConnection topicDurableConnection;
public static Test suite() throws Exception
{
// JBAS-3580, the execution order of tests in this test case is important
// so it must be defined explicitly when running under some JVMs
TestSuite suite = new TestSuite();
suite.addTest(new UnackedUnitTestCase("testUnackedQueue"));
suite.addTest(new UnackedUnitTestCase("testUnackedMultipleConnection"));
suite.addTest(new UnackedUnitTestCase("testUnackedMultipleSession"));
suite.addTest(new UnackedUnitTestCase("testUnackedTopic"));
suite.addTest(new UnackedUnitTestCase("testUnackedDurableTopic"));
suite.addTest(new UnackedUnitTestCase("testDummyLast"));
return suite;
}
/**
* Constructor the test
*
* @param name Description of Parameter
* @exception Exception Description of Exception
*/
public UnackedUnitTestCase(String name) throws Exception
{
super(name);
}
/**
* #Description of the Method
*
* @param persistence Description of Parameter
* @exception Exception Description of Exception
*/
public void runUnackedQueue(final int persistence) throws Exception
{
drainQueue();
final int iterationCount = getIterationCount();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue)context.lookup(TEST_QUEUE);
QueueSender sender = session.createSender(queue);
Message message = session.createBytesMessage();
((BytesMessage)message).writeBytes(PAYLOAD);
for (int i = 0; i < iterationCount; i++)
sender.send(message, persistence, 4, 0);
session.close();
session = queueConnection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
queue = (Queue)context.lookup(TEST_QUEUE);
QueueReceiver receiver = session.createReceiver(queue);
queueConnection.start();
message = receiver.receive(50);
int c = 0;
while (message != null)
{
message = receiver.receive(50);
c++;
}
assertTrue("Should have received all data unacked", c == iterationCount);
queueConnection.close();
QueueConnectionFactory queueFactory = (QueueConnectionFactory)context.lookup(QUEUE_FACTORY);
queueConnection = queueFactory.createQueueConnection();
assertTrue("Queue should be full", drainQueue() == iterationCount);
}
/**
* #Description of the Method
*
* @param persistence Description of Parameter
* @exception Exception Description of Exception
*/
public void runUnackedMultipleSession(final int persistence) throws Exception
{
System.out.println("++ runUnackedMultipleSession");
drainQueue();
final int iterationCount = getIterationCount();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue)context.lookup(TEST_QUEUE);
QueueSender sender = session.createSender(queue);
Message message = session.createBytesMessage();
((BytesMessage)message).writeBytes(PAYLOAD);
for (int i = 0; i < iterationCount; i++)
sender.send(message, persistence, 4, 0);
session.close();
QueueSession session1 = queueConnection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
QueueSession session2 = queueConnection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
try
{
queue = (Queue)context.lookup(TEST_QUEUE);
QueueReceiver receiver1 = session1.createReceiver(queue);
QueueReceiver receiver2 = session2.createReceiver(queue);
queueConnection.start();
int c1=0, c2=0;
Message messageConsumer1=null, messageConsumer2=null;
Message lastMessageConsumer1 = null, lastMessageConsumer2=null;
do
{
messageConsumer1 = receiver1.receive(1000);
messageConsumer2 = receiver2.receive(1000);
if (messageConsumer1 != null)
{
c1 ++;
lastMessageConsumer1 = messageConsumer1;
}
if (messageConsumer2 != null)
{
c2 ++;
lastMessageConsumer2 = messageConsumer2;
}
System.out.println("messageConsumer1=" + messageConsumer1 + " messageConsumer2=" + messageConsumer2 + " c1=" + c1 + " c2 = " + c2);
}
while (messageConsumer1!=null || messageConsumer2!=null);
assertEquals(iterationCount, c1 + c2);
if(lastMessageConsumer1 != null)
lastMessageConsumer1.acknowledge();
if(lastMessageConsumer2 != null)
lastMessageConsumer2.acknowledge();
queueConnection.stop();
session1.close();
session2.close();
}
finally
{
try
{
session1.close();
}
catch (Throwable ignored)
{
}
try
{
session2.close();
}
catch (Throwable ignored)
{
}
}
System.out.println("-- runUnackedMultipleSession");
}
/**
* #Description of the Method
*
* @param persistence Description of Parameter
* @exception Exception Description of Exception
*/
public void runUnackedMultipleConnection(final int persistence) throws Exception
{
System.out.println("++runUnackedMultipleConnection");
drainQueue();
final int iterationCount = getIterationCount();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue)context.lookup(TEST_QUEUE);
QueueSender sender = session.createSender(queue);
Message message = session.createBytesMessage();
((BytesMessage)message).writeBytes(PAYLOAD);
for (int i = 0; i < iterationCount; i++)
sender.send(message, persistence, 4, 0);
session.close();
QueueConnectionFactory queueFactory = (QueueConnectionFactory)context.lookup(QUEUE_FACTORY);
QueueConnection queueConnection1 = queueFactory.createQueueConnection();
QueueConnection queueConnection2 = queueFactory.createQueueConnection();
try
{
QueueSession session1 = queueConnection1.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
queue = (Queue)context.lookup(TEST_QUEUE);
QueueReceiver receiver1 = session1.createReceiver(queue);
QueueSession session2 = queueConnection2.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
QueueReceiver receiver2 = session2.createReceiver(queue);
queueConnection1.start();
queueConnection2.start();
int c1=0, c2=0;
Message messageConsumer1=null, messageConsumer2=null;
Message lastMessageConsumer1 = null, lastMessageConsumer2=null;
do
{
messageConsumer1 = receiver1.receive(100);
messageConsumer2 = receiver2.receive(100);
if (messageConsumer1 != null)
{
c1 ++;
lastMessageConsumer1 = messageConsumer1;
}
if (messageConsumer2 != null)
{
c2 ++;
lastMessageConsumer2 = messageConsumer2;
}
System.out.println("messageConsumer1=" + messageConsumer1 + " messageConsumer2=" + messageConsumer2 + " c1=" + c1 + " c2 = " + c2);
}
while (messageConsumer1!=null || messageConsumer2!=null);
if (lastMessageConsumer1!=null) lastMessageConsumer1.acknowledge();
if (lastMessageConsumer2!=null) lastMessageConsumer2.acknowledge();
assertEquals(iterationCount, c1 + c2);
}
finally
{
try{queueConnection1.close();} catch (Throwable ignored){}
try{queueConnection2.close();} catch (Throwable ignored){}
}
System.out.println("--runUnackedMultipleConnection");
}
/**
* #Description of the Method
*
* @param persistence Description of Parameter
* @exception Exception Description of Exception
*/
public void runUnackedTopic(final int persistence) throws Exception
{
drainQueue();
drainTopic();
final int iterationCount = getIterationCount();
final Logger log = getLog();
Thread sendThread =
new Thread()
{
public void run()
{
try
{
TopicSession session = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic)context.lookup(TEST_TOPIC);
TopicPublisher publisher = session.createPublisher(topic);
waitForSynchMessage();
BytesMessage message = session.createBytesMessage();
message.writeBytes(PAYLOAD);
for (int i = 0; i < iterationCount; i++)
{
publisher.publish(message, persistence, 4, 0);
}
session.close();
}
catch (Exception e)
{
log.error("error", e);
}
}
};
TopicSession session = topicConnection.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE);
Topic topic = (Topic)context.lookup(TEST_TOPIC);
TopicSubscriber subscriber = session.createSubscriber(topic);
MyMessageListener listener = new MyMessageListener(iterationCount, log);
queueConnection.start();
sendThread.start();
subscriber.setMessageListener(listener);
topicConnection.start();
sendSynchMessage();
synchronized (listener)
{
if (listener.i < iterationCount)
listener.wait(5000);
assertEquals(iterationCount, listener.i);
}
sendThread.join();
topicConnection.close();
TopicConnectionFactory topicFactory = (TopicConnectionFactory)context.lookup(TOPIC_FACTORY);
topicConnection = topicFactory.createTopicConnection();
queueConnection.stop();
assertTrue("Topic should be empty", drainTopic() == 0);
}
/**
* #Description of the Method
*
* @param persistence Description of Parameter
* @exception Exception Description of Exception
*/
public void runUnackedDurableTopic(final int persistence) throws Exception
{
drainQueue();
drainDurableTopic();
final int iterationCount = getIterationCount();
final Logger log = getLog();
Thread sendThread =
new Thread()
{
public void run()
{
try
{
TopicSession session = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic)context.lookup(TEST_DURABLE_TOPIC);
TopicPublisher publisher = session.createPublisher(topic);
waitForSynchMessage();
BytesMessage message = session.createBytesMessage();
message.writeBytes(PAYLOAD);
for (int i = 0; i < iterationCount; i++)
{
publisher.publish(message, persistence, 4, 0);
}
session.close();
}
catch (Exception e)
{
log.error("error", e);
}
}
};
TopicSession session = topicDurableConnection.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE);
Topic topic = (Topic)context.lookup(TEST_DURABLE_TOPIC);
TopicSubscriber subscriber = session.createDurableSubscriber(topic, "test");
MyMessageListener listener = new MyMessageListener(iterationCount, log);
queueConnection.start();
sendThread.start();
subscriber.setMessageListener(listener);
topicDurableConnection.start();
sendSynchMessage();
synchronized (listener)
{
System.out.println("Hello");
if (listener.i < iterationCount)
{
listener.wait(5000);
}
assertEquals(iterationCount, listener.i);
}
sendThread.join();
topicDurableConnection.close();
TopicConnectionFactory topicFactory = (TopicConnectionFactory)context.lookup("PreconfClientIDConnectionfactory");
topicDurableConnection = topicFactory.createTopicConnection("john", "needle");
queueConnection.stop();
assertTrue("Topic should be full", drainDurableTopic() == iterationCount);
}
/**
* A unit test for JUnit
*
* @exception Exception Description of Exception
*/
public void testUnackedQueue() throws Exception
{
getLog().debug("Starting UnackedQueue test");
runUnackedQueue(DeliveryMode.NON_PERSISTENT);
runUnackedQueue(DeliveryMode.PERSISTENT);
getLog().debug("UnackedQueue passed");
}
/**
* A unit test for JUnit
*
* @exception Exception Description of Exception
*/
public void testUnackedMultipleSession() throws Exception
{
getLog().debug("Starting UnackedMultipleSession test");
runUnackedMultipleSession(DeliveryMode.NON_PERSISTENT);
runUnackedMultipleSession(DeliveryMode.PERSISTENT);
getLog().debug("UnackedMultipleSession passed");
}
/**
* A unit test for JUnit
*
* @exception Exception Description of Exception
*/
public void testUnackedMultipleConnection() throws Exception
{
getLog().debug("Starting UnackedMultipleConnection test");
runUnackedMultipleConnection(DeliveryMode.NON_PERSISTENT);
runUnackedMultipleConnection(DeliveryMode.PERSISTENT);
getLog().debug("UnackedMultipleConnection passed");
}
/**
* A unit test for JUnit
*
* @exception Exception Description of Exception
*/
public void testUnackedTopic() throws Exception
{
getLog().debug("Starting UnackedTopic test");
runUnackedTopic(DeliveryMode.NON_PERSISTENT);
runUnackedTopic(DeliveryMode.PERSISTENT);
getLog().debug("UnackedTopic passed");
}
/**
* A unit test for JUnit
*
* @exception Exception Description of Exception
*/
public void testUnackedDurableTopic() throws Exception
{
getLog().debug("Starting UnackedDurableTopic test");
runUnackedDurableTopic(DeliveryMode.NON_PERSISTENT);
runUnackedDurableTopic(DeliveryMode.PERSISTENT);
getLog().debug("UnackedDurableTopic passed");
}
/**
* A unit test for JUnit
*
* @exception Exception Description of Exception
*/
public void testDummyLast() throws Exception
{
TopicSession session = topicDurableConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
session.unsubscribe("test");
queueConnection.close();
topicConnection.close();
topicDurableConnection.close();
}
/**
* The JUnit setup method
*
* @exception Exception Description of Exception
*/
protected void setUp() throws Exception
{
// call setUp() in superclass
super.setUp() ;
JMSDestinationsUtil.setupBasicDestinations();
if (context == null)
{
context = getInitialContext();
}
QueueConnectionFactory queueFactory = (QueueConnectionFactory)context.lookup(QUEUE_FACTORY);
queueConnection = queueFactory.createQueueConnection();
TopicConnectionFactory topicFactory = (TopicConnectionFactory)context.lookup(TOPIC_FACTORY);
topicConnection = topicFactory.createTopicConnection();
topicFactory = (TopicConnectionFactory) context.lookup("PreconfClientIDConnectionfactory");
topicDurableConnection = topicFactory.createTopicConnection("john", "needle");
}
protected void tearDown() throws Exception
{
if (queueConnection != null)
{
queueConnection.close();
queueConnection = null;
}
if (topicConnection != null)
{
topicConnection.close();
topicConnection = null;
}
if (topicDurableConnection != null)
{
topicDurableConnection.close();
topicDurableConnection = null;
}
JMSDestinationsUtil.destroyDestinations();
super.tearDown();
}
// Emptys out all the messages in a queue
private int drainQueue() throws Exception
{
getLog().debug("Draining Queue");
queueConnection.start();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue)context.lookup(TEST_QUEUE);
QueueReceiver receiver = session.createReceiver(queue);
Message message = receiver.receive(1000);
int c = 0;
while (message != null)
{
message = receiver.receive(1000);
c++;
}
getLog().debug(" Drained " + c + " messages from the queue");
session.close();
queueConnection.stop();
return c;
}
// Emptys out all the messages in a topic
private int drainTopic() throws Exception
{
getLog().debug("Draining Topic");
topicConnection.start();
final TopicSession session = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic)context.lookup(TEST_TOPIC);
TopicSubscriber subscriber = session.createSubscriber(topic);
Message message = subscriber.receive(1000);
int c = 0;
while (message != null)
{
message = subscriber.receive(1000);
c++;
}
getLog().debug(" Drained " + c + " messages from the topic");
session.close();
topicConnection.stop();
return c;
}
// Emptys out all the messages in a durable topic
private int drainDurableTopic() throws Exception
{
getLog().debug("Draining Durable Topic");
topicDurableConnection.start();
final TopicSession session = topicDurableConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic)context.lookup(TEST_DURABLE_TOPIC);
TopicSubscriber subscriber = session.createDurableSubscriber(topic, "test");
Message message = subscriber.receive(1000);
int c = 0;
while (message != null)
{
message = subscriber.receive(1000);
c++;
}
getLog().debug(" Drained " + c + " messages from the durable topic");
session.close();
topicDurableConnection.stop();
return c;
}
private void waitForSynchMessage() throws Exception
{
getLog().debug("Waiting for Synch Message");
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue)context.lookup(TEST_QUEUE);
QueueReceiver receiver = session.createReceiver(queue);
receiver.receive();
session.close();
getLog().debug("Got Synch Message");
}
private void sendSynchMessage() throws Exception
{
getLog().debug("Sending Synch Message");
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue)context.lookup(TEST_QUEUE);
QueueSender sender = session.createSender(queue);
Message message = session.createMessage();
sender.send(message);
session.close();
getLog().debug("Sent Synch Message");
}
public class MyMessageListener
implements MessageListener
{
public int i = 0;
public int iterationCount;
public Logger log;
public MyMessageListener(int iterationCount, Logger log)
{
this.iterationCount = iterationCount;
this.log = log;
}
public void onMessage(Message message)
{
synchronized (this)
{
System.out.println("Listener:: Got message " + i);
i++;
log.debug("Got message " + i);
if (i >= iterationCount)
this.notifyAll();
}
}
}
public int getIterationCount()
{
return 200;
}
}