/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.activemq.artemis.jms.tests; import javax.jms.BytesMessage; import javax.jms.Connection; import javax.jms.DeliveryMode; import javax.jms.InvalidDestinationException; import javax.jms.JMSException; import javax.jms.MapMessage; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.MessageProducer; import javax.jms.ObjectMessage; import javax.jms.Queue; import javax.jms.QueueReceiver; import javax.jms.Session; import javax.jms.StreamMessage; import javax.jms.TextMessage; import javax.jms.Topic; import javax.jms.TopicConnection; import javax.jms.TopicSession; import javax.jms.TopicSubscriber; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import org.apache.activemq.artemis.jms.tests.util.ProxyAssertSupport; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.junit.Assert; import org.junit.Test; public class MessageConsumerTest extends JMSTestCase { @Test public void testReceiveWithClientAckThenCloseSession() throws Exception { Connection conn = null; try { conn = createConnection(); Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sess.createProducer(queue1); final int NUM_MESSAGES = 5; for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sess.createTextMessage("message" + i); prod.send(tm); } Session sess2 = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons = sess2.createConsumer(queue1); conn.start(); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = (TextMessage) cons.receive(500); ProxyAssertSupport.assertNotNull(tm); ProxyAssertSupport.assertEquals("message" + i, tm.getText()); } // Now close the session sess2.close(); } finally { if (conn != null) { conn.close(); } removeAllMessages(queue1.getQueueName(), true); } } @Test public void testRelayMessage() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); final Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); final MessageProducer prod = sess.createProducer(queue2); MessageConsumer cons = sess.createConsumer(queue1); final int numMessages = 100; class MyListener implements MessageListener { boolean failed; int count; @Override public synchronized void onMessage(final Message m) { try { prod.send(m); count++; if (count == numMessages) { notify(); } } catch (JMSException e) { failed = true; } } synchronized void waitForMessages() throws Exception { while (count < numMessages) { this.wait(); } } } MyListener listener = new MyListener(); cons.setMessageListener(listener); final Session sess2 = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod2 = sess2.createProducer(queue1); for (int i = 0; i < numMessages; i++) { prod2.send(sess2.createMessage()); } listener.waitForMessages(); conn.close(); ProxyAssertSupport.assertFalse(listener.failed); } finally { if (conn != null) { conn.close(); } removeAllMessages(queue2.getQueueName(), true); } } /* * If there are two competing consumers on a queue/subscription then if one closes * and has unacknowledged deliveries these should be cancelled but also * delivery should be prompted on the channel, so the other consumer gets the message since * it may be waiting * A real use case for this if there is a consumer on a queue/durable sub, which then crashes * and before the connection resources are cleaned up, a message is sent * The client is quickly brought back. * Eventually the first client will have it's resources cleared up so the delivery gets * cancelled but we need to prompt deliver() so the reconnected client gets it */ @Test public void testRedeliveryToCompetingConsumerOnQueue() throws Exception { Connection conn = null; try { conn = createConnection(); Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSend.createProducer(queue1); conn.start(); Session sessConsume1 = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons1 = sessConsume1.createConsumer(queue1); TextMessage tm = sessSend.createTextMessage(); tm.setText("Your mum"); prod.send(tm); TextMessage tm2 = (TextMessage) cons1.receive(); ProxyAssertSupport.assertNotNull(tm2); ProxyAssertSupport.assertEquals("Your mum", tm2.getText()); // Don't ack // Create another consumer Session sessConsume2 = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons2 = sessConsume2.createConsumer(queue1); // this should cancel message and cause delivery to other consumer sessConsume1.close(); TextMessage tm3 = (TextMessage) cons2.receive(1000); ProxyAssertSupport.assertNotNull(tm3); ProxyAssertSupport.assertEquals("Your mum", tm3.getText()); tm3.acknowledge(); } finally { if (conn != null) { conn.close(); } } } /** * The simplest possible receive() test for a non-persistent message. */ @Test public void testReceive() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); // start consumer connection before the message is submitted consumerConnection.start(); TextMessage tm = producerSession.createTextMessage("someText"); queueProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); queueProducer.send(tm); TextMessage m = (TextMessage) queueConsumer.receive(); ProxyAssertSupport.assertEquals(tm.getText(), m.getText()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testReceivePersistent() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); // start consumer connection before the message is submitted consumerConnection.start(); TextMessage tm = producerSession.createTextMessage("someText"); ProxyAssertSupport.assertEquals(DeliveryMode.PERSISTENT, tm.getJMSDeliveryMode()); queueProducer.send(tm); TextMessage m = (TextMessage) queueConsumer.receive(); ProxyAssertSupport.assertEquals(tm.getText(), m.getText()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } /** * The simplest possible receive(timeout) test. */ @Test public void testReceiveTimeout() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); TextMessage tm = producerSession.createTextMessage("someText"); queueProducer.send(tm); // start consumer connection after the message is submitted consumerConnection.start(); TextMessage m = (TextMessage) queueConsumer.receive(2000); ProxyAssertSupport.assertEquals(tm.getText(), m.getText()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } /** * The simplest possible receiveNoWait() test. */ @Test public void testReceiveNoWait() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); TextMessage tm = producerSession.createTextMessage("someText"); queueProducer.send(tm); // start consumer connection after the message is submitted consumerConnection.start(); // NOTE! There semantics of receiveNoWait do not guarantee the message is available // immediately after the message is sent // It will be available some indeterminate time later. // This is fine and as per spec. // To implement receiveNoWait otherwise would be very costly // Also other messaging systems e.g. Sun, ActiveMQ Artemis implement it this way Thread.sleep(500); TextMessage m = (TextMessage) queueConsumer.receiveNoWait(); ProxyAssertSupport.assertEquals(tm.getText(), m.getText()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } /** * The simplest possible message listener test. */ @Test public void testReceiveOnListener() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); TextMessage tm = producerSession.createTextMessage("someText"); queueProducer.send(tm); MessageListenerImpl l = new MessageListenerImpl(); queueConsumer.setMessageListener(l); // start consumer connection after the message is submitted consumerConnection.start(); // wait for the listener to receive the message l.waitForMessages(); TextMessage m = (TextMessage) l.getNextMessage(); ProxyAssertSupport.assertEquals(tm.getText(), m.getText()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } // // Invalid destination test // @Test public void testCreateConsumerOnNonExistentTopic() throws Exception { Connection pconn = null; try { pconn = createConnection(); Session ps = pconn.createSession(false, Session.AUTO_ACKNOWLEDGE); try { ps.createConsumer(new Topic() { @Override public String getTopicName() throws JMSException { return "NoSuchTopic"; } }); ProxyAssertSupport.fail("should throw exception"); } catch (InvalidDestinationException e) { // OK } } finally { if (pconn != null) { pconn.close(); } } } @Test public void testCreateConsumerOnNonExistentQueue() throws Exception { Connection pconn = null; try { pconn = createConnection(); Session ps = pconn.createSession(false, Session.AUTO_ACKNOWLEDGE); try { ps.createConsumer(new Queue() { @Override public String getQueueName() throws JMSException { return "NoSuchQueue"; } }); ProxyAssertSupport.fail("should throw exception"); } catch (InvalidDestinationException e) { // OK } } finally { if (pconn != null) { pconn.close(); } } } // // closed consumer tests // /* Test that an ack can be sent after the consumer that received the message has been closed. * Acks are scoped per session. */ @Test public void testAckAfterConsumerClosed() throws Exception { Connection connSend = null; Connection connReceive = null; try { connSend = createConnection(); connSend.start(); Session sessSend = connSend.createSession(true, Session.SESSION_TRANSACTED); MessageProducer prod = sessSend.createProducer(queue1); prod.setDeliveryMode(DeliveryMode.PERSISTENT); Message m = sessSend.createTextMessage("hello"); prod.send(m); sessSend.commit(); connReceive = createConnection(); connReceive.start(); Session sessReceive = connReceive.createSession(true, Session.SESSION_TRANSACTED); MessageConsumer cons = sessReceive.createConsumer(queue1); TextMessage m2 = (TextMessage) cons.receive(1500); ProxyAssertSupport.assertNotNull(m2); ProxyAssertSupport.assertEquals("hello", m2.getText()); // It is legal to close the consumer before committing the tx which is when // the acks are sent cons.close(); sessReceive.commit(); connReceive.close(); log.trace("Done test"); } finally { if (connSend != null) { connSend.close(); } if (connReceive != null) { connReceive.close(); } } } @Test public void testClientAcknowledgmentOnClosedConsumer() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); TextMessage tm = producerSession.createTextMessage(); tm.setText("One"); queueProducer.send(tm); consumerConnection.start(); TextMessage m = (TextMessage) queueConsumer.receive(1500); ProxyAssertSupport.assertEquals(m.getText(), "One"); queueConsumer.close(); m.acknowledge(); try { queueConsumer.receive(2000); ProxyAssertSupport.fail("should throw exception"); } catch (javax.jms.IllegalStateException e) { // OK } } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testSendMessageAndCloseConsumer1() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); Message m = producerSession.createMessage(); queueProducer.send(m); queueConsumer.close(); // since no message was received, we expect the message back in the queue queueConsumer = consumerSession.createConsumer(queue1); consumerConnection.start(); Message r = queueConsumer.receive(2000); ProxyAssertSupport.assertEquals(m.getJMSMessageID(), r.getJMSMessageID()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } removeAllMessages(queue1.getQueueName(), true); } /** * Basically the same test as before, with more than one message and a slightly different * way of checking the messages are back in the queue. */ @Test public void testSendMessageAndCloseConsumer2() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(true, 0); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); TextMessage tm = producerSession.createTextMessage(); tm.setText("One"); queueProducer.send(tm); tm.setText("Two"); queueProducer.send(tm); consumerConnection.start(); TextMessage m = (TextMessage) queueConsumer.receive(1500); ProxyAssertSupport.assertEquals("One", m.getText()); queueConsumer.close(); consumerSession.commit(); // I expect that "Two" is still in the queue MessageConsumer queueConsumer2 = consumerSession.createConsumer(queue1); m = (TextMessage) queueConsumer2.receive(1500); ProxyAssertSupport.assertNotNull(m); ProxyAssertSupport.assertEquals("Two", m.getText()); consumerSession.commit(); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testRedel0() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); MessageProducer prod = sess.createProducer(queue1); TextMessage tm1 = sess.createTextMessage("a"); TextMessage tm2 = sess.createTextMessage("b"); TextMessage tm3 = sess.createTextMessage("c"); prod.send(tm1); prod.send(tm2); prod.send(tm3); sess.commit(); MessageConsumer cons1 = sess.createConsumer(queue1); TextMessage rm1 = (TextMessage) cons1.receive(); ProxyAssertSupport.assertNotNull(rm1); ProxyAssertSupport.assertEquals("a", rm1.getText()); cons1.close(); MessageConsumer cons2 = sess.createConsumer(queue1); sess.commit(); TextMessage rm2 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm2); ProxyAssertSupport.assertEquals("b", rm2.getText()); TextMessage rm3 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm3); ProxyAssertSupport.assertEquals("c", rm3.getText()); sess.commit(); } finally { if (conn != null) { conn.close(); } checkEmpty(queue1); removeAllMessages(queue1.getQueueName(), true); } } @Test public void testRedel1() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); MessageProducer prod = sess.createProducer(queue1); TextMessage tm1 = sess.createTextMessage("hello1"); TextMessage tm2 = sess.createTextMessage("hello2"); TextMessage tm3 = sess.createTextMessage("hello3"); prod.send(tm1); prod.send(tm2); prod.send(tm3); sess.commit(); MessageConsumer cons1 = sess.createConsumer(queue1); TextMessage rm1 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertNotNull(rm1); ProxyAssertSupport.assertEquals("hello1", rm1.getText()); cons1.close(); MessageConsumer cons2 = sess.createConsumer(queue1); sess.commit(); TextMessage rm2 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm2); ProxyAssertSupport.assertEquals("hello2", rm2.getText()); TextMessage rm3 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm3); ProxyAssertSupport.assertEquals("hello3", rm3.getText()); sess.commit(); } finally { if (conn != null) { conn.close(); } checkEmpty(queue1); removeAllMessages(queue1.getQueueName(), true); } } @Test public void testRedel2() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); MessageProducer prod = sess.createProducer(queue1); TextMessage tm1 = sess.createTextMessage("hello1-a"); TextMessage tm2 = sess.createTextMessage("hello2-a"); TextMessage tm3 = sess.createTextMessage("hello3-a"); prod.send(tm1); prod.send(tm2); prod.send(tm3); sess.commit(); MessageConsumer cons1 = sess.createConsumer(queue1); TextMessage rm1 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertNotNull(rm1); ProxyAssertSupport.assertEquals("hello1-a", rm1.getText()); cons1.close(); sess.commit(); MessageConsumer cons2 = sess.createConsumer(queue1); TextMessage rm2 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm2); ProxyAssertSupport.assertEquals("hello2-a", rm2.getText()); TextMessage rm3 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm3); ProxyAssertSupport.assertEquals("hello3-a", rm3.getText()); sess.commit(); } finally { if (conn != null) { conn.close(); } checkEmpty(queue1); removeAllMessages(queue1.getQueueName(), true); } } @Test public void testRedel3() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); MessageProducer prod = sess.createProducer(queue1); TextMessage tm1 = sess.createTextMessage("hello1"); log.trace(tm1.getJMSMessageID()); TextMessage tm2 = sess.createTextMessage("hello2"); TextMessage tm3 = sess.createTextMessage("hello3"); prod.send(tm1); prod.send(tm2); prod.send(tm3); sess.commit(); MessageConsumer cons1 = sess.createConsumer(queue1); TextMessage rm1 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertNotNull(rm1); ProxyAssertSupport.assertEquals("hello1", rm1.getText()); log.trace(rm1.getJMSMessageID()); log.trace("rolling back"); // rollback should cause redelivery of messages not acked sess.rollback(); log.trace("rolled back"); TextMessage rm2 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertEquals("hello1", rm2.getText()); log.trace(rm1.getJMSMessageID()); TextMessage rm3 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertEquals("hello2", rm3.getText()); TextMessage rm4 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertEquals("hello3", rm4.getText()); sess.commit(); } finally { if (conn != null) { conn.close(); } // This last step is important - there shouldn't be any more messages to receive checkEmpty(queue1); removeAllMessages(queue1.getQueueName(), true); } } @Test public void testRedel4() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); MessageProducer prod = sess.createProducer(queue1); TextMessage tm1 = sess.createTextMessage("hello1"); TextMessage tm2 = sess.createTextMessage("hello2"); TextMessage tm3 = sess.createTextMessage("hello3"); prod.send(tm1); prod.send(tm2); prod.send(tm3); sess.commit(); MessageConsumer cons1 = sess.createConsumer(queue1); TextMessage rm1 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertNotNull(rm1); ProxyAssertSupport.assertEquals("hello1", rm1.getText()); cons1.close(); // rollback should cause redelivery of messages // in this case redelivery occurs to a different receiver sess.rollback(); MessageConsumer cons2 = sess.createConsumer(queue1); TextMessage rm2 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm2); ProxyAssertSupport.assertEquals("hello1", rm2.getText()); TextMessage rm3 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm3); ProxyAssertSupport.assertEquals("hello2", rm3.getText()); TextMessage rm4 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm4); ProxyAssertSupport.assertEquals("hello3", rm4.getText()); sess.commit(); } finally { if (conn != null) { conn.close(); } // This last step is important - there shouldn't be any more messages to receive checkEmpty(queue1); removeAllMessages(queue1.getQueueName(), true); } } @Test public void testRedel5() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer prod = sess.createProducer(queue1); TextMessage tm1 = sess.createTextMessage("hello1"); TextMessage tm2 = sess.createTextMessage("hello2"); TextMessage tm3 = sess.createTextMessage("hello3"); prod.send(tm1); prod.send(tm2); prod.send(tm3); MessageConsumer cons1 = sess.createConsumer(queue1); TextMessage rm1 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertNotNull(rm1); ProxyAssertSupport.assertEquals("hello1", rm1.getText()); // redeliver sess.recover(); TextMessage rm2 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertNotNull(rm2); ProxyAssertSupport.assertEquals("hello1", rm2.getText()); TextMessage rm3 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertNotNull(rm3); ProxyAssertSupport.assertEquals("hello2", rm3.getText()); TextMessage rm4 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertNotNull(rm4); ProxyAssertSupport.assertEquals("hello3", rm4.getText()); rm4.acknowledge(); } finally { if (conn != null) { conn.close(); } // This last step is important - there shouldn't be any more messages to receive checkEmpty(queue1); removeAllMessages(queue1.getQueueName(), true); } } @Test public void testRedel6() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer prod = sess.createProducer(queue1); TextMessage tm1 = sess.createTextMessage("hello1"); TextMessage tm2 = sess.createTextMessage("hello2"); TextMessage tm3 = sess.createTextMessage("hello3"); prod.send(tm1); prod.send(tm2); prod.send(tm3); MessageConsumer cons1 = sess.createConsumer(queue1); TextMessage rm1 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertNotNull(rm1); ProxyAssertSupport.assertEquals("hello1", rm1.getText()); cons1.close(); log.debug("sess.recover()"); // redeliver sess.recover(); MessageConsumer cons2 = sess.createConsumer(queue1); log.debug("receiving ..."); TextMessage rm2 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm2); ProxyAssertSupport.assertEquals("hello1", rm2.getText()); TextMessage rm3 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm3); ProxyAssertSupport.assertEquals("hello2", rm3.getText()); TextMessage rm4 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(rm4); ProxyAssertSupport.assertEquals("hello3", rm4.getText()); rm4.acknowledge(); } finally { if (conn != null) { conn.close(); } // This last step is important - there shouldn't be any more messages to receive checkEmpty(queue1); removeAllMessages(queue1.getQueueName(), true); } } /** * http://www.jboss.org/index.html?module=bb&op=viewtopic&t=71350 */ @Test public void testRedel7() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer prod = sess.createProducer(queue1); TextMessage tm1 = sess.createTextMessage("1"); TextMessage tm2 = sess.createTextMessage("2"); TextMessage tm3 = sess.createTextMessage("3"); prod.send(tm1); prod.send(tm2); prod.send(tm3); MessageConsumer cons1 = sess.createConsumer(queue1); TextMessage r1 = (TextMessage) cons1.receive(); ProxyAssertSupport.assertEquals(tm1.getText(), r1.getText()); cons1.close(); MessageConsumer cons2 = sess.createConsumer(queue1); TextMessage r2 = (TextMessage) cons2.receive(); ProxyAssertSupport.assertEquals(tm2.getText(), r2.getText()); TextMessage r3 = (TextMessage) cons2.receive(); ProxyAssertSupport.assertEquals(tm3.getText(), r3.getText()); r1.acknowledge(); r2.acknowledge(); r3.acknowledge(); } finally { if (conn != null) { conn.close(); } removeAllMessages(queue1.getQueueName(), true); } } /** * http://www.jboss.org/index.html?module=bb&op=viewtopic&t=71350 */ @Test public void testRedel8() throws Exception { Connection conn = null; try { conn = createConnection(); Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sess.createProducer(queue1); // Send 3 messages prod.send(sess.createTextMessage("1")); prod.send(sess.createTextMessage("2")); prod.send(sess.createTextMessage("3")); conn.start(); MessageConsumer cons1 = sess.createConsumer(queue1); cons1.close(); MessageConsumer cons2 = sess.createConsumer(queue1); Message r1 = cons2.receive(); Message r2 = cons2.receive(); Message r3 = cons2.receive(); // Messages should be received? ProxyAssertSupport.assertNotNull(r1); ProxyAssertSupport.assertNotNull(r2); ProxyAssertSupport.assertNotNull(r3); } finally { if (conn != null) { conn.close(); } } } @Test public void testSendAndReceivePersistentDifferentConnections() throws Exception { Connection connSend = null; Connection connReceive = null; try { connSend = createConnection(); connSend.start(); Session sessSend = connSend.createSession(true, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSend.createProducer(null); prod.setDeliveryMode(DeliveryMode.PERSISTENT); Message m = sessSend.createTextMessage("hello"); prod.send(queue1, m); sessSend.commit(); connReceive = createConnection(); connReceive.start(); Session sessReceive = connReceive.createSession(true, Session.SESSION_TRANSACTED); MessageConsumer cons = sessReceive.createConsumer(queue1); TextMessage m2 = (TextMessage) cons.receive(1500); ProxyAssertSupport.assertNotNull(m2); ProxyAssertSupport.assertEquals("hello", m2.getText()); sessReceive.commit(); cons.close(); connReceive.close(); connReceive = createConnection(); connReceive.start(); sessReceive = connReceive.createSession(true, Session.SESSION_TRANSACTED); cons = sessReceive.createConsumer(queue1); } finally { if (connSend != null) { connSend.close(); } if (connReceive != null) { connReceive.close(); } checkEmpty(queue1); } } @Test public void testMultipleConcurrentConsumers() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); consumerConnection.start(); Session sess1 = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess2 = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess3 = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer cons1 = sess1.createConsumer(ActiveMQServerTestCase.topic1); MessageConsumer cons2 = sess2.createConsumer(ActiveMQServerTestCase.topic1); MessageConsumer cons3 = sess3.createConsumer(ActiveMQServerTestCase.topic1); final int NUM_MESSAGES = 10; class Receiver implements Runnable { Receiver(final MessageConsumer c1) { cons = c1; } MessageConsumer cons; boolean failed; @Override public void run() { try { for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage m = (TextMessage) cons.receive(5000); if (m == null) { log.error("Didn't receive all the messages"); failed = true; break; } if (!m.getText().equals("testing")) { failed = true; } } } catch (Exception e) { log.error("Failed in receiving messages", e); failed = true; } } } Receiver rec1 = new Receiver(cons1); Receiver rec2 = new Receiver(cons2); Receiver rec3 = new Receiver(cons3); Thread t1 = new Thread(rec1); Thread t2 = new Thread(rec2); Thread t3 = new Thread(rec3); log.trace("Starting threads"); t1.start(); t2.start(); t3.start(); log.trace("Sending messages to topic"); producerConnection.start(); Session prodSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = prodSession.createProducer(ActiveMQServerTestCase.topic1); prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT); for (int i = 0; i < NUM_MESSAGES; i++) { Message m = prodSession.createTextMessage("testing"); prod.send(m); log.trace("Sent message to topic"); } t1.join(15000); t2.join(15000); t3.join(15000); sess1.close(); sess2.close(); sess3.close(); prodSession.close(); ProxyAssertSupport.assertTrue(!rec1.failed); ProxyAssertSupport.assertTrue(!rec2.failed); ProxyAssertSupport.assertTrue(!rec3.failed); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testGetSelector() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); String selector = "JMSType = 'something'"; MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1, selector); ProxyAssertSupport.assertEquals(selector, topicConsumer.getMessageSelector()); } finally { if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testGetSelectorOnClosedConsumer() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); topicConsumer.close(); try { topicConsumer.getMessageSelector(); Assert.fail("must throw a JMS IllegalStateException"); } catch (javax.jms.IllegalStateException e) { // OK } } finally { if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testGetNoLocalOnClosedConsumer() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); TopicConnection tc = (TopicConnection) consumerConnection; TopicSession consumerSession = tc.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); TopicSubscriber topicConsumer = consumerSession.createSubscriber(ActiveMQServerTestCase.topic1); topicConsumer.close(); try { topicConsumer.getNoLocal(); Assert.fail("must throw a JMS IllegalStateException"); } catch (javax.jms.IllegalStateException e) { // OK } } finally { if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testGetTopic() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); Topic t = ((TopicSubscriber) topicConsumer).getTopic(); ProxyAssertSupport.assertEquals(ActiveMQServerTestCase.topic1, t); } finally { if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testGetTopicOnClosedConsumer() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); topicConsumer.close(); try { ((TopicSubscriber) topicConsumer).getTopic(); Assert.fail("must throw a JMS IllegalStateException"); } catch (javax.jms.IllegalStateException e) { // OK } } finally { if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testGetQueue() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); Queue q = ((QueueReceiver) queueConsumer).getQueue(); ProxyAssertSupport.assertEquals(queue1, q); } finally { if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testGetQueueOnClosedConsumer() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); queueConsumer.close(); try { ((QueueReceiver) queueConsumer).getQueue(); Assert.fail("must throw a JMS IllegalStateException"); } catch (javax.jms.IllegalStateException e) { // OK } } finally { if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testReceiveOnTopicTimeoutNoMessage() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); Message m = topicConsumer.receive(1000); ProxyAssertSupport.assertNull(m); } finally { if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testReceiveOnTopicConnectionStopped() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); final MessageProducer topicProducer = producerSession.createProducer(ActiveMQServerTestCase.topic1); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); final Message m = producerSession.createMessage(); new Thread(new Runnable() { @Override public void run() { try { // this is needed to make sure the main thread has enough time to block Thread.sleep(1000); topicProducer.send(m); } catch (Exception e) { log.error(e); } } }, "Producer").start(); ProxyAssertSupport.assertNull(topicConsumer.receive(1500)); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testReceiveOnTopicTimeout() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); final MessageProducer topicProducer = producerSession.createProducer(ActiveMQServerTestCase.topic1); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); consumerConnection.start(); final Message m1 = producerSession.createMessage(); new Thread(new Runnable() { @Override public void run() { try { // this is needed to make sure the main thread has enough time to block Thread.sleep(1000); topicProducer.send(m1); } catch (Exception e) { log.error(e); } } }, "Producer").start(); Message m2 = topicConsumer.receive(1500); ProxyAssertSupport.assertEquals(m1.getJMSMessageID(), m2.getJMSMessageID()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testReceiveOnTopic() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); final MessageProducer topicProducer = producerSession.createProducer(ActiveMQServerTestCase.topic1); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); consumerConnection.start(); final Message m1 = producerSession.createMessage(); new Thread(new Runnable() { @Override public void run() { try { // this is needed to make sure the main thread has enough time to block Thread.sleep(1000); topicProducer.send(m1); } catch (Exception e) { log.error(e); } } }, "Producer").start(); Message m2 = topicConsumer.receive(3000); ProxyAssertSupport.assertEquals(m1.getJMSMessageID(), m2.getJMSMessageID()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testReceiveNoWaitOnTopic() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); final MessageProducer topicProducer = producerSession.createProducer(ActiveMQServerTestCase.topic1); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); consumerConnection.start(); Message m = topicConsumer.receiveNoWait(); ProxyAssertSupport.assertNull(m); Message m1 = producerSession.createMessage(); topicProducer.send(m1); // block this thread for a while to allow ServerConsumerDelegate's delivery thread to kick in Thread.sleep(500); m = topicConsumer.receiveNoWait(); ProxyAssertSupport.assertEquals(m1.getJMSMessageID(), m.getJMSMessageID()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } /** * The test sends a burst of messages and verifies if the consumer receives all of them. */ @Test public void testStressReceiveOnQueue() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); final Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); final MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); final int count = 100; consumerConnection.start(); new Thread(new Runnable() { @Override public void run() { try { for (int i = 0; i < count; i++) { Message m = producerSession.createMessage(); queueProducer.send(m); } } catch (Exception e) { log.error(e); } } }, "ProducerTestThread").start(); for (int i = 0; i < count; i++) { Message m = queueConsumer.receive(1500); ProxyAssertSupport.assertNotNull(m); } } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } checkEmpty(queue1); } } /** * The test sends a burst of messages and verifies if the consumer receives all of them. */ @Test public void testStressReceiveOnTopic() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); final Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); final MessageProducer topicProducer = producerSession.createProducer(ActiveMQServerTestCase.topic1); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); final int count = 1000; consumerConnection.start(); new Thread(new Runnable() { @Override public void run() { try { // this is needed to make sure the main thread has enough time to block Thread.sleep(1000); for (int i = 0; i < count; i++) { Message m = producerSession.createMessage(); topicProducer.send(m); } } catch (Exception e) { log.error(e); } } }, "ProducerTestThread").start(); for (int i = 0; i < count; i++) { Message m = topicConsumer.receive(10000); ProxyAssertSupport.assertNotNull(m); } checkEmpty(ActiveMQServerTestCase.topic1); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testReceiveOnClose() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); final MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); consumerConnection.start(); final CountDownLatch latch = new CountDownLatch(1); Thread closerThread = new Thread(new Runnable() { @Override public void run() { try { // this is needed to make sure the main thread has enough time to block Thread.sleep(1000); topicConsumer.close(); } catch (Exception e) { log.error(e); } finally { latch.countDown(); } } }, "closing thread"); closerThread.start(); ProxyAssertSupport.assertNull(topicConsumer.receive(1500)); // wait for the closing thread to finish boolean closed = latch.await(5000, TimeUnit.MILLISECONDS); ProxyAssertSupport.assertTrue(closed); } finally { if (consumerConnection != null) { consumerConnection.close(); } } } /** * to be used by testTimeoutReceiveOnClose */ private class ThreadCloser extends Thread { final Object waitMonitor; long timeToSleep; MessageConsumer topicConsumer; final AtomicBoolean running; private ThreadCloser(final AtomicBoolean running, final Object waitMonitor, final long timeToSleep, final MessageConsumer topicConsumer) { this.running = running; this.waitMonitor = waitMonitor; this.timeToSleep = timeToSleep; this.topicConsumer = topicConsumer; } @Override public void run() { try { synchronized (waitMonitor) { while (running.get()) { waitMonitor.wait(); } } Thread.sleep(timeToSleep); topicConsumer.close(); } catch (Exception e) { log.error(e); e.printStackTrace(); } } } /** * to be used by testTimeoutReceiveOnClose */ private class ThreadReceiver extends Thread { long timeToWait; final Object waitMonitor; long t1; long t2; Object receivedObject; MessageConsumer topicConsumer; final AtomicBoolean running; private ThreadReceiver(final AtomicBoolean running, final Object waitMonitor, final long timeToWait, final MessageConsumer topicConsumer) { this.running = running; this.waitMonitor = waitMonitor; this.timeToWait = timeToWait; this.topicConsumer = topicConsumer; } @Override public void run() { try { synchronized (waitMonitor) { while (running.get()) { waitMonitor.wait(); } } t1 = System.currentTimeMillis(); receivedObject = topicConsumer.receive(timeToWait); t2 = System.currentTimeMillis(); } catch (Exception e) { log.error(e); e.printStackTrace(); } } } @Test public void testTimeoutReceiveOnClose() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); // This is a really weird test - the received object is always going to be null since no message is sent!! ActiveMQServerTestCase.forceGC(); // / If A GC need to be executed, it' s better to be executed now if (log.isTraceEnabled()) { log.trace("testTimeoutReceiveOnClose"); } Object monitor = new Object(); ThreadCloser closer = null; ThreadReceiver receiver = null; AtomicBoolean running = new AtomicBoolean(true); closer = new ThreadCloser(running, monitor, 1000, topicConsumer); receiver = new ThreadReceiver(running, monitor, 2000, topicConsumer); closer.start(); receiver.start(); Thread.sleep(2000); synchronized (monitor) { running.set(false); monitor.notifyAll(); } closer.join(); receiver.join(); ProxyAssertSupport.assertNull(receiver.receivedObject); // We need to make sure the ProxyAssertSupport.assertTrue("Receive was supposed to receive a notification before 2 seconds", receiver.t2 - receiver.t1 <= 1500); } finally { if (consumerConnection != null) { consumerConnection.close(); } } } // // MessageListener tests // @Test public void testMessageListenerOnTopic() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer topicProducer = producerSession.createProducer(ActiveMQServerTestCase.topic1); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); MessageListenerImpl l = new MessageListenerImpl(); topicConsumer.setMessageListener(l); consumerConnection.start(); Message m1 = producerSession.createMessage(); topicProducer.send(m1); // block the current thread until the listener gets something; this is to avoid closing // the connection too early l.waitForMessages(); ProxyAssertSupport.assertEquals(m1.getJMSMessageID(), l.getNextMessage().getJMSMessageID()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testMessageListenerOnTopicMultipleMessages() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer topicProducer = producerSession.createProducer(ActiveMQServerTestCase.topic1); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); log.debug("testMessageListenerOnTopicMultipleMessages"); int NUM_MESSAGES = 10; MessageListenerImpl l = new MessageListenerImpl(NUM_MESSAGES); topicConsumer.setMessageListener(l); consumerConnection.start(); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage m = producerSession.createTextMessage("body" + i); topicProducer.send(m); } l.waitForMessages(); int counter = 0; for (Iterator<Message> i = l.getMessages().iterator(); i.hasNext(); counter++) { TextMessage m = (TextMessage) i.next(); ProxyAssertSupport.assertEquals("body" + counter, m.getText()); } log.debug("testMessageListenerOnTopicMultipleMessages done"); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testMessageListenerOnQueueMultipleMessages() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); log.debug("testMessageListenerOnQueueMultipleMessages"); int NUM_MESSAGES = 10; MessageListenerImpl l = new MessageListenerImpl(NUM_MESSAGES); queueConsumer.setMessageListener(l); consumerConnection.start(); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage m = producerSession.createTextMessage("body" + i); queueProducer.send(m); } l.waitForMessages(); int counter = 0; for (Iterator<Message> i = l.getMessages().iterator(); i.hasNext(); counter++) { TextMessage m = (TextMessage) i.next(); ProxyAssertSupport.assertEquals("body" + counter, m.getText()); } log.debug("testMessageListenerOnTopicMultipleMessages done"); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testSetMessageListenerTwice() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer topicProducer = producerSession.createProducer(ActiveMQServerTestCase.topic1); MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); MessageListenerImpl listener1 = new MessageListenerImpl(); topicConsumer.setMessageListener(listener1); MessageListenerImpl listener2 = new MessageListenerImpl(); topicConsumer.setMessageListener(listener2); consumerConnection.start(); Message m1 = producerSession.createMessage(); topicProducer.send(m1); // block the current thread until the listener gets something; this is to avoid closing // connection too early listener2.waitForMessages(); ProxyAssertSupport.assertEquals(m1.getJMSMessageID(), listener2.getNextMessage().getJMSMessageID()); ProxyAssertSupport.assertEquals(0, listener1.size()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testSetMessageListenerWhileReceiving() throws Exception { Connection consumerConnection = null; try { consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); final MessageConsumer topicConsumer = consumerSession.createConsumer(ActiveMQServerTestCase.topic1); consumerConnection.start(); Thread worker1 = new Thread(new Runnable() { @Override public void run() { try { topicConsumer.receive(3000); } catch (Exception e) { e.printStackTrace(); } } }, "Receiver"); worker1.start(); Thread.sleep(1000); try { topicConsumer.setMessageListener(new MessageListenerImpl()); ProxyAssertSupport.fail("should have thrown JMSException"); } catch (JMSException e) { // ok log.trace(e.getMessage()); } } finally { if (consumerConnection != null) { consumerConnection.close(); } } } // This is commented out until http:// jira.jboss.com/jira/browse/JBMESSAGING-983 is complete @Test public void testStopConnectionDuringOnMessage() throws Exception { if (log.isTraceEnabled()) { log.trace("testStopConnectionWhileOnMessageIsExecuting"); } final AtomicInteger messagesReceived = new AtomicInteger(0); MessageListener myListener = new MessageListener() { @Override public void onMessage(final Message message) { messagesReceived.incrementAndGet(); try { Thread.sleep(100L); } catch (InterruptedException e) { // Ignore } } }; Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); queueConsumer.setMessageListener(myListener); log.trace("Starting consumer connection"); consumerConnection.start(); final int MESSAGE_COUNT = 100; log.trace("Sending the first batch of messages"); for (int i = 0; i < MESSAGE_COUNT / 2; i++) { queueProducer.send(producerSession.createTextMessage("Message #" + Integer.toString(i))); } Thread.sleep(500L); log.trace("Stopping consumer connection"); consumerConnection.stop(); int countAfterStop = messagesReceived.get(); ProxyAssertSupport.assertTrue("Should have received some messages before stopping", countAfterStop > 0); log.trace("Sending the second batch of messages"); for (int i = MESSAGE_COUNT / 2; i < MESSAGE_COUNT; i++) { queueProducer.send(producerSession.createTextMessage("Message #" + Integer.toString(i))); } log.trace("Sleeping a bit to check that no messages are received"); Thread.sleep(2000); ProxyAssertSupport.assertEquals("Should not receive any messages after the connection has been stopped", countAfterStop, messagesReceived.get()); log.trace("Restarting consumer connection"); consumerConnection.start(); log.trace("Sleeping to allow remaining messages to arrive"); Thread.sleep(15000); ProxyAssertSupport.assertEquals("Should have received all messages after restarting", MESSAGE_COUNT, messagesReceived.get()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } removeAllMessages(queue1.getQueueName(), true); } } // Test that stop doesn't in any way break subsequent close @Test public void testCloseAfterStop() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); MessageListener myListener = new MessageListener() { @Override public void onMessage(final Message message) { try { Thread.sleep(1); } catch (InterruptedException e) { // Ignore } } }; queueConsumer.setMessageListener(myListener); consumerConnection.start(); for (int i = 0; i < 100; i++) { queueProducer.send(producerSession.createTextMessage("Message #" + Integer.toString(i))); } consumerConnection.stop(); consumerConnection.close(); consumerConnection = null; } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } removeAllMessages(queue1.getQueueName(), true); } } // // Multiple consumers // @Test public void testTwoConsumersNonTransacted() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); TextMessage tm = producerSession.createTextMessage(); tm.setText("One"); queueProducer.send(tm); tm.setText("Two"); queueProducer.send(tm); // recreate the connection and receive the first message consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); consumerConnection.start(); TextMessage m = (TextMessage) queueConsumer.receive(1500); ProxyAssertSupport.assertEquals("One", m.getText()); consumerConnection.close(); consumerConnection = null; // recreate the connection and receive the second message consumerConnection = createConnection(); consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); queueConsumer = consumerSession.createConsumer(queue1); consumerConnection.start(); m = (TextMessage) queueConsumer.receive(1500); ProxyAssertSupport.assertEquals("Two", m.getText()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } } } @Test public void testTwoConsumersTransacted() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer queueProducer = producerSession.createProducer(queue1); TextMessage tm = producerSession.createTextMessage(); tm.setText("One"); queueProducer.send(tm); tm.setText("Two"); queueProducer.send(tm); // recreate the connection and receive the first message consumerConnection = createConnection(); Session consumerSession = consumerConnection.createSession(true, -1); MessageConsumer queueConsumer = consumerSession.createConsumer(queue1); consumerConnection.start(); TextMessage m = (TextMessage) queueConsumer.receive(1500); ProxyAssertSupport.assertEquals("One", m.getText()); consumerSession.commit(); consumerConnection.close(); consumerConnection = null; // recreate the connection and receive the second message consumerConnection = createConnection(); consumerSession = consumerConnection.createSession(true, -1); queueConsumer = consumerSession.createConsumer(queue1); consumerConnection.start(); m = (TextMessage) queueConsumer.receive(1500); ProxyAssertSupport.assertEquals("Two", m.getText()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } removeAllMessages(queue1.getQueueName(), true); } } // // NoLocal // @Test public void testNoLocal() throws Exception { if (log.isTraceEnabled()) { log.trace("testNoLocal"); } Connection conn1 = null; Connection conn2 = null; try { conn1 = createConnection(); Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer1 = sess1.createProducer(ActiveMQServerTestCase.topic1); producer1.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageConsumer consumer1 = sess1.createConsumer(ActiveMQServerTestCase.topic1, null, true); conn2 = createConnection(); Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE); ProxyAssertSupport.assertEquals(Session.AUTO_ACKNOWLEDGE, sess2.getAcknowledgeMode()); MessageConsumer consumer2 = sess2.createConsumer(ActiveMQServerTestCase.topic1, null, true); // we need different session because we cannot access the same session from different // threads Session sess3 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE); ProxyAssertSupport.assertEquals(Session.AUTO_ACKNOWLEDGE, sess3.getAcknowledgeMode()); MessageConsumer consumer3 = sess3.createConsumer(ActiveMQServerTestCase.topic1, null, true); // ClientConsumer 1 should not get the message but consumers 2 and 3 should conn1.start(); conn2.start(); class TestRunnable implements Runnable { boolean exceptionThrown; public Message m; MessageConsumer consumer; TestRunnable(final MessageConsumer consumer) { this.consumer = consumer; } @Override public void run() { try { m = consumer.receive(1500); } catch (Exception e) { exceptionThrown = true; } } } TestRunnable tr1 = new TestRunnable(consumer1); TestRunnable tr2 = new TestRunnable(consumer2); TestRunnable tr3 = new TestRunnable(consumer3); Thread t1 = new Thread(tr1); Thread t2 = new Thread(tr2); Thread t3 = new Thread(tr3); t1.start(); t2.start(); t3.start(); Message m2 = sess1.createTextMessage("Hello"); producer1.send(m2); t1.join(); t2.join(); t3.join(); ProxyAssertSupport.assertTrue(!tr1.exceptionThrown); ProxyAssertSupport.assertTrue(!tr2.exceptionThrown); ProxyAssertSupport.assertTrue(!tr3.exceptionThrown); ProxyAssertSupport.assertNull(tr1.m); ProxyAssertSupport.assertNotNull(tr2.m); ProxyAssertSupport.assertNotNull(tr3.m); } finally { if (conn1 != null) { conn1.close(); } if (conn2 != null) { conn2.close(); } } } @Test public void testNoLocalMemoryExhaustion() throws Exception { Connection conn = null; try { conn = createConnection(); Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sess.createProducer(ActiveMQServerTestCase.topic1); MessageConsumer cons = sess.createConsumer(ActiveMQServerTestCase.topic1, null, true); final int numMessages = 100; for (int i = 0; i < numMessages; i++) { prod.send(sess.createMessage()); } conn.start(); Message msg = cons.receive(3000); ProxyAssertSupport.assertNull(msg); checkEmpty(ActiveMQServerTestCase.topic1); } finally { if (conn != null) { conn.close(); } } } /* * * Also see JMS 1.1 Spec. 6.12 */ @Test public void testTopicRedelivery() throws Exception { Connection conn1 = null; try { conn1 = createConnection(); conn1.start(); // Create 2 non durable subscribers on topic Session sess1 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE); Session sess2 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons1 = sess1.createConsumer(ActiveMQServerTestCase.topic1); MessageConsumer cons2 = sess2.createConsumer(ActiveMQServerTestCase.topic1); conn1.start(); Session sess3 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sess3.createProducer(ActiveMQServerTestCase.topic1); prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT); TextMessage tm = sess3.createTextMessage("nurse!"); prod.send(tm); TextMessage tm1 = (TextMessage) cons1.receive(1500); TextMessage tm2 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(tm1); ProxyAssertSupport.assertNotNull(tm2); ProxyAssertSupport.assertEquals("nurse!", tm1.getText()); ProxyAssertSupport.assertEquals("nurse!", tm2.getText()); // acknowledge tm1 tm1.acknowledge(); // tm2 has not been acknowledged // so should be redelivered on session.recover sess2.recover(); tm2 = (TextMessage) cons2.receive(1500); ProxyAssertSupport.assertNotNull(tm2); ProxyAssertSupport.assertEquals("nurse!", tm2.getText()); // but tm1 should not be redelivered tm1 = (TextMessage) cons1.receive(1500); ProxyAssertSupport.assertNull(tm1); } finally { if (conn1 != null) { log.trace("closing connection"); conn1.close(); } } } /** * Topics shouldn't persist messages for non durable subscribers and redeliver them on reconnection * even if delivery mode of persistent is specified * See JMS spec. sec. 6.12 */ @Test public void testNoRedeliveryOnNonDurableSubscriber() throws Exception { Connection conn1 = null; Connection conn2 = null; try { conn1 = createConnection(); conn1.start(); Session sess1 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer prod = sess1.createProducer(null); prod.setDeliveryMode(DeliveryMode.PERSISTENT); final int NUM_MESSAGES = 1; MessageConsumer cons = sess1.createConsumer(ActiveMQServerTestCase.topic1); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sess1.createTextMessage("helloxyz"); prod.send(ActiveMQServerTestCase.topic1, tm); } // receive but don't ack int count = 0; while (true) { TextMessage tm = (TextMessage) cons.receive(1000); if (tm == null) { break; } ProxyAssertSupport.assertEquals(tm.getText(), "helloxyz"); count++; } ProxyAssertSupport.assertEquals(NUM_MESSAGES, count); conn1.close(); conn1 = null; checkEmpty(ActiveMQServerTestCase.topic1); } finally { if (conn1 != null) { conn1.close(); } if (conn2 != null) { conn2.close(); } } } // Check messages have correct type after being resurrected from persistent storage @Test public void testPersistedMessageType() throws Exception { Connection theConn = null; Connection theOtherConn = null; try { theConn = createConnection(); theConn.start(); // Send some persistent messages to a queue with no receivers Session sessSend = theConn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer theProducer = sessSend.createProducer(queue1); theProducer.setDeliveryMode(DeliveryMode.PERSISTENT); Message m = sessSend.createMessage(); m.setStringProperty("p1", "aardvark"); BytesMessage bm = sessSend.createBytesMessage(); bm.writeObject("aardvark"); MapMessage mm = sessSend.createMapMessage(); mm.setString("s1", "aardvark"); ObjectMessage om = sessSend.createObjectMessage(); om.setObject("aardvark"); StreamMessage sm = sessSend.createStreamMessage(); sm.writeString("aardvark"); TextMessage tm = sessSend.createTextMessage("aardvark"); theProducer.send(m); theProducer.send(bm); theProducer.send(mm); theProducer.send(om); theProducer.send(sm); theProducer.send(tm); theConn.close(); theOtherConn = createConnection(); theOtherConn.start(); Session sessReceive = theOtherConn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer theConsumer = sessReceive.createConsumer(queue1); Message m2 = theConsumer.receive(1500); log.trace("m2 is " + m2); ProxyAssertSupport.assertNotNull(m2); ProxyAssertSupport.assertEquals("aardvark", m2.getStringProperty("p1")); BytesMessage bm2 = (BytesMessage) theConsumer.receive(1500); ProxyAssertSupport.assertEquals("aardvark", bm2.readUTF()); MapMessage mm2 = (MapMessage) theConsumer.receive(1500); ProxyAssertSupport.assertEquals("aardvark", mm2.getString("s1")); ObjectMessage om2 = (ObjectMessage) theConsumer.receive(1500); ProxyAssertSupport.assertEquals("aardvark", (String) om2.getObject()); StreamMessage sm2 = (StreamMessage) theConsumer.receive(1500); ProxyAssertSupport.assertEquals("aardvark", sm2.readString()); TextMessage tm2 = (TextMessage) theConsumer.receive(1500); ProxyAssertSupport.assertEquals("aardvark", tm2.getText()); } finally { if (theConn != null) { theConn.close(); } if (theOtherConn != null) { theOtherConn.close(); } } } @Test public void testDurableSubscriptionSimple() throws Exception { final String CLIENT_ID1 = "test-client-id1"; Connection conn1 = null; try { conn1 = createConnection(); conn1.setClientID(CLIENT_ID1); Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sess1.createProducer(null); prod.setDeliveryMode(DeliveryMode.PERSISTENT); MessageConsumer durable = sess1.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription"); conn1.start(); final int NUM_MESSAGES = 50; for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sess1.createTextMessage("hello"); prod.send(ActiveMQServerTestCase.topic1, tm); } int count = 0; while (true) { TextMessage tm = (TextMessage) durable.receive(1500); if (tm == null) { break; } count++; } ProxyAssertSupport.assertEquals(NUM_MESSAGES, count); durable.close(); sess1.unsubscribe("mySubscription"); } finally { if (conn1 != null) { conn1.close(); } } } @Test public void testDurableSubscriptionMultipleSubscriptions() throws Exception { final String CLIENT_ID1 = "test-client-id1"; Connection conn1 = null; Connection conn2 = null; Connection conn3 = null; try { conn1 = createConnection(); conn1.setClientID(CLIENT_ID1); Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); sess1.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription1"); sess1.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription2"); conn1.close(); conn2 = createConnection(); conn2.setClientID(CLIENT_ID1); Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = sess2.createProducer(ActiveMQServerTestCase.topic1); producer.setDeliveryMode(DeliveryMode.PERSISTENT); final int NUM_MESSAGES = 50; for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sess2.createTextMessage("hello"); producer.send(tm); } sess2.unsubscribe("mySubscription1"); conn2.close(); conn3 = createConnection(); conn3.setClientID(CLIENT_ID1); conn3.start(); Session sess3 = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer durable3 = sess3.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription2"); int count = 0; while (true) { TextMessage tm = (TextMessage) durable3.receive(1000); if (tm == null) { break; } ProxyAssertSupport.assertEquals("hello", tm.getText()); count++; } ProxyAssertSupport.assertEquals(NUM_MESSAGES, count); log.debug("received " + NUM_MESSAGES + " messages"); MessageConsumer durable4 = sess3.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription1"); Message m = durable4.receive(1000); ProxyAssertSupport.assertNull(m); durable3.close(); sess3.unsubscribe("mySubscription2"); durable4.close(); sess3.unsubscribe("mySubscription1"); } finally { if (conn1 != null) { conn1.close(); } if (conn2 != null) { conn2.close(); } if (conn3 != null) { conn3.close(); } } } @Test public void testDurableSubscriptionDataRemaining() throws Exception { final String CLIENT_ID1 = "test-client-id1"; Connection conn1 = null; Connection conn2 = null; Connection conn3 = null; Connection conn4 = null; Connection conn5 = null; Connection conn6 = null; Session sess1; Session sess3; Session sess4; Session sess6 = null; try { // Create a durable subscriber on one connection and close it conn1 = createConnection(); conn1.setClientID(CLIENT_ID1); sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer durable = sess1.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription"); conn1.close(); // Send some messages on another connection and close it conn2 = createConnection(); conn2.setClientID(CLIENT_ID1); Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod2 = sess2.createProducer(null); prod2.setDeliveryMode(DeliveryMode.PERSISTENT); final int NUM_MESSAGES = 10; for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sess2.createTextMessage("hello"); prod2.send(ActiveMQServerTestCase.topic1, tm); } conn2.close(); // Receive the messages on another connection conn3 = createConnection(); conn3.setClientID(CLIENT_ID1); conn3.start(); sess3 = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE); durable = sess3.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription"); int count = 0; while (true) { TextMessage tm = (TextMessage) durable.receive(1000); if (tm == null) { break; } ProxyAssertSupport.assertEquals("hello", tm.getText()); count++; } ProxyAssertSupport.assertEquals(NUM_MESSAGES, count); conn3.close(); // Try and receive them again conn4 = createConnection(); conn4.setClientID(CLIENT_ID1); conn4.start(); sess4 = conn4.createSession(false, Session.AUTO_ACKNOWLEDGE); durable = sess4.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription"); TextMessage tm = (TextMessage) durable.receive(1000); ProxyAssertSupport.assertNull(tm); conn4.close(); // Send some more messages and unsubscribe conn5 = createConnection(); conn5.setClientID(CLIENT_ID1); conn5.start(); Session sess5 = conn5.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod5 = sess5.createProducer(null); prod5.setDeliveryMode(DeliveryMode.PERSISTENT); log.debug("sending.1 " + NUM_MESSAGES + " messages"); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm2 = sess5.createTextMessage("hello"); prod5.send(ActiveMQServerTestCase.topic1, tm2); } log.debug("unsubscribing mySubscription"); durable.close(); sess5.unsubscribe("mySubscription"); log.debug("unsubscribing done"); conn5.close(); // Resubscribe with the same name conn6 = createConnection(); conn6.setClientID(CLIENT_ID1); conn6.start(); sess6 = conn6.createSession(false, Session.AUTO_ACKNOWLEDGE); durable = sess6.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription"); TextMessage tm3 = (TextMessage) durable.receive(1000); ProxyAssertSupport.assertNull(tm3); durable.close(); } finally { if (conn1 != null) { conn1.close(); } if (conn2 != null) { conn2.close(); } if (conn3 != null) { conn3.close(); } if (conn4 != null) { conn4.close(); } if (conn5 != null) { conn5.close(); } if (sess6 != null) { sess6.unsubscribe("mySubscription"); } if (conn6 != null) { conn6.close(); } } } @Test public void testDurableSubscriptionReconnect() throws Exception { final String CLIENT_ID1 = "test-client-id1"; Connection conn1 = null; Connection conn2 = null; try { conn1 = createConnection(); conn1.setClientID(CLIENT_ID1); Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sess1.createProducer(null); prod.setDeliveryMode(DeliveryMode.PERSISTENT); MessageConsumer durable = sess1.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription"); conn1.start(); final int NUM_MESSAGES = 2; for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sess1.createTextMessage("hello"); prod.send(ActiveMQServerTestCase.topic1, tm); } final int NUM_TO_RECEIVE = NUM_MESSAGES - 1; for (int i = 0; i < NUM_TO_RECEIVE; i++) { TextMessage tm = (TextMessage) durable.receive(3000); ProxyAssertSupport.assertNotNull(tm); } // Close the connection conn1.close(); conn1 = null; conn2 = createConnection(); conn2.setClientID(CLIENT_ID1); Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE); // Re-subscribe to the subscription MessageConsumer durable2 = sess2.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription"); conn2.start(); int count = 0; while (true) { TextMessage tm = (TextMessage) durable2.receive(1500); if (tm == null) { break; } count++; } ProxyAssertSupport.assertEquals(NUM_MESSAGES - NUM_TO_RECEIVE, count); durable2.close(); sess2.unsubscribe("mySubscription"); } finally { if (conn1 != null) { conn1.close(); } if (conn2 != null) { conn2.close(); } } } @Test public void testDurableSubscriptionReconnectDifferentClientID() throws Exception { final String CLIENT_ID1 = "test-client-id1"; final String CLIENT_ID2 = "test-client-id2"; Connection conn1 = null; Connection conn2 = null; try { conn1 = createConnection(); conn1.setClientID(CLIENT_ID1); Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sess1.createProducer(null); prod.setDeliveryMode(DeliveryMode.PERSISTENT); MessageConsumer durable = sess1.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription"); conn1.start(); final int NUM_MESSAGES = 50; for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sess1.createTextMessage("hello"); prod.send(ActiveMQServerTestCase.topic1, tm); } final int NUM_TO_RECEIVE1 = 22; for (int i = 0; i < NUM_TO_RECEIVE1; i++) { TextMessage tm = (TextMessage) durable.receive(1500); if (tm == null) { ProxyAssertSupport.fail(); } } // Close the connection conn1.close(); conn1 = null; conn2 = createConnection(); conn2.setClientID(CLIENT_ID2); Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE); // Re-subscribe to the subscription MessageConsumer durable2 = sess2.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription"); conn2.start(); TextMessage tm = (TextMessage) durable2.receive(1500); ProxyAssertSupport.assertNull(tm); durable2.close(); sess2.unsubscribe("mySubscription"); // Now need to remove the original subscription conn1 = createConnection(); conn1.setClientID(CLIENT_ID1); sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); sess1.unsubscribe("mySubscription"); } finally { if (conn1 != null) { conn1.close(); } if (conn2 != null) { conn2.close(); } } } @Test public void testDurableSubscriptionInvalidUnsubscribe() throws Exception { final String CLIENT_ID1 = "test-client-id1"; Connection conn1 = null; try { conn1 = createConnection(); conn1.setClientID(CLIENT_ID1); Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); try { sess1.unsubscribe("non-existent subscription"); ProxyAssertSupport.fail(); } catch (JMSException e) { } } finally { if (conn1 != null) { conn1.close(); } } } @Test public void testDurableSubscriptionClientIDNotSet() throws Exception { // Client id must be set before creating a durable subscription // This assumes we are not setting it in the connection factory which // is currently true but may change in the future Connection conn1 = null; try { conn1 = createConnection(); ProxyAssertSupport.assertNull(conn1.getClientID()); Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); try { sess1.createDurableSubscriber(ActiveMQServerTestCase.topic1, "mySubscription"); ProxyAssertSupport.fail(); } catch (JMSException e) { } } finally { if (conn1 != null) { conn1.close(); } } } @Test public void testRedeliveredDifferentSessions() throws Exception { Connection producerConnection = null; Connection consumerConnection = null; try { producerConnection = createConnection(); consumerConnection = createConnection(); Session sessProducer = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessProducer.createProducer(queue1); TextMessage tm = sessProducer.createTextMessage("testRedeliveredDifferentSessions"); prod.send(tm); consumerConnection.start(); Session sess1 = consumerConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons1 = sess1.createConsumer(queue1); TextMessage tm2 = (TextMessage) cons1.receive(3000); ProxyAssertSupport.assertNotNull(tm2); ProxyAssertSupport.assertEquals("testRedeliveredDifferentSessions", tm2.getText()); // don't acknowledge it sess1.close(); Session sess2 = consumerConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons2 = sess2.createConsumer(queue1); TextMessage tm3 = (TextMessage) cons2.receive(3000); ProxyAssertSupport.assertNotNull(tm3); ProxyAssertSupport.assertEquals("testRedeliveredDifferentSessions", tm3.getText()); ProxyAssertSupport.assertTrue(tm3.getJMSRedelivered()); } finally { if (producerConnection != null) { producerConnection.close(); } if (consumerConnection != null) { consumerConnection.close(); } removeAllMessages(queue1.getQueueName(), true); } } @Test public void testRedelMessageListener1() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sessProducer = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); Session sessConsumer = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons = sessConsumer.createConsumer(queue1); RedelMessageListenerImpl listener = new RedelMessageListenerImpl(false); listener.sess = sessConsumer; cons.setMessageListener(listener); MessageProducer prod = sessProducer.createProducer(queue1); prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT); TextMessage m1 = sessProducer.createTextMessage("a"); TextMessage m2 = sessProducer.createTextMessage("b"); TextMessage m3 = sessProducer.createTextMessage("c"); prod.send(m1); prod.send(m2); prod.send(m3); listener.waitForMessages(); conn.close(); conn = null; ProxyAssertSupport.assertFalse(listener.failed); } finally { if (conn != null) { conn.close(); } } } @Test public void testRedelMessageListener2() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); MessageConsumer cons = sess.createConsumer(queue1); RedelMessageListenerImpl listener = new RedelMessageListenerImpl(true); listener.sess = sess; cons.setMessageListener(listener); MessageProducer prod = sessSend.createProducer(queue1); TextMessage m1 = sess.createTextMessage("a"); TextMessage m2 = sess.createTextMessage("b"); TextMessage m3 = sess.createTextMessage("c"); prod.send(m1); prod.send(m2); prod.send(m3); listener.waitForMessages(); log.debug(listener.messageOrder); ProxyAssertSupport.assertFalse(listener.messageOrder, listener.failed); conn.close(); conn = null; } finally { if (conn != null) { conn.close(); } } } // http://jira.jboss.org/jira/browse/JBMESSAGING-1294 - commented out until 2.0 beta @Test public void testExceptionMessageListener1() throws Exception { Connection conn = createConnection(); conn.start(); Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer cons = sess.createConsumer(queue1); ExceptionRedelMessageListenerImpl listener = new ExceptionRedelMessageListenerImpl(sess); cons.setMessageListener(listener); MessageProducer prod = sessSend.createProducer(queue1); TextMessage m1 = sess.createTextMessage("a"); TextMessage m2 = sess.createTextMessage("b"); TextMessage m3 = sess.createTextMessage("c"); prod.send(m1); prod.send(m2); prod.send(m3); listener.waitForMessages(); ProxyAssertSupport.assertFalse(listener.message, listener.failed); } @Test public void testExceptionMessageListener2() throws Exception { Connection conn = createConnection(); conn.start(); Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE); MessageConsumer cons = sess.createConsumer(queue1); ExceptionRedelMessageListenerImpl listener = new ExceptionRedelMessageListenerImpl(sess); cons.setMessageListener(listener); MessageProducer prod = sessSend.createProducer(queue1); TextMessage m1 = sess.createTextMessage("a"); TextMessage m2 = sess.createTextMessage("b"); TextMessage m3 = sess.createTextMessage("c"); prod.send(m1); prod.send(m2); prod.send(m3); listener.waitForMessages(); ProxyAssertSupport.assertFalse(listener.message, listener.failed); } @Test public void testExceptionMessageListener3() throws Exception { Connection conn = createConnection(); conn.start(); Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); MessageConsumer cons = sess.createConsumer(queue1); ExceptionRedelMessageListenerImpl listener = new ExceptionRedelMessageListenerImpl(sess); cons.setMessageListener(listener); MessageProducer prod = sessSend.createProducer(queue1); TextMessage m1 = sess.createTextMessage("a"); TextMessage m2 = sess.createTextMessage("b"); TextMessage m3 = sess.createTextMessage("c"); prod.send(m1); prod.send(m2); prod.send(m3); listener.waitForMessages(); ProxyAssertSupport.assertFalse(listener.failed); conn.close(); removeAllMessages(queue1.getQueueName(), true); } @Test public void testExceptionMessageListener4() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons = sess.createConsumer(queue1); ExceptionRedelMessageListenerImpl listener = new ExceptionRedelMessageListenerImpl(sess); cons.setMessageListener(listener); MessageProducer prod = sessSend.createProducer(queue1); TextMessage m1 = sess.createTextMessage("a"); TextMessage m2 = sess.createTextMessage("b"); TextMessage m3 = sess.createTextMessage("c"); prod.send(m1); prod.send(m2); prod.send(m3); listener.waitForMessages(); ProxyAssertSupport.assertFalse(listener.failed); conn.close(); conn = null; } finally { if (conn != null) { conn.close(); } removeAllMessages(queue1.getQueueName(), true); } } @Test public void testExceptionMessageListenerCloseConnection() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons = sess.createConsumer(queue1); CountDownLatch latch = new CountDownLatch(1); ConnectionCloseMessageListener listener = new ConnectionCloseMessageListener(conn, latch); cons.setMessageListener(listener); conn.start(); MessageProducer prod = sessSend.createProducer(queue1); TextMessage m1 = sess.createTextMessage("a"); prod.send(m1); ProxyAssertSupport.assertTrue(latch.await(5, TimeUnit.SECONDS)); ProxyAssertSupport.assertNotNull(listener.exception); ProxyAssertSupport.assertTrue(listener.exception instanceof javax.jms.IllegalStateException); } finally { if (conn != null) { conn.close(); } removeAllMessages(queue1.getQueueName(), true); } } @Test public void testExceptionMessageListenerStopConnection() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons = sess.createConsumer(queue1); CountDownLatch latch = new CountDownLatch(1); ConnectionStopMessageListener listener = new ConnectionStopMessageListener(conn, latch); cons.setMessageListener(listener); conn.start(); MessageProducer prod = sessSend.createProducer(queue1); TextMessage m1 = sess.createTextMessage("a"); prod.send(m1); ProxyAssertSupport.assertTrue(latch.await(5, TimeUnit.SECONDS)); ProxyAssertSupport.assertNotNull(listener.exception); ProxyAssertSupport.assertTrue(listener.exception instanceof javax.jms.IllegalStateException); } finally { if (conn != null) { conn.close(); } removeAllMessages(queue1.getQueueName(), true); } } @Test public void testExceptionMessageListenerStopSession() throws Exception { Connection conn = null; try { conn = createConnection(); conn.start(); Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer cons = sess.createConsumer(queue1); CountDownLatch latch = new CountDownLatch(1); SessionCloseMessageListener listener = new SessionCloseMessageListener(sess, latch); cons.setMessageListener(listener); conn.start(); MessageProducer prod = sessSend.createProducer(queue1); TextMessage m1 = sess.createTextMessage("a"); prod.send(m1); ProxyAssertSupport.assertTrue(latch.await(5, TimeUnit.SECONDS)); ProxyAssertSupport.assertNotNull(listener.exception); ProxyAssertSupport.assertTrue(listener.exception instanceof javax.jms.IllegalStateException); } finally { if (conn != null) { conn.close(); } removeAllMessages(queue1.getQueueName(), true); } } // Package protected --------------------------------------------- // Protected ----------------------------------------------------- // Private ------------------------------------------------------- // Inner classes ------------------------------------------------- private class ConnectionCloseMessageListener implements MessageListener { private Connection conn; private CountDownLatch latch; private JMSException exception; private ConnectionCloseMessageListener(Connection conn, CountDownLatch latch) { this.conn = conn; this.latch = latch; } @Override public void onMessage(Message message) { try { conn.close(); } catch (JMSException e) { this.exception = e; } latch.countDown(); } } private class ConnectionStopMessageListener implements MessageListener { private Connection conn; private CountDownLatch latch; private JMSException exception; private ConnectionStopMessageListener(Connection conn, CountDownLatch latch) { this.conn = conn; this.latch = latch; } @Override public void onMessage(Message message) { try { conn.stop(); } catch (JMSException e) { this.exception = e; } latch.countDown(); } } private class SessionCloseMessageListener implements MessageListener { private Session session; private CountDownLatch latch; private JMSException exception; private SessionCloseMessageListener(Session session, CountDownLatch latch) { this.session = session; this.latch = latch; } @Override public void onMessage(Message message) { try { session.close(); } catch (JMSException e) { this.exception = e; } latch.countDown(); } } private class ExceptionRedelMessageListenerImpl implements MessageListener { private final CountDownLatch latch = new CountDownLatch(1); private int count; private final Session sess; private boolean failed; String message = "ok"; private void failed(final String msg) { log.warn(msg); failed = true; message = msg; } public void waitForMessages() throws InterruptedException { ActiveMQTestBase.waitForLatch(latch); } private ExceptionRedelMessageListenerImpl(final Session sess) { this.sess = sess; } @Override public void onMessage(final Message m) { TextMessage tm = (TextMessage) m; count++; try { if (count == 1) { if (!"a".equals(tm.getText())) { failed("Should be a but was " + tm.getText()); latch.countDown(); } throw new RuntimeException("Aardvark"); } else if (count == 2) { if (sess.getAcknowledgeMode() == Session.AUTO_ACKNOWLEDGE || sess.getAcknowledgeMode() == Session.DUPS_OK_ACKNOWLEDGE) { // Message should be immediately redelivered if (!"a".equals(tm.getText())) { failed("Should be a but was " + tm.getText()); latch.countDown(); } if (!tm.getJMSRedelivered()) { failed("Message was supposed to be a redelivery"); latch.countDown(); } } else { // Transacted or CLIENT_ACKNOWLEDGE - next message should be delivered if (!"b".equals(tm.getText())) { failed("Should be b but was " + tm.getText()); latch.countDown(); } } } else if (count == 3) { if (sess.getAcknowledgeMode() == Session.AUTO_ACKNOWLEDGE || sess.getAcknowledgeMode() == Session.DUPS_OK_ACKNOWLEDGE) { if (!"b".equals(tm.getText())) { failed("Should be b but was " + tm.getText()); latch.countDown(); } } else { if (!"c".equals(tm.getText())) { failed("Should be c but was " + tm.getText()); latch.countDown(); } latch.countDown(); } } else if (count == 4) { if (sess.getAcknowledgeMode() == Session.AUTO_ACKNOWLEDGE || sess.getAcknowledgeMode() == Session.DUPS_OK_ACKNOWLEDGE) { if (!"c".equals(tm.getText())) { failed("Should be c but was " + tm.getText()); latch.countDown(); } latch.countDown(); } else { // Shouldn't get a 4th message failed("Shouldn't get a 4th message"); latch.countDown(); } } } catch (JMSException e) { log.error(e.getMessage(), e); failed("Got a JMSException " + e.toString()); latch.countDown(); } } } private class RedelMessageListenerImpl implements MessageListener { private Session sess; private int count; private boolean failed; private String messageOrder = "message sequence is: "; private final CountDownLatch latch = new CountDownLatch(1); private final boolean transacted; private RedelMessageListenerImpl(final boolean transacted) { this.transacted = transacted; } /** * Blocks the calling thread until at least a message is received */ public void waitForMessages() throws InterruptedException { ActiveMQTestBase.waitForLatch(latch); } @Override public void onMessage(final Message m) { try { TextMessage tm = (TextMessage) m; messageOrder += tm.getText() + " "; if (count == 0) { if (!"a".equals(tm.getText())) { failed = true; latch.countDown(); } if (transacted) { sess.rollback(); messageOrder += "RB "; } else { messageOrder += "RC "; sess.recover(); } } if (count == 1) { if (!"a".equals(tm.getText())) { failed = true; latch.countDown(); } if (!tm.getJMSRedelivered()) { failed = true; latch.countDown(); } } if (count == 2) { if (!"b".equals(tm.getText())) { failed = true; latch.countDown(); } } if (count == 3) { if (!"c".equals(tm.getText())) { failed = true; latch.countDown(); } if (transacted) { sess.commit(); } else { tm.acknowledge(); } latch.countDown(); } count++; } catch (JMSException e) { failed = true; latch.countDown(); } } } private class MessageListenerImpl implements MessageListener { private final List<Message> messages = Collections.synchronizedList(new ArrayList<Message>()); private CountDownLatch latch = new CountDownLatch(1); private MessageListenerImpl(final int count) { latch = new CountDownLatch(count); } private MessageListenerImpl() { this(1); } /** * Blocks the calling thread until at least a message is received */ public void waitForMessages() throws InterruptedException { ActiveMQTestBase.waitForLatch(latch); } @Override public void onMessage(final Message m) { messages.add(m); log.trace("Added message " + m + " to my list"); latch.countDown(); } public Message getNextMessage() { Iterator<Message> i = messages.iterator(); if (!i.hasNext()) { return null; } Message m = i.next(); i.remove(); return m; } public List<Message> getMessages() { return messages; } public int size() { return messages.size(); } } }