/*
* 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 java.util.Enumeration;
import javax.jms.DeliveryMode;
import javax.jms.InvalidDestinationException;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueRequestor;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.ServerSession;
import javax.jms.ServerSessionPool;
import javax.jms.Session;
import javax.jms.TemporaryQueue;
import javax.jms.TemporaryTopic;
import javax.jms.TextMessage;
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 javax.naming.InitialContext;
import org.jboss.logging.Logger;
import org.jboss.test.JBossJMSTestCase;
import org.jboss.test.util.jms.JMSDestinationsUtil;
import EDU.oswego.cs.dl.util.concurrent.CountDown;
/**
* Basic jms tests.
*
* @author Scott.Stark@jboss.org
* @version $Revision: 105321 $
*/
public class JBossJMSUnitTest extends JBossJMSTestCase
{
/** The default TopicFactory jndi name */
static String TOPIC_FACTORY = "ConnectionFactory";
/** The default QueueFactory jndi name */
static String QUEUE_FACTORY = "ConnectionFactory";
static String TEST_QUEUE = "queue/testQueue";
static String TEST_TOPIC = "topic/testTopic";
static String TEST_DURABLE_TOPIC = "topic/testDurableTopic";
//JMSProviderAdapter providerAdapter;
static Context context;
static QueueConnection queueConnection;
static TopicConnection topicConnection;
public JBossJMSUnitTest(String name) throws Exception
{
super(name);
}
protected void setUp() throws Exception
{
super.setUp();
JMSDestinationsUtil.setupBasicDestinations();
}
protected void tearDown() throws Exception
{
super.tearDown();
disconnect();
JMSDestinationsUtil.destroyDestinations();
}
// Emptys out all the messages in a queue
protected void drainQueue() throws Exception
{
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) context.lookup(TEST_QUEUE);
QueueReceiver receiver = session.createReceiver(queue);
Message message = receiver.receive(50);
int c = 0;
while (message != null)
{
message = receiver.receive(50);
c++;
}
if (c != 0)
getLog().debug(" Drained " + c + " messages from the queue");
session.close();
}
protected void connect() throws Exception
{
if (context == null)
{
context = new InitialContext();
}
QueueConnectionFactory queueFactory = (QueueConnectionFactory) context.lookup(QUEUE_FACTORY);
queueConnection = queueFactory.createQueueConnection();
TopicConnectionFactory topicFactory = (TopicConnectionFactory) context.lookup(TOPIC_FACTORY);
topicConnection = topicFactory.createTopicConnection();
getLog().debug("Connection to spyderMQ established.");
}
protected void disconnect() throws Exception
{
if (queueConnection != null)
{
queueConnection.close();
queueConnection = null;
}
if (topicConnection != null)
{
topicConnection.close();
topicConnection = null;
}
}
/**
* Test that messages are ordered by message arrival and priority.
* This also tests :
* Using a non-transacted AUTO_ACKNOWLEDGE session
* Using a QueueReceiver
* Using a QueueSender
* Sending PERSITENT and NON_PERSISTENT text messages.
* Using a QueueBrowser
*/
public void testQueueMessageOrder() throws Exception
{
getLog().debug("Starting QueueMessageOrder test");
connect();
queueConnection.start();
drainQueue();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) context.lookup(TEST_QUEUE);
QueueSender sender = session.createSender(queue);
TextMessage message = session.createTextMessage();
message.setText("Normal message");
sender.send(message, DeliveryMode.NON_PERSISTENT, 4, 0);
//sender.send(queue, message, DeliveryMode.NON_PERSISTENT, 4, 0);
message.setText("Persistent message");
sender.send(message, DeliveryMode.PERSISTENT, 4, 0);
//sender.send(queue, message, DeliveryMode.PERSISTENT, 4, 0);
message.setText("High Priority Persistent message");
sender.send(message, DeliveryMode.PERSISTENT, 10, 0);
//sender.send(queue, message, DeliveryMode.PERSISTENT, 10, 0);
//message.setText("Expiring Persistent message");
//sender.send(queue, message, DeliveryMode.NON_PERSISTENT, 4, 1);
QueueBrowser browser = session.createBrowser(queue);
Enumeration i = browser.getEnumeration();
//message = (TextMessage)enum.nextElement();
//if( !message.getText().equals("High Priority Persistent message") )
// throw new Exception("Queue is not prioritizing messages correctly. Unexpected Message:"+message);
getLog().debug(message.getText());
message = (TextMessage) i.nextElement();
//if( !message.getText().equals("Normal message") )
// throw new Exception("Queue is not ordering messages correctly. Unexpected Message:"+message);
getLog().debug(message.getText());
message = (TextMessage) i.nextElement();
//if( !message.getText().equals("Persistent message") )
// throw new Exception("Queue is not ordering messages correctly. Unexpected Message:"+message);
getLog().debug(message.getText());
// if( enum.hasMoreElements() )
// throw new Exception("Queue does not expire messages correctly. Unexpected Message:"+enum.nextElement());
disconnect();
getLog().debug("QueueMessageOrder passed");
}
/**
* Test that a using QueueRequestor works.
* this also tests that :
* temporary queues work.
*/
public void testRequestReplyQueue() throws Exception
{
getLog().debug("Starting RequestReplyQueue test");
connect();
{
queueConnection.start();
drainQueue();
}
Thread serverThread = new Thread()
{
public void run()
{
Logger log = Logger.getLogger(getClass().getName());
try
{
log.debug("Server Thread Started");
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) context.lookup(TEST_QUEUE);
QueueReceiver queueReceiver = session.createReceiver(queue);
boolean done = false;
while (!done)
{
TextMessage message = (TextMessage) queueReceiver.receive();
Queue tempQueue = (Queue) message.getJMSReplyTo();
QueueSender replySender = session.createSender(tempQueue);
TextMessage reply = session.createTextMessage();
reply.setText("Request Processed");
reply.setJMSCorrelationID(message.getJMSMessageID());
replySender.send(reply);
if (message.getText().equals("Quit"))
done = true;
}
session.close();
log.debug("Server Thread Finished");
}
catch (Exception e)
{
log.error("Error", e);
}
}
};
serverThread.start();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) context.lookup(TEST_QUEUE);
QueueRequestor queueRequestor = new QueueRequestor(session, queue);
TextMessage message = session.createTextMessage();
message.setText("Request Test");
for (int i = 0; i < 5; i++)
{
getLog().debug("Making client request #" + i);
TextMessage reply = (TextMessage) queueRequestor.request(message);
String replyID = new String(reply.getJMSCorrelationID());
if (!replyID.equals(message.getJMSMessageID()))
throw new Exception("REQUEST: ERROR: Reply does not match sent message");
}
getLog().debug("Making client request to shut server down.");
message.setText("Quit");
queueRequestor.request(message);
serverThread.join();
disconnect();
getLog().debug("RequestReplyQueue passed");
}
/**
* Test that temporary queues can be deleted.
*/
public void testTemporaryQueueDelete() throws Exception
{
getLog().debug("Starting TemporaryQueueDelete test");
connect();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
TemporaryQueue queue = session.createTemporaryQueue();
queue.delete();
disconnect();
getLog().debug("TemporaryQueueDelete passed");
}
/**
* Test that temporary topics can be deleted.
*/
public void testTemporaryTopicDelete() throws Exception
{
getLog().debug("Starting TemporaryTopicDelete test");
connect();
TopicSession session = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TemporaryTopic topic = session.createTemporaryTopic();
topic.delete();
disconnect();
getLog().debug("TemporaryTopicDelete passed");
}
/**
* Test invalid destination trying to send a message.
*/
public void testInvalidDestinationQueueSend() throws Exception
{
getLog().debug("Starting InvaidDestinationQueueSend test");
connect();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
TemporaryQueue queue = session.createTemporaryQueue();
QueueSender sender = session.createSender(queue);
queue.delete();
TextMessage message = session.createTextMessage("hello");
boolean caught = false;
try
{
sender.send(message);
}
catch (InvalidDestinationException expected)
{
caught = true;
}
disconnect();
assertTrue("Expected an InvalidDestinationException", caught);
getLog().debug("InvaldDestinationQueueSend passed");
}
/**
* Test invalid destination trying to browse a message.
*/
public void testInvalidDestinationQueueBrowse() throws Exception
{
getLog().debug("Starting InvalidDestinationQueueBrowse test");
connect();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
TemporaryQueue queue = session.createTemporaryQueue();
QueueBrowser browser = session.createBrowser(queue);
queue.delete();
boolean caught = false;
try
{
browser.getEnumeration();
}
catch (InvalidDestinationException expected)
{
caught = true;
}
disconnect();
assertTrue("Expected an InvalidDestinationException", caught);
getLog().debug("InvalidDestinationQueueBrowse passed");
}
/**
* Test invalid destination trying to send a message.
*/
public void testInvalidDestinationTopicPublish() throws Exception
{
getLog().debug("Starting InvaidDestinationTopicPublish test");
connect();
TopicSession session = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TemporaryTopic topic = session.createTemporaryTopic();
TopicPublisher publisher = session.createPublisher(topic);
topic.delete();
TextMessage message = session.createTextMessage("hello");
boolean caught = false;
try
{
publisher.publish(message);
}
catch (InvalidDestinationException expected)
{
caught = true;
}
disconnect();
assertTrue("Expected an InvalidDestinationException", caught);
getLog().debug("InvaldDestinationTopicPublish passed");
}
/**
* Test errors trying on topic subscribe.
*/
public void testErrorsTopicSubscribe() throws Exception
{
getLog().debug("Starting InvalidDestinationTopicSubscribe test");
connect();
try
{
TopicSession session = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic) context.lookup(TEST_TOPIC);
TemporaryTopic temp = session.createTemporaryTopic();
boolean caught = false;
try
{
session.createSubscriber(null);
}
catch (InvalidDestinationException expected)
{
caught = true;
}
assertTrue("Expected an InvalidDestinationException for a null topic", caught);
caught = false;
try
{
session.createSubscriber(null, null, true);
}
catch (InvalidDestinationException expected)
{
caught = true;
}
assertTrue("Expected an InvalidDestinationException for a null topic", caught);
caught = false;
try
{
session.createDurableSubscriber(null, "NotUsed");
}
catch (InvalidDestinationException expected)
{
caught = true;
}
assertTrue("Expected an InvalidDestinationException for a null topic", caught);
caught = false;
try
{
session.createDurableSubscriber(temp, "NotUsed");
}
catch (InvalidDestinationException expected)
{
caught = true;
}
assertTrue("Expected an InvalidDestinationException for a temporary topic", caught);
caught = false;
try
{
session.createDurableSubscriber(null, "NotUsed", null, true);
}
catch (InvalidDestinationException expected)
{
caught = true;
}
assertTrue("Expected an InvalidDestinationException for a null topic", caught);
caught = false;
try
{
session.createDurableSubscriber(temp, "NotUsed", null, true);
}
catch (InvalidDestinationException expected)
{
caught = true;
}
assertTrue("Expected an InvalidDestinationException for a temporary topic", caught);
caught = false;
try
{
session.createDurableSubscriber(topic, null);
}
catch (Exception expected)
{
caught = true;
}
assertTrue("Expected a Exception for a null subscription", caught);
caught = false;
try
{
session.createDurableSubscriber(topic, null, null, false);
}
catch (Exception expected)
{
caught = true;
}
assertTrue("Expected a Exception for a null subscription", caught);
caught = false;
try
{
session.createDurableSubscriber(topic, " ");
}
catch (Exception expected)
{
caught = true;
}
assertTrue("Expected a Exception for an empty subscription", caught);
caught = false;
try
{
session.createDurableSubscriber(topic, " ", null, false);
}
catch (Exception expected)
{
caught = true;
}
assertTrue("Expected a Exception for an empty subscription", caught);
}
finally
{
disconnect();
}
getLog().debug("InvalidDestinationTopicSubscriber passed");
}
/**
* Test create queue.
*/
public void testCreateQueue() throws Exception
{
getLog().debug("Starting create queue test");
connect();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue jndiQueue = (Queue) getInitialContext().lookup("queue/testQueue");
Queue createQueue = session.createQueue(jndiQueue.getQueueName());
assertTrue("Failed for " + QUEUE_FACTORY, jndiQueue.equals(createQueue));
getLog().debug("InvalidDestinationTopicSubscriber passed");
}
public void testMessageListener() throws Exception
{
getLog().debug("Starting create queue test");
connect();
queueConnection.start();
drainQueue();
final CountDown counter1 = new CountDown(3);
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) context.lookup(TEST_QUEUE);
QueueReceiver receiver = session.createReceiver(queue);
receiver.setMessageListener(new MessageListener()
{
public void onMessage(Message msg)
{
Logger log = Logger.getLogger(getClass().getName());
log.debug("ML");
try
{
if (msg instanceof TextMessage)
{
log.debug(((TextMessage) msg).getText());
counter1.release();
}
}
catch (Exception e)
{
}
}
});
QueueSender sender = session.createSender(queue);
TextMessage message = session.createTextMessage();
message.setText("Normal message");
sender.send(message, DeliveryMode.NON_PERSISTENT, 4, 0);
//sender.send(queue, message, DeliveryMode.NON_PERSISTENT, 4, 0);
message.setText("Persistent message");
sender.send(message, DeliveryMode.PERSISTENT, 4, 0);
//sender.send(queue, message, DeliveryMode.PERSISTENT, 4, 0);
message.setText("High Priority Persistent message");
sender.send(message, DeliveryMode.PERSISTENT, 10, 0);
//sender.send(queue, message, DeliveryMode.PERSISTENT, 10, 0);
// Wait for the msgs to be received
counter1.acquire();
log.debug("MessageListener1 received the TMs sent");
final CountDown counter2 = new CountDown(2);
receiver.setMessageListener(new MessageListener()
{
public void onMessage(Message msg)
{
Logger log = Logger.getLogger(getClass().getName());
log.debug("ML 2");
try
{
if (msg instanceof TextMessage)
{
log.debug(((TextMessage) msg).getText());
counter2.release();
}
}
catch (Exception e)
{
}
}
});
message.setText("Persistent message");
sender.send(message, DeliveryMode.PERSISTENT, 4, 0);
//sender.send(queue, message, DeliveryMode.PERSISTENT, 4, 0);
message.setText("High Priority Persistent message");
sender.send(message, DeliveryMode.PERSISTENT, 10, 0);
//sender.send(queue, message, DeliveryMode.PERSISTENT, 10, 0);
// Wait for the msgs to be received
counter2.acquire();
log.debug("MessageListener2 received the TMs sent");
receiver.setMessageListener(null);
message.setText("Persistent message");
sender.send(message, DeliveryMode.PERSISTENT, 4, 0);
//sender.send(queue, message, DeliveryMode.PERSISTENT, 4, 0);
message.setText("High Priority Persistent message");
sender.send(message, DeliveryMode.PERSISTENT, 10, 0);
//sender.send(queue, message, DeliveryMode.PERSISTENT, 10, 0);
sender.close();
drainQueue();
disconnect();
getLog().debug("MessageListener test passed");
}
public void testApplicationServerStuff() throws Exception
{
getLog().debug("Starting testing app server stuff");
connect();
Queue testQueue = (Queue) context.lookup(TEST_QUEUE);
final QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
session.setMessageListener(new MessageListener()
{
public void onMessage(Message mess)
{
Logger log = Logger.getLogger(getClass().getName());
log.debug("Processing message");
try
{
if (mess instanceof TextMessage)
log.debug(((TextMessage) mess).getText());
}
catch (Exception e)
{
log.error("Error", e);
}
}
});
QueueSender sender = session.createSender(testQueue);
sender.send(session.createTextMessage("Hi"));
sender.send(session.createTextMessage("There"));
sender.send(session.createTextMessage("Guys"));
queueConnection.createConnectionConsumer(testQueue, null, new ServerSessionPool()
{
public ServerSession getServerSession()
{
Logger.getLogger(getClass().getName()).debug("Getting server session.");
return new ServerSession()
{
public Session getSession()
{
return session;
}
public void start()
{
Logger.getLogger(getClass().getName()).debug("Starting server session.");
session.run();
}
};
}
}, 10);
queueConnection.start();
try
{
Thread.sleep(5 * 1000);
}
catch (Exception e)
{
}
disconnect();
getLog().debug("Testing app server stuff passed");
}
//simply put a few messages on the test queue for next time.
/* public void testPM() throws Exception
{
getLog().debug("Starting testing pm");
connect();
Queue testQueue = (Queue)context.lookup(TEST_QUEUE);
QueueSession session = queueConnection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
QueueSender sender = session.createSender(testQueue);
sender.send(session.createTextMessage("From last time"));
sender.send(session.createTextMessage("From last time"));
sender.send(session.createTextMessage("From last time"));
sender.close();
session.close();
disconnect();
getLog().debug("Testing pm stuff passed");
}
*/
private void drainMessagesForTopic(TopicSubscriber sub) throws JMSException
{
Message msg = sub.receive(50);
int c = 0;
while (msg != null)
{
c++;
if (msg instanceof TextMessage)
getLog().debug(((TextMessage) msg).getText());
msg = sub.receive(50);
}
getLog().debug("Received " + c + " messages from topic.");
}
public void testTopics() throws Exception
{
getLog().debug("Starting Topic test");
connect();
TopicConnectionFactory topicFactory = (TopicConnectionFactory) context.lookup(TOPIC_FACTORY);
topicConnection = topicFactory.createTopicConnection("john", "needle");
topicConnection.start();
//set up some subscribers to the topic
TopicSession session = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic) context.lookup(TEST_TOPIC);
TopicSubscriber sub1 = session.createDurableSubscriber(topic, "sub1");
TopicSubscriber sub2 = session.createSubscriber(topic);
TopicSubscriber sub3 = session.createSubscriber(topic);
//Now a sender
TopicPublisher sender = session.createPublisher(topic);
//send some messages
sender.publish(session.createTextMessage("Message 1"));
sender.publish(session.createTextMessage("Message 2"));
sender.publish(session.createTextMessage("Message 3"));
drainMessagesForTopic(sub1);
drainMessagesForTopic(sub2);
drainMessagesForTopic(sub3);
//close some subscribers
sub1.close();
sub2.close();
//send some more messages
sender.publish(session.createTextMessage("Message 4"));
sender.publish(session.createTextMessage("Message 5"));
sender.publish(session.createTextMessage("Message 6"));
//give time for message 4 to be negatively acked (as it will be cause last receive timed out)
try
{
Thread.sleep(5 * 1000);
}
catch (InterruptedException e)
{
}
drainMessagesForTopic(sub3);
//open subscribers again.
sub1 = session.createDurableSubscriber(topic, "sub1");
sub2 = session.createSubscriber(topic);
//Send a final message
sender.publish(session.createTextMessage("Final message"));
sender.close();
drainMessagesForTopic(sub1);
drainMessagesForTopic(sub2);
drainMessagesForTopic(sub3);
sub1.close();
sub2.close();
sub3.close();
session.unsubscribe("sub1");
topicConnection.stop();
topicConnection.close();
disconnect();
getLog().debug("Topic test passed");
}
/**
* Test to seeif the NoLocal feature of topics works.
* Messages published from the same connection should not
* be received by Subscribers on the same connection.
*/
public void testTopicNoLocal() throws Exception
{
getLog().debug("Starting TopicNoLocal test");
connect();
TopicConnectionFactory topicFactory = (TopicConnectionFactory) context.lookup(TOPIC_FACTORY);
TopicConnection topicConnection1 = topicFactory.createTopicConnection();
topicConnection1.start();
TopicConnection topicConnection2 = topicFactory.createTopicConnection();
topicConnection2.start();
// We don't want local messages on this topic.
TopicSession session1 = topicConnection1.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic) context.lookup(TEST_TOPIC);
TopicSubscriber subscriber1 = session1.createSubscriber(topic, null, true);
TopicPublisher sender1 = session1.createPublisher(topic);
//Now a sender
TopicSession session2 = topicConnection2.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TopicPublisher sender2 = session2.createPublisher(topic);
drainMessagesForTopic(subscriber1);
//send some messages
sender1.publish(session1.createTextMessage("Local Message"));
sender2.publish(session2.createTextMessage("Remote Message"));
// Get the messages, we should get the remote message
// but not the local message
TextMessage msg1 = (TextMessage) subscriber1.receive(2000);
if (msg1 == null)
{
fail("Did not get any messages");
}
else
{
getLog().debug("Got message: " + msg1);
if (msg1.getText().equals("Local Message"))
{
fail("Got a local message");
}
TextMessage msg2 = (TextMessage) subscriber1.receive(2000);
if (msg2 != null)
{
getLog().debug("Got message: " + msg2);
fail("Got an extra message. msg1:" + msg1 + ", msg2:" + msg2);
}
}
topicConnection1.stop();
topicConnection1.close();
topicConnection2.stop();
topicConnection2.close();
disconnect();
getLog().debug("TopicNoLocal test passed");
}
/**
* Test to see whether no local works if a message
* was created somewhere else.
*/
public void testTopicNoLocalBounce() throws Exception
{
getLog().debug("Starting TopicNoLocalBounce test");
connect();
TopicConnectionFactory topicFactory = (TopicConnectionFactory) context.lookup(TOPIC_FACTORY);
TopicConnection topicConnection1 = topicFactory.createTopicConnection();
topicConnection1.start();
TopicConnection topicConnection2 = topicFactory.createTopicConnection();
topicConnection2.start();
// Session 1
TopicSession session1 = topicConnection1.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic) context.lookup(TEST_TOPIC);
TopicSubscriber subscriber1 = session1.createSubscriber(topic, null, true);
TopicPublisher sender1 = session1.createPublisher(topic);
// Session 2
TopicSession session2 = topicConnection2.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TopicSubscriber subscriber2 = session2.createSubscriber(topic, null, true);
TopicPublisher sender2 = session2.createPublisher(topic);
drainMessagesForTopic(subscriber1);
drainMessagesForTopic(subscriber2);
//send the message
sender1.publish(session1.createTextMessage("Message"));
assertTrue("Subscriber1 should not get a message", subscriber1.receiveNoWait() == null);
TextMessage msg = (TextMessage) subscriber2.receive(2000);
assertTrue("Subscriber2 should get a message, got " + msg, msg != null && msg.getText().equals("Message"));
//send it back
sender2.publish(msg);
msg = (TextMessage) subscriber1.receive(2000);
assertTrue("Subscriber1 should get a message, got " + msg, msg != null && msg.getText().equals("Message"));
assertTrue("Subscriber2 should not get a message", subscriber2.receiveNoWait() == null);
topicConnection1.stop();
topicConnection1.close();
topicConnection2.stop();
topicConnection2.close();
disconnect();
getLog().debug("TopicNoLocalBounce test passed");
}
/**
* Test subscribing to a topic with one selector, then changing to another
*/
public void testTopicSelectorChange() throws Exception
{
getLog().debug("Starting TopicSelectorChange test");
getLog().debug("Create topic connection");
TopicConnectionFactory topicFactory = (TopicConnectionFactory) context.lookup(TOPIC_FACTORY);
topicConnection = topicFactory.createTopicConnection("john", "needle");
topicConnection.start();
try
{
getLog().debug("Retrieving Topic");
Topic topic = (Topic) context.lookup(TEST_DURABLE_TOPIC);
getLog().debug("Creating a send session");
TopicSession sendSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TopicPublisher sender = sendSession.createPublisher(topic);
getLog().debug("Clearing the topic");
TopicSession subSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TopicSubscriber subscriber = subSession.createDurableSubscriber(topic, "test");
Message message = subscriber.receive(50);
while (message != null)
message = subscriber.receive(50);
subSession.close();
getLog().debug("Subscribing to topic, looking for Value = 'A'");
subSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
subscriber = subSession.createDurableSubscriber(topic, "test", "Value = 'A'", false);
getLog().debug("Send some messages");
message = sendSession.createTextMessage("Message1");
message.setStringProperty("Value", "A");
sender.publish(message);
message = sendSession.createTextMessage("Message2");
message.setStringProperty("Value", "A");
sender.publish(message);
message = sendSession.createTextMessage("Message3");
message.setStringProperty("Value", "B");
sender.publish(message);
getLog().debug("Retrieving the A messages");
message = subscriber.receive(2000);
assertTrue("Expected message 1", message != null);
assertTrue("Should get an A", message.getStringProperty("Value").equals("A"));
message = subscriber.receive(2000);
assertTrue("Expected message 2", message != null);
assertTrue("Should get a second A", message.getStringProperty("Value").equals("A"));
assertTrue("That should be it for A", subscriber.receive(2000) == null);
getLog().debug("Closing the subscriber without acknowledgement");
subSession.close();
getLog().debug("Subscribing to topic, looking for Value = 'B'");
subSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
subscriber = subSession.createDurableSubscriber(topic, "test", "Value = 'B'", false);
getLog().debug("Retrieving the non-existent B messages");
assertTrue("B should not be there", subscriber.receive(2000) == null);
getLog().debug("Closing the subscriber.");
subSession.close();
getLog().debug("Subscribing to topic, looking for those Value = 'A'");
subSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
subscriber = subSession.createDurableSubscriber(topic, "test", "Value = 'A'", false);
assertTrue("Should not be any A the subscription was changed", subscriber.receive(2000) == null);
subSession.close();
getLog().debug("Subscribing to topic, looking for everything");
subSession = topicConnection.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE);
subscriber = subSession.createDurableSubscriber(topic, "test", null, false);
message = sendSession.createTextMessage("Message4");
message.setStringProperty("Value", "A");
sender.publish(message);
message = subscriber.receive(2000);
assertTrue("Expected message 4", message != null);
assertTrue("Should be an A which we don't acknowledge", message.getStringProperty("Value").equals("A"));
subSession.close();
getLog().debug("Subscribing to topic, looking for the Value = 'A'");
subSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
subscriber = subSession.createDurableSubscriber(topic, "test", "Value = 'A'", false);
assertTrue(
"Should not be any A, the subscription was changed. Even though the old and new selectors match the message",
subscriber.receive(2000) == null);
subSession.close();
getLog().debug("Closing the send session");
sendSession.close();
getLog().debug("Removing the subscription");
subSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
subSession.unsubscribe("test");
}
finally
{
getLog().debug("Closing the connection");
topicConnection.close();
}
getLog().debug("TopicSelectorChange test passed");
}
/**
* Test subscribing to a topic with a null and empty selector
*/
public void testTopicSelectorNullOrEmpty() throws Exception
{
getLog().debug("Starting TopicSelectorNullOrEmpty test");
getLog().debug("Create topic connection");
TopicConnectionFactory topicFactory = (TopicConnectionFactory) context.lookup(TOPIC_FACTORY);
topicConnection = topicFactory.createTopicConnection("john", "needle");
topicConnection.start();
try
{
getLog().debug("Retrieving Topic");
Topic topic = (Topic) context.lookup(TEST_DURABLE_TOPIC);
getLog().debug("Creating a send session");
TopicSession sendSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TopicPublisher sender = sendSession.createPublisher(topic);
getLog().debug("Clearing the topic");
TopicSession subSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TopicSubscriber subscriber = subSession.createDurableSubscriber(topic, "test");
TextMessage message = (TextMessage) subscriber.receive(50);
while (message != null)
message = (TextMessage) subscriber.receive(50);
subSession.close();
getLog().debug("Subscribing to topic, with null selector");
subSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
subscriber = subSession.createDurableSubscriber(topic, "test", null, false);
getLog().debug("Send a message");
message = sendSession.createTextMessage("Message1");
sender.publish(message);
getLog().debug("Retrieving the message");
message = (TextMessage) subscriber.receive(2000);
assertTrue("Expected message 1", message != null);
assertTrue("Should get Message1", message.getText().equals("Message1"));
getLog().debug("Closing the subscriber");
subSession.close();
getLog().debug("Subscribing to topic, with an empty selector");
subSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
subscriber = subSession.createDurableSubscriber(topic, "test", " ", false);
getLog().debug("Send a message");
message = sendSession.createTextMessage("Message2");
sender.publish(message);
getLog().debug("Retrieving the message");
message = (TextMessage) subscriber.receive(2000);
assertTrue("Expected message 2", message != null);
assertTrue("Should get Message2", message.getText().equals("Message2"));
getLog().debug("Closing the subscriber");
getLog().debug("Removing the subscription");
subSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
subSession.unsubscribe("test");
subSession.close();
}
finally
{
getLog().debug("Closing the connection");
topicConnection.close();
}
getLog().debug("TopicSelectorNullOrEmpty test passed");
}
/**
* Test sending/receiving an outdated message
*/
public void testSendReceiveOutdated() throws Exception
{
getLog().debug("Starting SendReceiveOutdated test");
connect();
try
{
queueConnection.start();
drainQueue();
queueConnection.stop();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) context.lookup(TEST_QUEUE);
QueueSender sender = session.createSender(queue);
QueueReceiver receiver = session.createReceiver(queue);
// Send a message that has expired
TextMessage message = session.createTextMessage("Outdated");
sender.send(message, DeliveryMode.PERSISTENT, 4, 1);
Thread.sleep(100);
// Send a message that has not expired
message = session.createTextMessage("OK");
sender.send(message);
// Try to receive the message the not expired message
queueConnection.start();
message = (TextMessage) receiver.receiveNoWait();
assertEquals("OK", message.getText());
// Should be no more
assertTrue("Didn't expect anymore messages", receiver.receiveNoWait() == null);
}
finally
{
disconnect();
}
getLog().debug("SendReceiveOutdated test passed");
}
public void testSendReceiveExpired() throws Exception
{
getLog().debug("Starting testSendReceiveExpired test");
connect();
try
{
queueConnection.start();
drainQueue();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) context.lookup(TEST_QUEUE);
QueueSender sender = session.createSender(queue);
QueueReceiver receiver = session.createReceiver(queue);
// Send a message that expires in 5 seconds
TextMessage message = session.createTextMessage("5 Second Expiration");
sender.send(message, DeliveryMode.PERSISTENT, 4, 5*1000);
// Send a message that has not expired
message = session.createTextMessage("OK");
sender.send(message);
// Sleep 6 seconds
Thread.sleep(6*1000);
// Try to receive the OK message
message = (TextMessage) receiver.receiveNoWait();
assertEquals("OK", message.getText());
// Should be no more
assertTrue("Didn't expect anymore messages", receiver.receiveNoWait() == null);
// Send a message that expires in 10 seconds
message = session.createTextMessage("10 Second Expiration");
sender.send(message, DeliveryMode.PERSISTENT, 4, 10*1000);
// Send a message that has not expired
message = session.createTextMessage("OK");
sender.send(message);
// Sleep 1 seconds
Thread.sleep(1*1000);
// Try to receive the messages
message = (TextMessage) receiver.receiveNoWait();
assertEquals("10 Second Expiration", message.getText());
message = (TextMessage) receiver.receiveNoWait();
assertEquals("OK", message.getText());
// Should be no more
assertTrue("Didn't expect anymore messages", receiver.receiveNoWait() == null);
// Test that JMSExpiration has no affect
message = session.createTextMessage("5 Second Expiration");
message.setJMSExpiration(System.currentTimeMillis() + 5*1000);
sender.send(message, DeliveryMode.PERSISTENT, 4, 0);
// Send a message that has not expired
message = session.createTextMessage("OK");
sender.send(message);
// Sleep 6 seconds
Thread.sleep(6*1000);
// Try to receive the OK message
message = (TextMessage) receiver.receiveNoWait();
assertEquals("5 Second Expiration", message.getText());
message = (TextMessage) receiver.receiveNoWait();
assertEquals("OK", message.getText());
assertTrue("Didn't expect anymore messages", receiver.receiveNoWait() == null);
}
finally
{
disconnect();
}
}
class Synch
{
boolean waiting = false;
String text;
public synchronized void doWait(long timeout) throws InterruptedException
{
waiting = true;
this.wait(timeout);
}
public synchronized void doNotify() throws InterruptedException
{
while (waiting == false)
wait(100);
this.notifyAll();
}
public String getText()
{
return text;
}
public void setText(String text)
{
this.text = text;
}
}
/**
* Test sending/listening an outdated message
*/
public void testSendListenOutdated() throws Exception
{
getLog().debug("Starting SendListenOutdated test");
connect();
try
{
queueConnection.start();
drainQueue();
queueConnection.stop();
QueueSession session = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) context.lookup(TEST_QUEUE);
QueueSender sender = session.createSender(queue);
QueueReceiver receiver = session.createReceiver(queue);
// Send a message that has expired
TextMessage message = session.createTextMessage("Outdated");
sender.send(message, DeliveryMode.PERSISTENT, 4, 1);
Thread.sleep(100);
// Send a message that has not expired
message = session.createTextMessage("OK");
sender.send(message);
// Try to receive the message the not expired message
final Synch synch = new Synch();
MessageListener messagelistener = new MessageListener()
{
public void onMessage(Message message)
{
listenOutdated(message, synch);
}
};
receiver.setMessageListener(messagelistener);
queueConnection.start();
synch.doWait(10000);
assertEquals("OK", synch.getText());
}
finally
{
disconnect();
}
getLog().debug("SendListenOutdated test passed");
}
private void listenOutdated(Message message, Synch synch)
{
try
{
synch.setText(((TextMessage) message).getText());
}
catch (Throwable t)
{
log.error("Error:", t);
}
finally
{
try
{
synch.doNotify();
}
catch (Throwable t)
{
log.error("Error:", t);
}
}
}
}