Package org.jboss.test.messaging.jms

Source Code of org.jboss.test.messaging.jms.MessageConsumerTest$MessageListenerImpl

/*
  * JBoss, Home of Professional Open Source
  * Copyright 2005, JBoss Inc., and individual contributors as indicated
  * by the @authors tag. See the copyright.txt in the distribution for a
  * full listing of individual contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
package org.jboss.test.messaging.jms;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
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.TopicSubscriber;
import javax.naming.InitialContext;

import org.jboss.jms.destination.JBossTopic;
import org.jboss.test.messaging.MessagingTestCase;
import org.jboss.test.messaging.tools.ServerManagement;

import EDU.oswego.cs.dl.util.concurrent.Latch;

/**
* @author <a href="mailto:ovidiu@jboss.org">Ovidiu Feodorov</a>
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
* @author <a href="mailto:clebert.suconic@jboss.com">Clebert Suconic</a>
* @version <tt>$Revision: 2507 $</tt>
*
* $Id: MessageConsumerTest.java 2507 2007-02-28 23:46:51Z timfox $
*/
public class MessageConsumerTest extends MessagingTestCase
{
   // Constants -----------------------------------------------------

   // Static --------------------------------------------------------

   // Attributes ----------------------------------------------------

   protected Connection producerConnection, consumerConnection;
   protected Session producerSession, consumerSession;
   protected MessageProducer topicProducer, queueProducer;
   protected MessageConsumer topicConsumer, queueConsumer;
   protected Topic topic;
   protected Queue queue;
   protected Queue queue2;
   protected ConnectionFactory cf;

   protected Thread worker1;

   // Constructors --------------------------------------------------

   public MessageConsumerTest(String name)
   {
      super(name);
   }

   // Public --------------------------------------------------------

   public void setUp() throws Exception
   {
      super.setUp();

      ServerManagement.start("all");

      ServerManagement.undeployTopic("Topic");
      ServerManagement.undeployQueue("Queue");
      ServerManagement.undeployQueue("Queue2");

      ServerManagement.deployTopic("Topic");
      ServerManagement.deployQueue("Queue");
      ServerManagement.deployQueue("Queue2");

      InitialContext ic = new InitialContext(ServerManagement.getJNDIEnvironment());
      cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
      topic = (Topic)ic.lookup("/topic/Topic");
      queue = (Queue)ic.lookup("/queue/Queue");
      queue2 = (Queue)ic.lookup("/queue/Queue2");

      producerConnection = cf.createConnection();
      consumerConnection = cf.createConnection();

      producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);

      topicProducer = producerSession.createProducer(topic);
      topicProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
      topicConsumer = consumerSession.createConsumer(topic);

      queueProducer = producerSession.createProducer(queue);
      queueProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
      queueConsumer = consumerSession.createConsumer(queue);

      this.drainDestination(cf, queue);
      this.drainDestination(cf, queue2);

      log.debug("setup done");
   }

   public void tearDown() throws Exception
   {
      producerConnection.close();
      consumerConnection.close();

      if (worker1 != null)
      {
         worker1.interrupt();
      }

      ServerManagement.undeployTopic("Topic");
      ServerManagement.undeployQueue("Queue");
      ServerManagement.undeployQueue("Queue2");

      super.tearDown();
   }

  
   public void testReceiveWithClientAckThenCloseSession() throws Exception
   {
      Connection conn = null;
     
      try
      {
         conn = cf.createConnection();
        
         Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        
         MessageProducer prod = sess.createProducer(queue);
        
         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(queue);
        
         conn.start();
        
         for (int i = 0; i < NUM_MESSAGES; i++)
         {
            TextMessage tm = (TextMessage)cons.receive(500);
           
            assertNotNull(tm);
           
            assertEquals("message" + i, tm.getText());
         }
        
         // Now close the session

         sess2.close();
        
      }
      finally
      {
         if (conn != null)
         {
            conn.close();
         }
      }
      
   }
  
  
   public void testRelayMessage() throws Exception
   {
      Connection conn = cf.createConnection();

      conn.start();

      final Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

      MessageConsumer cons = sess.createConsumer(queue);

      final Object lock = new Object();

      final int numMessages = 100;


      class MyListener implements MessageListener
      {
         boolean failed;

         int count;

         public void onMessage(Message m)
         {
            try
            {
               MessageProducer prod = sess.createProducer(queue2);

               prod.send(m);

               count++;

               if (count == numMessages)
               {
                  synchronized (lock)
                  {
                     lock.notify();
                  }

               }
            }
            catch (JMSException e)
            {
               failed = true;
            }
         }
      }

      MyListener listener = new MyListener();

      cons.setMessageListener(listener);

      MessageProducer prod = sess.createProducer(queue);

      for (int i = 0; i < numMessages; i++)
      {
         prod.send(sess.createMessage());
      }

      synchronized (lock)
      {
         lock.wait();
      }

      conn.close();

      assertFalse(listener.failed);
   }


   /*
    * 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
    */
   public void testRedeliveryToCompetingConsumerOnQueue() throws Exception
   {
      Connection conn = null;
     
      try
      {
         conn = cf.createConnection();
     
         Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
  
         MessageProducer prod = sessSend.createProducer(queue);
  
         conn.start();
  
         Session sessConsume1 = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
  
         MessageConsumer cons1 = sessConsume1.createConsumer(queue);
  
         TextMessage tm = sessSend.createTextMessage();
  
         tm.setText("Your mum");
  
         prod.send(tm);
  
         TextMessage tm2 = (TextMessage)cons1.receive();
  
         assertNotNull(tm2);
  
         assertEquals("Your mum", tm2.getText());
  
         // Don't ack
  
         // Create another consumer
  
         Session sessConsume2 = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
  
         MessageConsumer cons2 = sessConsume2.createConsumer(queue);
  
         // this should cancel message and cause delivery to other consumer
  
         log.trace("Closed session 1");
         sessConsume1.close();
  
         TextMessage tm3 = (TextMessage)cons2.receive(1000);
  
         assertNotNull(tm3);
  
         assertEquals("Your mum", tm3.getText());
  
         tm3.acknowledge();
      }
      finally
      {

         if (conn != null)
         {
            conn.close();
         }
      }

   }


   public void testRedeliveryToCompetingConsumerOnSubscription() throws Exception
   {
      Connection conn = cf.createConnection();

      conn.setClientID("wibble");

      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

      MessageProducer prod = sessSend.createProducer(topic);

      conn.start();

      Session sessConsume1 = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);

      MessageConsumer cons1 = sessConsume1.createDurableSubscriber(topic, "sub1");

      TextMessage tm = sessSend.createTextMessage();

      tm.setText("Your mum");

      prod.send(tm);

      TextMessage tm2 = (TextMessage)cons1.receive();

      assertNotNull(tm2);

      assertEquals("Your mum", tm2.getText());

      //Don't ack

      //Create another consumer

      Session sessConsume2 = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);

      MessageConsumer cons2 = sessConsume2.createDurableSubscriber(topic, "sub1");

      //this should cancel message and cause delivery to other consumer

      sessConsume1.close();

      TextMessage tm3 = (TextMessage)cons2.receive(1000);

      assertNotNull(tm3);

      assertEquals("Your mum", tm3.getText());

      tm3.acknowledge();

      conn.close();

   }

   /**
    * The simplest possible receive() test for a non-persistent message.
    */
   public void testReceive() throws Exception
   {
      // 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();
      assertEquals(tm.getText(), m.getText());

   }

   public void testReceivePersistent() throws Exception
   {
      // start consumer connection before the message is submitted
      consumerConnection.start();

      TextMessage tm = producerSession.createTextMessage("someText");
      assertEquals(DeliveryMode.PERSISTENT, tm.getJMSDeliveryMode());

      queueProducer.send(tm);

      TextMessage m = (TextMessage)queueConsumer.receive();
      assertEquals(tm.getText(), m.getText());
   }


   /**
    * The simplest possible receive(timeout) test.
    */
   public void testReceiveTimeout() throws Exception
   {
      TextMessage tm = producerSession.createTextMessage("someText");
      queueProducer.send(tm);

      // start consumer connection after the message is submitted
      consumerConnection.start();

      TextMessage m = (TextMessage)queueConsumer.receive(3000);
      assertEquals(tm.getText(), m.getText());
   }

   /**
    * The simplest possible receiveNoWait() test.
    */
   public void testReceiveNoWait() throws Exception
   {
      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 implement it this way

      Thread.sleep(500);

      TextMessage m = (TextMessage)queueConsumer.receiveNoWait();
      assertEquals(tm.getText(), m.getText());
   }

   /**
    * The simplest possible message listener test.
    */
   public void testReceiveOnListener() throws Exception
   {
      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();
      assertEquals(tm.getText(), m.getText());
   }

   //
   // Invalid destination test
   //

   public void testCreateConsumerOnInexistentDestination() throws Exception
   {
      Connection pconn = cf.createConnection();

      try
      {
         Session ps = pconn.createSession(false, Session.AUTO_ACKNOWLEDGE);

         try
         {
            ps.createConsumer(new JBossTopic("NoSuchTopic"));
            fail("should throw exception");
         }
         catch(InvalidDestinationException e)
         {
            // OK
         }
      }
      finally
      {
         pconn.close();
      }
   }

   //
   // closed consumer tests
   //

   //This test is not valid -
   //The message will not be in the new consumer it will be in the original consumer

//   public void testClose1() throws Exception
//   {
//      // there is a consumer already open by setup
//
//      consumerConnection.start();
//
//      Message m = producerSession.createMessage();
//      queueProducer.send(m);
//
//      // the message is in the channel, however the queue maintains it as "not delivered"
//
//      QueueBrowser browser = producerSession.createBrowser(queue);
//      Enumeration e = browser.getEnumeration();
//      Message bm = (Message)e.nextElement();
//      assertEquals(m.getJMSMessageID(), bm.getJMSMessageID());
//      assertFalse(e.hasMoreElements());
//
//      // create a second consumer and try to receive from queue, it should return the message
//      MessageConsumer queueConsumer2 = consumerSession.createConsumer(queue);
//
//      Message rm = queueConsumer2.receive(3000);
//      assertEquals(m.getJMSMessageID(), rm.getJMSMessageID());
//
//      queueConsumer.close();
//
//
//      // try to receive from queue again, it should get a message
//      rm = queueConsumer2.receive(3000);
//      assertNull(rm);
//
//   }

   /* Test that an ack can be sent after the consumer that received the message has been closed.
    * Acks are scoped per session.
    */
   public void testAckAfterConsumerClosed() throws Exception
   {
      Connection connSend = null;
      Connection connReceive = null;

      try
      {

         connSend = cf.createConnection();

         connSend.start();

         Session sessSend = connSend.createSession(true, Session.SESSION_TRANSACTED);

         MessageProducer prod = sessSend.createProducer(queue2);

         prod.setDeliveryMode(DeliveryMode.PERSISTENT);

         Message m = sessSend.createTextMessage("hello");

         prod.send(m);

         sessSend.commit();

         connReceive = cf.createConnection();

         connReceive.start();

         Session sessReceive = connReceive.createSession(true, Session.SESSION_TRANSACTED);

         MessageConsumer cons = sessReceive.createConsumer(queue2);

         TextMessage m2 = (TextMessage)cons.receive(1500);

         assertNotNull(m2);

         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();
      }
   }


    public void testClientAcknowledgmentOnClosedConsumer() throws Exception
    {
       // create my consumer from scratch
       consumerConnection.close();

       TextMessage tm = producerSession.createTextMessage();

       tm.setText("One");
       queueProducer.send(tm);


       consumerConnection = cf.createConnection();
       consumerSession = consumerConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
       queueConsumer = consumerSession.createConsumer(queue);

       consumerConnection.start();

       TextMessage m =  (TextMessage)queueConsumer.receive(1500);
       assertEquals(m.getText(), "One");

       queueConsumer.close();

       m.acknowledge();

       try
       {
          queueConsumer.receive(2000);
          fail("should throw exception");
       }
       catch(javax.jms.IllegalStateException e)
       {
          // OK
       }
    }




   public void testSendMessageAndCloseConsumer1() throws Exception
   {
      // setUp() created a consumer already

      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(queue);

      consumerConnection.start();

      Message r = queueConsumer.receive(3000);
      assertEquals(m.getJMSMessageID(), r.getJMSMessageID());
   }


   /**
    * 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.
    */
   public void testSendMessageAndCloseConsumer2() throws Exception
   {
      // create my consumer from scratch
      consumerConnection.close();

      TextMessage tm = producerSession.createTextMessage();

      tm.setText("One");
      queueProducer.send(tm);

      tm.setText("Two");
      queueProducer.send(tm);

      consumerConnection = cf.createConnection();
      consumerSession = consumerConnection.createSession(true, 0);
      queueConsumer = consumerSession.createConsumer(queue);

      consumerConnection.start();

      TextMessage m =  (TextMessage)queueConsumer.receive(1500);
      assertEquals("One", m.getText());

      queueConsumer.close();
      consumerSession.commit();

      // I expect that "Two" is still in the queue

      MessageConsumer queueConsumer2 = consumerSession.createConsumer(queue);
      m =  (TextMessage)queueConsumer2.receive(1500);
      assertNotNull(m);
      assertEquals(m.getText(), "Two");

      consumerSession.commit();

      consumerConnection.close();
   }

    public void testRedel0() throws Exception
    {
       Connection conn = null;

       try
       {
          conn = cf.createConnection();
          conn.start();

          Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
          MessageProducer prod = sess.createProducer(queue);
          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(queue);

          TextMessage rm1 = (TextMessage)cons1.receive();
          assertNotNull(rm1);
          assertEquals("a", rm1.getText());

          cons1.close();

          MessageConsumer cons2 = sess.createConsumer(queue);

          sess.commit();

          TextMessage rm2 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm2);
          assertEquals("b", rm2.getText());

          TextMessage rm3 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm3);
          assertEquals("c", rm3.getText());

          TextMessage rm4 = (TextMessage)cons2.receive(1500);
          assertNull(rm4);


       }
       finally
       {
          if (conn != null)
          {
             conn.close();
          }
       }

    }


    public void testRedel1() throws Exception
    {
       Connection conn = null;

       try
       {
          conn = cf.createConnection();
          conn.start();

          Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
          MessageProducer prod = sess.createProducer(queue);
          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(queue);

          TextMessage rm1 = (TextMessage)cons1.receive(1500);
          assertNotNull(rm1);
          assertEquals("hello1", rm1.getText());

          cons1.close();

          MessageConsumer cons2 = sess.createConsumer(queue);

          sess.commit();

          TextMessage rm2 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm2);
          assertEquals("hello2", rm2.getText());

          TextMessage rm3 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm3);
          assertEquals("hello3", rm3.getText());

          TextMessage rm4 = (TextMessage)cons2.receive(1500);
          assertNull(rm4);


       }
       finally
       {
          if (conn != null)
          {
             conn.close();
          }
       }

    }

    public void testRedel2() throws Exception
    {
       Connection conn = null;

       try
       {
          conn = cf.createConnection();
          conn.start();

          Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
          MessageProducer prod = sess.createProducer(queue);
          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(queue);

          TextMessage rm1 = (TextMessage)cons1.receive(1500);
          assertNotNull(rm1);
          assertEquals("hello1", rm1.getText());

          cons1.close();

          sess.commit();

          MessageConsumer cons2 = sess.createConsumer(queue);

          TextMessage rm2 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm2);
          assertEquals("hello2", rm2.getText());

          TextMessage rm3 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm3);
          assertEquals("hello3", rm3.getText());

          TextMessage rm4 = (TextMessage)cons2.receive(1500);
          assertNull(rm4);


       }
       finally
       {
          if (conn != null)
          {
             conn.close();
          }
       }

    }

    public void testRedel3() throws Exception
    {
       Connection conn = null;

       try
       {
          conn = cf.createConnection();
          conn.start();

          Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
          MessageProducer prod = sess.createProducer(queue);
          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(queue);

          TextMessage rm1 = (TextMessage)cons1.receive(1500);
          assertNotNull(rm1);
          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);
          assertEquals("hello1", rm2.getText());
          log.trace(rm1.getJMSMessageID());

          TextMessage rm3 = (TextMessage)cons1.receive(1500);
          assertEquals("hello2", rm3.getText());

          TextMessage rm4 = (TextMessage)cons1.receive(1500);
          assertEquals("hello3", rm4.getText());

          //This last step is important - there shouldn't be any more messages to receive
          TextMessage rm5 = (TextMessage)cons1.receive(1500);
          assertNull(rm5);

       }
       finally
       {
          if (conn != null)
          {
             conn.close();
          }
       }

    }

    public void testRedel4() throws Exception
    {
       Connection conn = null;

       try
       {
          conn = cf.createConnection();
          conn.start();

          Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
          MessageProducer prod = sess.createProducer(queue);
          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(queue);

          TextMessage rm1 = (TextMessage)cons1.receive(1500);
          assertNotNull(rm1);
          assertEquals("hello1", rm1.getText());

          cons1.close();

          //Cancelling is asynch so can take some time
          Thread.sleep(500);
         
          //rollback should cause redelivery of messages

          //in this case redelivery occurs to a different receiver

          sess.rollback();

          MessageConsumer cons2 = sess.createConsumer(queue);

          TextMessage rm2 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm2);
          assertEquals("hello1", rm2.getText());

          TextMessage rm3 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm3);
          assertEquals("hello2", rm3.getText());

          TextMessage rm4 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm4);
          assertEquals("hello3", rm4.getText());

          //This last step is important - there shouldn't be any more messages to receive
          TextMessage rm5 = (TextMessage)cons2.receive(1500);
          assertNull(rm5);


       }
       finally
       {
          if (conn != null)
          {
             conn.close();
          }
       }
    }


    public void testRedel5() throws Exception
    {
       Connection conn = null;

       try
       {
          conn = cf.createConnection();
          conn.start();

          Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
          MessageProducer prod = sess.createProducer(queue);
          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(queue);

          TextMessage rm1 = (TextMessage)cons1.receive(1500);
          assertNotNull(rm1);
          assertEquals("hello1", rm1.getText());

          //redeliver
          sess.recover();

          TextMessage rm2 = (TextMessage)cons1.receive(1500);
          assertNotNull(rm2);
          assertEquals("hello1", rm2.getText());

          TextMessage rm3 = (TextMessage)cons1.receive(1500);
          assertNotNull(rm3);
          assertEquals("hello2", rm3.getText());

          TextMessage rm4 = (TextMessage)cons1.receive(1500);
          assertNotNull(rm4);
          assertEquals("hello3", rm4.getText());


          //This last step is important - there shouldn't be any more messages to receive
          TextMessage rm5 = (TextMessage)cons1.receive(1500);
          assertNull(rm5);
       }
       finally
       {
          if (conn != null)
          {
             conn.close();
          }
       }
    }

    public void testRedel6() throws Exception
    {
       Connection conn = null;

       try
       {
          conn = cf.createConnection();
          conn.start();

          Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
          MessageProducer prod = sess.createProducer(queue);
          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(queue);

          TextMessage rm1 = (TextMessage)cons1.receive(1500);
          assertNotNull(rm1);
          assertEquals("hello1", rm1.getText());

          cons1.close();
 
          //Give time for asynch cancel to happen
          Thread.sleep(500);

          log.debug("sess.recover()");

          //redeliver
          sess.recover();

          MessageConsumer cons2 = sess.createConsumer(queue);

          log.debug("receiving ...");

          TextMessage rm2 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm2);
          assertEquals("hello1", rm2.getText());

          TextMessage rm3 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm3);
          assertEquals("hello2", rm3.getText());

          TextMessage rm4 = (TextMessage)cons2.receive(1500);
          assertNotNull(rm4);
          assertEquals("hello3", rm4.getText());


          //This last step is important - there shouldn't be any more messages to receive
          TextMessage rm5 = (TextMessage)cons2.receive(1500);
          assertNull(rm5);


       }
       finally
       {
          if (conn != null)
          {
             conn.close();
          }
       }

    }

   /**
    * http://www.jboss.org/index.html?module=bb&op=viewtopic&t=71350
    */
   public void testRedel7() throws Exception
   {
      Connection conn = null;

       try
       {
          conn = cf.createConnection();
          conn.start();

          Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);

          MessageProducer prod = sess.createProducer(queue);
         
          TextMessage tm1 = sess.createTextMessage("1");
         
          TextMessage tm2 = sess.createTextMessage("2");
         
          TextMessage tm3 = sess.createTextMessage("3");
         
          prod.send(tm1);
          prod.send(tm2);
          prod.send(tm3);

          log.trace("Creating consumer");
          MessageConsumer cons1 = sess.createConsumer(queue);

          log.trace("Waiting for message");
         
          TextMessage r1 = (TextMessage)cons1.receive();
         
          assertEquals(tm1.getText(), r1.getText());

          log.trace("Got first message");

          cons1.close();

          log.trace("Closed consumer");

          MessageConsumer cons2 = sess.createConsumer(queue);

          log.trace("Waiting for second message");
          TextMessage r2 = (TextMessage)cons2.receive();
         
          assertEquals(tm2.getText(), r2.getText());

          log.trace("got second message");

          TextMessage r3 = (TextMessage)cons2.receive();
         
          assertEquals(tm3.getText(), r3.getText());

          r1.acknowledge();
          r2.acknowledge();
          r3.acknowledge();
       }
       finally
       {
          if (conn != null)
          {
             conn.close();
          }
       }
   }

   /**
    * http://www.jboss.org/index.html?module=bb&op=viewtopic&t=71350
    */
   public void testRedel8() throws Exception
   {
      Connection conn = null;

       try
       {
          conn = cf.createConnection();

          Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

          MessageProducer prod = sess.createProducer(queue);

          //Send 3 messages

          prod.send(sess.createTextMessage("1"));
          prod.send(sess.createTextMessage("2"));
          prod.send(sess.createTextMessage("3"));
         
          log.trace("Sent messages");

          conn.start();

          MessageConsumer cons1 = sess.createConsumer(queue);

          log.trace("closing cons1");

          cons1.close();

          log.trace("cons1 closed");

          MessageConsumer cons2 = sess.createConsumer(queue);

          log.trace("cons2 created");

          Message r1 = cons2.receive();
          Message r2 = cons2.receive();
          Message r3 = cons2.receive();

          //Messages should be received?
          assertNotNull(r1);
          assertNotNull(r2);
          assertNotNull(r3);
       }
       finally
       {
          if (conn != null)
          {
             conn.close();
          }
       }
   }


   /**
    * Test server-side consumer delegate activation (on receive())
    */
// This test is not valid since the message will be in the first consumer, not c2


//   public void testReceive1() throws Exception
//   {
//      Connection conn = null;
//
//       try
//       {
//          conn = cf.createConnection();
//
//          Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
//
//          s.createConsumer(queue);
//
//          conn.start();
//
//          MessageProducer p = s.createProducer(queue);
//          Message m = s.createTextMessage("1");
//          p.send(m);
//
//          MessageConsumer c2 = s.createConsumer(queue);
//
//          // TODO the test should be modified to deal with the multiple consumer receive undeterminism
//
//          Message r = c2.receive(2000);
//
//
//          assertEquals(m.getJMSMessageID(), r.getJMSMessageID());
//       }
//       finally
//       {
//          if (conn != null)
//          {
//             conn.close();
//          }
//       }
//   }

   /**
    * Test server-side consumer delegate activation (on receive())
    */

   //This test is not valid since the message will be in the first consumer, not c2

//   public void testReceive2() throws Exception
//   {
//      Connection conn = null;
//
//       try
//       {
//          conn = cf.createConnection();
//
//          Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
//
//          s.createConsumer(queue);
//
//          conn.start();
//
//          MessageProducer p = s.createProducer(queue);
//          Message m = s.createTextMessage("1");
//          p.send(m);
//
//          MessageConsumer c2 = s.createConsumer(queue);
//          final Set received = new HashSet();
//
//          // TODO the test should be modified to deal with the multiple consumer receive undeterminism
//
//          class Listener implements MessageListener
//          {
//             Latch latch = new Latch();
//
//             public void onMessage(Message m)
//             {
//                received.add(m);
//                latch.release();
//             }
//          }
//
//          Listener list = new Listener();
//          c2.setMessageListener(list);
//
//          list.latch.acquire();
//          assertEquals(1, received.size());
//          Message r = (Message)received.iterator().next();
//          assertEquals(m.getJMSMessageID(), r.getJMSMessageID());
//
//       }
//       finally
//       {
//          if (conn != null)
//          {
//             conn.close();
//          }
//       }
//   }


   public void testSendAndReceivePersistentDifferentConnections() throws Exception
   {
      Connection connSend = null;
      Connection connReceive = null;

      try
      {

         log.trace("Running testSendAndReceivePersistentDifferentConnections");

         connSend = cf.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(queue2, m);

         sessSend.commit();

         connReceive = cf.createConnection();

         connReceive.start();

         Session sessReceive = connReceive.createSession(true, Session.SESSION_TRANSACTED);

         MessageConsumer cons = sessReceive.createConsumer(queue2);

         TextMessage m2 = (TextMessage)cons.receive(1500);

         assertNotNull(m2);

         assertEquals("hello", m2.getText());

         sessReceive.commit();

         cons.close();


         connReceive = cf.createConnection();

         connReceive.start();

         sessReceive = connReceive.createSession(true, Session.SESSION_TRANSACTED);

         cons = sessReceive.createConsumer(queue2);

         TextMessage m3 = (TextMessage)cons.receive(1500);

         assertNull(m3);


         log.trace("Done test");

      }
      finally
      {
         if (connSend != null) connSend.close();
         if (connReceive != null) connReceive.close();
      }
   }


   /**
    * TODO Get rid of this (http://jira.jboss.org/jira/browse/JBMESSAGING-92)
    */

   //This test is no longer valid since we only use one listener per connection now

//   public void testRemotingInternals() throws Exception
//   {
//      if (ServerManagement.isRemote())
//      {
//         return;
//      }
//
//      Connector serverConnector = ServerManagement.getConnector();
//      ServerInvoker serverInvoker = serverConnector.getServerInvoker();
//
//      JMSServerInvocationHandler invocationHandler =
//            (JMSServerInvocationHandler)serverInvoker.getInvocationHandler("JMS");
//
//      Collection listeners = invocationHandler.getListeners();
//
//      assertEquals(3, listeners.size());  // topicConsumer's and queueConsumer's
//
//      MessageConsumer c = consumerSession.createConsumer(queue);
//
//      listeners = invocationHandler.getListeners();
//      assertEquals(4, listeners.size());
//
//      c.close();
//
//      listeners = invocationHandler.getListeners();
//      assertEquals(3, listeners.size());
//   }

   public void testMultipleConcurrentConsumers() throws Exception
   {
      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(topic);
      MessageConsumer cons2 = sess2.createConsumer(topic);
      MessageConsumer cons3 = sess3.createConsumer(topic);

      final int NUM_MESSAGES = 100;

      class Receiver implements Runnable
      {
         Receiver(MessageConsumer c1)
         {
            cons = c1;
         }
         MessageConsumer cons;
         boolean failed;
         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;
                  }
                  log.trace("received message");
                  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(topic);
      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();
      t2.join();
      t3.join();

      sess1.close();
      sess2.close();
      sess3.close();
      prodSession.close();

      assertTrue(!rec1.failed);
      assertTrue(!rec2.failed);
      assertTrue(!rec3.failed);
   }



   public void testGetSelector() throws Exception
   {
      String selector = "JMSType = 'something'";
      topicConsumer = consumerSession.createConsumer(topic, selector);
      assertEquals(selector, topicConsumer.getMessageSelector());
   }

   public void testGetSelectorOnClosedConsumer() throws Exception
   {
      topicConsumer.close();

      try
      {
         topicConsumer.getMessageSelector();
      }
      catch(javax.jms.IllegalStateException e)
      {
         // OK
      }
   }


   public void testGetTopic() throws Exception
   {
      Topic t = ((TopicSubscriber)topicConsumer).getTopic();
      assertEquals(topic, t);
   }

   public void testGetTopicOnClosedConsumer() throws Exception
   {
      topicConsumer.close();

      try
      {
         ((TopicSubscriber)topicConsumer).getTopic();
      }
      catch(javax.jms.IllegalStateException e)
      {
         // OK
      }
   }


   public void testGetQueue() throws Exception
   {
      Queue q = ((QueueReceiver)queueConsumer).getQueue();
      assertEquals(queue, q);
   }

   public void testGetQueueOnClosedConsumer() throws Exception
   {
      queueConsumer.close();

      try
      {
         ((QueueReceiver)queueConsumer).getQueue();
      }
      catch(javax.jms.IllegalStateException e)
      {
         // OK
      }
   }


   public void testReceiveOnTopicTimeoutNoMessage() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testReceiveOnTopicTimeoutNoMessage");
      Message m = topicConsumer.receive(1000);
      assertNull(m);
   }

   public void testReceiveOnTopicConnectionStopped() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testReceiveOnTopicConnectionStopped");
      consumerConnection.stop();

      final Message m = producerSession.createMessage();
      new Thread(new Runnable()
      {
         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();

      assertNull(topicConsumer.receive(1500));
   }


   public void testReceiveOnTopicTimeout() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testReceiveOnTopicTimeout");
      consumerConnection.start();

      final Message m1 = producerSession.createMessage();
      new Thread(new Runnable()
      {
         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);
      assertEquals(m1.getJMSMessageID(), m2.getJMSMessageID());
   }


   public void testReceiveOnTopic() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testReceiveOnTopic");
      consumerConnection.start();

      final Message m1 = producerSession.createMessage();
      new Thread(new Runnable()
      {
         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);

      if (log.isTraceEnabled()) log.trace("m1:" + m1 + ", m2:" + m2) ;

      assertEquals(m1.getJMSMessageID(), m2.getJMSMessageID());
   }



   public void testReceiveNoWaitOnTopic() throws Exception
   {
      consumerConnection.start();

      Message m = topicConsumer.receiveNoWait();

      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();

      assertEquals(m1.getJMSMessageID(), m.getJMSMessageID());
   }




   /**
    * The test sends a burst of messages and verifies if the consumer receives all of them.
    */


   public void testStressReceiveOnQueue() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testStressReceiveOnQueue");
      final int count = 100;

      consumerConnection.start();

      new Thread(new Runnable()
      {
         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();
                  queueProducer.send(m);
               }
            }
            catch(Exception e)
            {
               log.error(e);
            }
         }
      }, "ProducerTestThread").start();

      int received = 0;
      while(true)
      {
         Message m = queueConsumer.receive(1500);
         if (m == null)
         {
            break;
         }
         //Thread.sleep(1000);
         received++;
      }

      assertEquals(count, received);

   }


   /**
    * The test sends a burst of messages and verifies if the consumer receives all of them.
    */




   public void testStressReceiveOnTopic() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testStressReceiveOnTopic");
      final int count = 1000;

      consumerConnection.start();

      new Thread(new Runnable()
      {
         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();

      int received = 0;
      while(true)
      {
         Message m = topicConsumer.receive(1500);
         if (m == null)
         {
            break;
         }
         //Thread.sleep(1000);
         received++;
      }

      assertEquals(count, received);

   }



   public void testReceiveOnClose() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testReceiveOnClose");
      consumerConnection.start();
      final Latch latch = new Latch();
      Thread closerThread = new Thread(new Runnable()
      {
         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.release();
            }
         }
      }, "closing thread");
      closerThread.start();

      assertNull(topicConsumer.receive(3000));

      // wait for the closing thread to finish
      latch.acquire();
   }

    /** to be used by testTimeoutReceiveOnClose */
     private class ThreadCloser extends Thread
     {

         Object waitMonitor;
         long timeToSleep;

         public ThreadCloser( Object waitMonitor, long timeToSleep)
         {
             this.waitMonitor=waitMonitor;
             this.timeToSleep=timeToSleep;
         }


         public void run()
         {
             try
             {
                 log.info("(ThreadCloser)Waiting on monitor to close thread");
                 synchronized (waitMonitor)
                 {
                     waitMonitor.wait();
                 }
                 log.info("(ThreadCloser)Notification received");
                 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;
         Object waitMonitor;
         long t1;
         long t2;
         Object receivedObject;

         public ThreadReceiver(Object waitMonitor, long timeToWait)
         {
             this.waitMonitor=waitMonitor;
             this.timeToWait=timeToWait;
         }

         public void run()
         {
             try
             {
                 log.info("(ThreadReceiver)Waiting on monitor to close thread");
                 synchronized(waitMonitor)
                 {
                     waitMonitor.wait();
                 }
                 log.info("(ThreadReceiver)Notification received");
                 t1=System.currentTimeMillis();
                 receivedObject=topicConsumer.receive(timeToWait);
                 t2=System.currentTimeMillis();

             }
             catch (Exception e)
             {
                 log.error(e);
                 e.printStackTrace();
             }
         }
     }

    public void testTimeoutReceiveOnClose() throws Exception
    {
       System.gc();       /// If A GC need to be executed, it' s better to be executed now
       Thread.sleep(1000);
       if (log.isTraceEnabled()) log.trace("testTimeoutReceiveOnClose");

       Object monitor = new Object();
       ThreadCloser closer = null;
       ThreadReceiver receiver = new ThreadReceiver(monitor,2000);

       closer = new ThreadCloser(monitor,1000);
       receiver= new ThreadReceiver(monitor,2000);
       closer.start();
       receiver.start();
       Thread.sleep(2000);
       synchronized (monitor)
       {
          monitor.notifyAll();
       }
       closer.join();
       receiver.join();


       assertNull(receiver.receivedObject);

       log.info("Elapsed time was " + (receiver.t2-receiver.t1));

       // We need to make sure the
       assertTrue("Receive was supposed to receive a notification before 2 seconds",receiver.t2-receiver.t1<=1500);
    }

   //
   // MessageListener tests
   //

   public void testMessageListenerOnTopic() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testMessageListenerOnTopic");

      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();

      assertEquals(m1.getJMSMessageID(), l.getNextMessage().getJMSMessageID());
   }


////   TODO: enable this
////   public void testMessageListenerOnTopicMultipleMessages() throws Exception
////   {
////      log.debug("testMessageListenerOnTopicMultipleMessages");
////
////      MessageListenerImpl l = new MessageListenerImpl();
////      topicConsumer.setMessageListener(l);
////
////      consumerConnection.start();
////
////      int NUM_MESSAGES = 10;
////      for(int i = 0; i < NUM_MESSAGES; i++)
////      {
////         TextMessage m = producerSession.createTextMessage("body" + i);
////         topicProducer.send(m);
////      }
////
////      for(int i = 0; i < NUM_MESSAGES; i++)
////      {
////         l.waitForMessages();
////         log.trace("got message " + i);
////      }
////
////
////      int counter = 0;
////      for(Iterator i = l.getMessages().iterator(); i.hasNext(); counter++)
////      {
////         TextMessage m = (TextMessage)i.next();
////         assertEquals("body" + counter, m.getText());
////      }
////
////      log.debug("testMessageListenerOnTopicMultipleMessages done");
////   }
//
////   TODO: enable this
////   public void testMessageListenerOnQueueMultipleMessages() throws Exception
////   {
////      log.debug("testMessageListenerOnQueueMultipleMessages");
////
////      MessageListenerImpl l = new MessageListenerImpl();
////      QueueConsumer.setMessageListener(l);
////
////      consumerConnection.start();
////
////      int NUM_MESSAGES = 10;
////      for(int i = 0; i < NUM_MESSAGES; i++)
////      {
////         TextMessage m = producerSession.createTextMessage("body" + i);
////         queueProducer.send(m);
////      }
////
////      for(int i = 0; i < NUM_MESSAGES; i++)
////      {
////         l.waitForMessages();
////         log.trace("got message " + i);
////      }
////
////
////      int counter = 0;
////      for(Iterator i = l.getMessages().iterator(); i.hasNext(); counter++)
////      {
////         TextMessage m = (TextMessage)i.next();
////         assertEquals("body" + counter, m.getText());
////      }
////
////      log.debug("testMessageListenerOnTopicMultipleMessages done");
////   }


   public void testSetMessageListenerTwice() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testSetMessageListenerTwice");
      MessageListenerImpl listener1 = new MessageListenerImpl();

      topicConsumer.setMessageListener(listener1);
      log.trace("Set message listener1");

      MessageListenerImpl listener2 = new MessageListenerImpl();

      topicConsumer.setMessageListener(listener2);
      log.trace("Set message 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
      //log.trace("Waiting for messages....");

      listener2.waitForMessages();

      assertEquals(m1.getJMSMessageID(), listener2.getNextMessage().getJMSMessageID());
      assertEquals(0, listener1.size());
   }

   public void testSetMessageListenerWhileReceiving() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testSetMessageListenerWhileReceiving");
      consumerConnection.start();
      worker1= new Thread(new Runnable()
      {
         public void run()
         {
            try
            {
               topicConsumer.receive(3000);
            }
            catch(Exception e)
            {
               e.printStackTrace();
            }
         }}, "Receiver");

      worker1.start();

      Thread.sleep(1000);

      try
      {
         topicConsumer.setMessageListener(new MessageListenerImpl());
         fail("should have thrown JMSException");
      }
      catch(JMSException e)
      {
          // ok
         log.trace(e.getMessage());
      }
   }


   //
   // Multiple consumers
   //

   public void testTwoConsumersNonTransacted() throws Exception
   {

      consumerSession.close();

      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 = cf.createConnection();
      consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      queueConsumer = consumerSession.createConsumer(queue);
      consumerConnection.start();

      TextMessage m = (TextMessage)queueConsumer.receive(1500);
      assertEquals("One", m.getText());

      consumerConnection.close();

      // recreate the connection and receive the second message
      consumerConnection = cf.createConnection();
      consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      queueConsumer = consumerSession.createConsumer(queue);
      consumerConnection.start();

      m = (TextMessage)queueConsumer.receive(1500);
      assertEquals("Two", m.getText());

      consumerConnection.close();
   }

   public void testTwoConsumersTransacted() throws Exception
   {

      consumerSession.close();

      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 = cf.createConnection();
      consumerSession = consumerConnection.createSession(true, -1);
      queueConsumer = consumerSession.createConsumer(queue);
      consumerConnection.start();

      TextMessage m = (TextMessage)queueConsumer.receive(1500);
      assertEquals("One", m.getText());

      consumerSession.commit();
      consumerConnection.close();

      // recreate the connection and receive the second message
      consumerConnection = cf.createConnection();
      consumerSession = consumerConnection.createSession(true, -1);
      queueConsumer = consumerSession.createConsumer(queue);
      consumerConnection.start();

      m = (TextMessage)queueConsumer.receive(1500);
      assertEquals("Two", m.getText());

      consumerConnection.close();
   }

   //
   // NoLocal
   //

   public void testNoLocal() throws Exception
   {
      if (log.isTraceEnabled()) log.trace("testNoLocal");

      Connection conn1 = null;
      Connection conn2 = null;

      try
      {

         conn1 = cf.createConnection();
         Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);

         MessageProducer producer1 = sess1.createProducer(topic);
         producer1.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
         MessageConsumer consumer1 = sess1.createConsumer(topic, null, true);

         conn2 = cf.createConnection();

         Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
         assertEquals(Session.AUTO_ACKNOWLEDGE, sess2.getAcknowledgeMode());
         MessageConsumer consumer2 = sess2.createConsumer(topic, null, true);

         // we need different session because we cannot access the same session from different
         // threads
         Session sess3 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
         assertEquals(Session.AUTO_ACKNOWLEDGE, sess3.getAcknowledgeMode());
         MessageConsumer consumer3 = sess3.createConsumer(topic, null, true);

         //Consumer 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(MessageConsumer consumer)
            {
               this.consumer = consumer;
            }

            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();

         assertTrue(!tr1.exceptionThrown);
         assertTrue(!tr2.exceptionThrown);
         assertTrue(!tr3.exceptionThrown);

         assertNull(tr1.m);

         assertNotNull(tr2.m);
         assertNotNull(tr3.m);

      }
      finally
      {
         if (conn1 != null)
         {
            conn1.close();
         }
         if (conn2 != null)
         {
            conn2.close();
         }
      }

   }






   /*
    *
    * Also see JMS 1.1 Spec. 6.12
    */
   public void testTopicRedelivery() throws Exception
   {
      Connection conn1 = null;

      try
      {

         conn1 = cf.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);


         log.trace("careting consumer1");
         MessageConsumer cons1 = sess1.createConsumer(topic);

         log.trace("creating consumer2");
         MessageConsumer cons2 = sess2.createConsumer(topic);

         log.trace("starting connection");

         conn1.start();

         log.trace("started connection");

         Session sess3 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer prod = sess3.createProducer(topic);
         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);

         assertNotNull(tm1);
         assertNotNull(tm2);
         assertEquals("nurse!", tm1.getText());
         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);
         assertNotNull(tm2);
         assertEquals("nurse!", tm2.getText());


         //but tm1 should not be redelivered
         tm1 = (TextMessage)cons1.receive(1500);
         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

   */
   public void testNoRedeliveryOnNonDurableSubscriber() throws Exception
   {
      Connection conn1 = null;
      Connection conn2 = null;

      try
      {

         conn1 = cf.createConnection();
         conn1.start();

         Session sess1 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
         MessageProducer prod = sess1.createProducer(topic);
         prod.setDeliveryMode(DeliveryMode.PERSISTENT);

         final int NUM_MESSAGES = 1;

         MessageConsumer cons = sess1.createConsumer(topic);

         for (int i = 0; i < NUM_MESSAGES; i++)
         {
            TextMessage tm = sess1.createTextMessage("helloxyz");
            prod.send(topic, tm);
         }

         //receive but don't ack

         int count = 0;
         while (true)
         {
            TextMessage tm = (TextMessage)cons.receive(1000);
            if (tm == null) break;
            assertEquals(tm.getText(), "helloxyz");
            count++;
         }
         assertEquals(NUM_MESSAGES, count);

         conn1.close();

         conn2 = cf.createConnection();
         conn2.start();

         Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);

         MessageConsumer cons2 = sess2.createConsumer(topic);
         Message m = cons2.receive(1500);
         assertNull(m);

         conn2.close();
      }
      finally
      {
         if (conn1 != null)
         {
            conn1.close();
         }
         if (conn2 != null)
         {
            conn2.close();
         }
      }


   }

   //Check messages have correct type after being resurrected from persistent storage
   public void testPersistedMessageType() throws Exception
   {
      Connection theConn = null;
      Connection theOtherConn = null;

      try
      {
         theConn = cf.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(queue2);
         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 = cf.createConnection();
         theOtherConn.start();

         Session sessReceive = theOtherConn.createSession(false, Session.AUTO_ACKNOWLEDGE);

         MessageConsumer theConsumer = sessReceive.createConsumer(queue2);

         Message m2 = theConsumer.receive(1500);

         log.trace("m2 is " + m2);

         assertNotNull(m2);

         assertEquals("aardvark", m2.getStringProperty("p1"));

         BytesMessage bm2 = (BytesMessage)theConsumer.receive(1500);
         assertEquals("aardvark", bm2.readUTF());

         MapMessage mm2 = (MapMessage)theConsumer.receive(1500);
         assertEquals("aardvark", mm2.getString("s1"));

         ObjectMessage om2 = (ObjectMessage)theConsumer.receive(1500);
         assertEquals("aardvark", (String)om2.getObject());

         StreamMessage sm2 = (StreamMessage)theConsumer.receive(1500);
         assertEquals("aardvark", sm2.readString());
      }
      finally
      {
         if (theConn != null)
         {
            theConn.close();
         }
         if (theOtherConn != null)
         {
            theOtherConn.close();
         }
      }


   }




   public void testDurableSubscriptionSimple() throws Exception
   {
      final String CLIENT_ID1 = "test-client-id1";

      Connection conn1 = null;

      try
      {
         conn1 = cf.createConnection();

         conn1.setClientID(CLIENT_ID1);

         Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer prod = sess1.createProducer(topic);
         prod.setDeliveryMode(DeliveryMode.PERSISTENT);

         MessageConsumer durable = sess1.createDurableSubscriber(topic, "mySubscription");

         conn1.start();

         final int NUM_MESSAGES = 50;

         for (int i = 0; i < NUM_MESSAGES; i++)
         {
            TextMessage tm = sess1.createTextMessage("hello");
            prod.send(topic, tm);
         }

         int count = 0;
         while (true)
         {
            TextMessage tm = (TextMessage)durable.receive(1500);
            if (tm == null)
            {
               break;
            }
            count++;
         }

         assertEquals(NUM_MESSAGES, count);

         durable.close();

         sess1.unsubscribe("mySubscription");
      }
      finally
      {
         if (conn1 != null)
         {
            conn1.close();
         }
      }

   }


   public void testDurableSubscriptionMultipleSubscriptions() throws Exception
   {
      final String CLIENT_ID1 = "test-client-id1";

      Connection conn1 = null;
      Connection conn2 = null;

      try
      {

         conn1 = cf.createConnection();

         conn1.setClientID(CLIENT_ID1);

         Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);

         log.debug("creating first durable subscription");
         sess1.createDurableSubscriber(topic, "mySubscription1");

         log.debug("creating the second durable subscription");
         sess1.createDurableSubscriber(topic, "mySubscription2");

         log.debug("closing conn1");
         conn1.close();

         conn2 = cf.createConnection();
         conn2.setClientID(CLIENT_ID1);

         Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer producer = sess2.createProducer(topic);
         producer.setDeliveryMode(DeliveryMode.PERSISTENT);

         final int NUM_MESSAGES = 50;

         log.debug("sending messages");

         for (int i = 0; i < NUM_MESSAGES; i++)
         {
            TextMessage tm = sess2.createTextMessage("hello");
            producer.send(tm);
         }

         log.debug("all " + NUM_MESSAGES + " messages sent");

         sess2.unsubscribe("mySubscription1");

         log.debug("unsubscribed 'mySubscription1'");

         conn2.close();

         Connection conn3 = cf.createConnection();
         conn3.setClientID(CLIENT_ID1);
         conn3.start();
         Session sess3 = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageConsumer durable3 = sess3.createDurableSubscriber(topic, "mySubscription2");

         int count = 0;
         while (true)
         {
            TextMessage tm = (TextMessage)durable3.receive(1000);
            if (tm == null)
            {
               break;
            }
            assertEquals("hello", tm.getText());
            count++;
         }

         assertEquals(NUM_MESSAGES, count);

         log.debug("received " + NUM_MESSAGES + " messages");

         MessageConsumer durable4 = sess3.createDurableSubscriber(topic, "mySubscription1");

         Message m = durable4.receive(1000);
         assertNull(m);
        
         conn3.close();

      }
      finally
      {
         if (conn1 != null)
         {
            conn1.close();
         }
         if (conn2 != null)
         {
            conn2.close();
         }
      }

   }



   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 = cf.createConnection();
         conn1.setClientID(CLIENT_ID1);
         sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageConsumer durable = sess1.createDurableSubscriber(topic, "mySubscription");
         conn1.close();


         // Send some messages on another connection and close it
         conn2 = cf.createConnection();
         conn2.setClientID(CLIENT_ID1);
         Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer prod2 = sess2.createProducer(topic);
         prod2.setDeliveryMode(DeliveryMode.PERSISTENT);
         final int NUM_MESSAGES = 10;
         for (int i = 0; i < NUM_MESSAGES; i++)
         {
            TextMessage tm = sess2.createTextMessage("hello");
            prod2.send(topic, tm);
         }
         conn2.close();

         // Receive the messages on another connection
         conn3 = cf.createConnection();
         conn3.setClientID(CLIENT_ID1);
         conn3.start();
         sess3 = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
         durable = sess3.createDurableSubscriber(topic, "mySubscription");
         int count = 0;
         while (true)
         {
            TextMessage tm = (TextMessage)durable.receive(1000);
            if (tm == null)
            {
               break;
            }
            assertEquals("hello", tm.getText());
            count++;
         }
         assertEquals(NUM_MESSAGES, count);
         conn3.close();

         // Try and receive them again
         conn4 = cf.createConnection();
         conn4.setClientID(CLIENT_ID1);
         conn4.start();
         sess4 = conn4.createSession(false, Session.AUTO_ACKNOWLEDGE);
         durable = sess4.createDurableSubscriber(topic, "mySubscription");

         TextMessage tm = (TextMessage)durable.receive(1000);
         assertNull(tm);
         conn4.close();

         // Send some more messages and unsubscribe
         conn5 = cf.createConnection();
         conn5.setClientID(CLIENT_ID1);
         conn5.start();
         Session sess5 = conn5.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer prod5 = sess5.createProducer(topic);
         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(topic, tm2);
         }

         log.debug("unsubscribing mySubscription");

         durable.close();
         sess5.unsubscribe("mySubscription");
         log.debug("unsubscribing done");
         conn5.close();

         // Resubscribe with the same name
         conn6 = cf.createConnection();
         conn6.setClientID(CLIENT_ID1);
         conn6.start();
         sess6 = conn6.createSession(false, Session.AUTO_ACKNOWLEDGE);
         durable = sess6.createDurableSubscriber(topic, "mySubscription");

         TextMessage tm3 = (TextMessage)durable.receive(1000);
         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();
         }
      }

   }


   public void testDurableSubscriptionReconnect() throws Exception
   {
      final String CLIENT_ID1 = "test-client-id1";

      Connection conn1 = null;
      Connection conn2 = null;

      try
      {
         conn1 = cf.createConnection();
         conn1.setClientID(CLIENT_ID1);

         Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer prod = sess1.createProducer(topic);
         prod.setDeliveryMode(DeliveryMode.PERSISTENT);

         log.debug("creating durable subscription");
         MessageConsumer durable = sess1.createDurableSubscriber(topic, "mySubscription");
         log.debug("durable subscription created");

         conn1.start();

         final int NUM_MESSAGES = 2;


         log.debug("sending messages ...");

         for (int i = 0; i < NUM_MESSAGES; i++)
         {
            TextMessage tm = sess1.createTextMessage("hello");
            prod.send(topic, tm);
         }

         final int NUM_TO_RECEIVE = NUM_MESSAGES - 1;

         log.debug("receiving messages ...");

         for (int i = 0; i < NUM_TO_RECEIVE; i++)
         {
            TextMessage tm = (TextMessage)durable.receive(3000);
            assertNotNull(tm);
         }

         // Close the connection
         conn1.close();
         conn1 = null;

         conn2 = cf.createConnection();

         conn2.setClientID(CLIENT_ID1);

         Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);

         // Re-subscribe to the subscription

         log.trace("resubscribing");

         MessageConsumer durable2 = sess2.createDurableSubscriber(topic, "mySubscription");

         conn2.start();

         int count = 0;
         while (true)
         {
            TextMessage tm = (TextMessage)durable2.receive(1500);
            if (tm == null)
            {
               break;
            }
            count++;
         }

         log.trace("Received " + count  + " messages");

         assertEquals(NUM_MESSAGES - NUM_TO_RECEIVE, count);

         durable2.close();

         sess2.unsubscribe("mySubscription");
      }
      finally
      {
         if (conn1 != null)
         {
            conn1.close();
         }
         if (conn2 != null)
         {
            conn2.close();
         }
      }


   }

   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 = cf.createConnection();

         conn1.setClientID(CLIENT_ID1);

         Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer prod = sess1.createProducer(topic);
         prod.setDeliveryMode(DeliveryMode.PERSISTENT);

         MessageConsumer durable = sess1.createDurableSubscriber(topic, "mySubscription");

         conn1.start();

         final int NUM_MESSAGES = 50;


         for (int i = 0; i < NUM_MESSAGES; i++)
         {
            TextMessage tm = sess1.createTextMessage("hello");
            prod.send(topic, 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)
            {
               fail();
            }
         }

         //Close the connection
         conn1.close();
         conn1 = null;

         conn2 = cf.createConnection();

         conn2.setClientID(CLIENT_ID2);

         Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);

         //Re-subscribe to the subscription
         MessageConsumer durable2 = sess2.createDurableSubscriber(topic, "mySubscription");

         conn2.start();

         int count = 0;
         while (true)
         {
            TextMessage tm = (TextMessage)durable2.receive(1500);
            if (tm == null)
            {
               break;
            }
            count++;
         }

         assertEquals(0, count);

         durable2.close();

         sess2.unsubscribe("mySubscription");
      }
      finally
      {
         if (conn1 != null)
         {
            conn1.close();
         }
         if (conn2 != null)
         {
            conn2.close();
         }
      }

   }



   public void testDurableSubscriptionInvalidUnsubscribe() throws Exception
   {
      final String CLIENT_ID1 = "test-client-id1";

      Connection conn1 = null;

      try
      {
         conn1 = cf.createConnection();


         conn1.setClientID(CLIENT_ID1);

         Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);

         try
         {
            sess1.unsubscribe("non-existent subscription");
            fail();
         }
         catch (JMSException e)
         {
         }
      }
      finally
      {
         if (conn1 != null)
         {
            conn1.close();
         }
      }
   }




   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 = cf.createConnection();

         assertNull(conn1.getClientID());

         Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);

         try
         {
            sess1.createDurableSubscriber(topic, "mySubscription");
            fail();
         }
         catch (JMSException e)
         {}

      }
      finally
      {
         if (conn1 != null)
         {
            conn1.close();
         }
      }
   }

   public void testRedeliveredDifferentSessions() throws Exception
   {
      producerSession.close();
      consumerSession.close();

      Session sessProducer = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      MessageProducer prod = sessProducer.createProducer(queue);
      TextMessage tm = sessProducer.createTextMessage("testRedeliveredDifferentSessions");
      prod.send(tm);

      consumerConnection.start();

      Session sess1 = consumerConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageConsumer cons1 = sess1.createConsumer(queue);
      TextMessage tm2 = (TextMessage)cons1.receive(3000);
     
      assertNotNull(tm2);
      assertEquals("testRedeliveredDifferentSessions", tm2.getText());

      //don't acknowledge it
      sess1.close();

      Session sess2 = consumerConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageConsumer cons2 = sess2.createConsumer(queue);
      TextMessage tm3 = (TextMessage)cons2.receive(3000);
     
      assertNotNull(tm3);
      assertEquals("testRedeliveredDifferentSessions", tm3.getText());
     
      assertTrue(tm3.getJMSRedelivered());
   }



   public void testRedelMessageListener1() throws Exception
   {
      Connection conn = cf.createConnection();

      conn.start();

      Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);

      MessageConsumer cons = sess.createConsumer(queue2);

      RedelMessageListenerImpl listener = new RedelMessageListenerImpl(false);
      listener.sess = sess;

      cons.setMessageListener(listener);

      MessageProducer prod = sess.createProducer(queue2);
      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
      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();

      conn.close();

      assertFalse(listener.failed);


   }


   public void testRedelMessageListener2() throws Exception
   {
      Connection conn = cf.createConnection();

      conn.start();

      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

      Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);

      MessageConsumer cons = sess.createConsumer(queue2);

      RedelMessageListenerImpl listener = new RedelMessageListenerImpl(true);
      listener.sess = sess;

      cons.setMessageListener(listener);

      MessageProducer prod = sessSend.createProducer(queue2);
      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();

      assertFalse(listener.failed);

      conn.close();

   }


   public void testExceptionMessageListener1() throws Exception
   {
      Connection conn = cf.createConnection();

      conn.start();

      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

      Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

      MessageConsumer cons = sess.createConsumer(queue2);

      ExceptionRedelMessageListenerImpl listener = new ExceptionRedelMessageListenerImpl(sess);

      cons.setMessageListener(listener);

      MessageProducer prod = sessSend.createProducer(queue2);
      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();

      assertFalse(listener.failed);

      conn.close();

   }

   public void testExceptionMessageListener2() throws Exception
   {
      Connection conn = cf.createConnection();

      conn.start();

      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

      Session sess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);

      MessageConsumer cons = sess.createConsumer(queue2);

      ExceptionRedelMessageListenerImpl listener = new ExceptionRedelMessageListenerImpl(sess);

      cons.setMessageListener(listener);

      MessageProducer prod = sessSend.createProducer(queue2);
      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();

      assertFalse(listener.failed);

      conn.close();

   }

   public void testExceptionMessageListener3() throws Exception
   {
      Connection conn = cf.createConnection();

      conn.start();

      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

      Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);

      MessageConsumer cons = sess.createConsumer(queue2);

      ExceptionRedelMessageListenerImpl listener = new ExceptionRedelMessageListenerImpl(sess);

      cons.setMessageListener(listener);

      MessageProducer prod = sessSend.createProducer(queue2);
      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();

      assertFalse(listener.failed);

      conn.close();

   }

   public void testExceptionMessageListener4() throws Exception
   {
      Connection conn = cf.createConnection();

      conn.start();

      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

      Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);

      MessageConsumer cons = sess.createConsumer(queue2);

      ExceptionRedelMessageListenerImpl listener = new ExceptionRedelMessageListenerImpl(sess);

      cons.setMessageListener(listener);

      MessageProducer prod = sessSend.createProducer(queue2);
      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();

      assertFalse(listener.failed);

      conn.close();

   }


   // Package protected ---------------------------------------------

   // Protected -----------------------------------------------------

   // Private -------------------------------------------------------

   // Inner classes -------------------------------------------------

   private class ExceptionRedelMessageListenerImpl implements MessageListener
   {
      private Latch latch = new Latch();

      private int count;

      private Session sess;

      private boolean failed;

      public void waitForMessages() throws InterruptedException
      {
         latch.acquire();
         //Thread.sleep(2000); //enough time for postdeliver to be called
      }

      public ExceptionRedelMessageListenerImpl(Session sess)
      {
         this.sess = sess;
      }

      public void onMessage(Message m)
      {
         TextMessage tm = (TextMessage)m;
         count++;

         log.info(this + " Got message:" + count);
        
         try
         {
            log.info(this + " message:" + tm.getText());
            if (count == 1)
            {
               if (!("a".equals(tm.getText())))
               {
                  log.info("Should be a but was " + tm.getText());
                  failed = true;
                  latch.release();
               }
               log.info("Throwing exception");
               throw new RuntimeException("Aardvark");
            }
            else if (count == 2)
            {
               log.info("ack mode:" + sess.getAcknowledgeMode());
               if (sess.getAcknowledgeMode() == Session.AUTO_ACKNOWLEDGE || sess.getAcknowledgeMode() == Session.DUPS_OK_ACKNOWLEDGE)
               {
                  //Message should be immediately redelivered
                  if (!("a".equals(tm.getText())))
                  {
                     log.info("Should be a but was " + tm.getText());
                     failed = true;
                     latch.release();
                  }
                  if (!tm.getJMSRedelivered())
                  {
                     failed = true;
                     latch.release();
                  }
               }
               else
               {
                  //Transacted or CLIENT_ACKNOWLEDGE - next message should be delivered
                  if (!("b".equals(tm.getText())))
                  {
                     log.info("Should be b but was " + tm.getText());
                     failed = true;
                     latch.release();
                  }
               }
            }
            else if (count == 3)
            {
               if (sess.getAcknowledgeMode() == Session.AUTO_ACKNOWLEDGE || sess.getAcknowledgeMode() == Session.DUPS_OK_ACKNOWLEDGE)
               {
                  if (!("b".equals(tm.getText())))
                  {
                     log.info("Should be b but was " + tm.getText());
                     failed = true;
                     latch.release();
                  }
               }
               else
               {
                  if (!("c".equals(tm.getText())))
                  {
                     log.info("Should be c but was " + tm.getText());
                     failed = true;
                     latch.release();
                  }
                  latch.release();
               }
            }

            else if (count == 4)
            {
               if (sess.getAcknowledgeMode() == Session.AUTO_ACKNOWLEDGE || sess.getAcknowledgeMode() == Session.DUPS_OK_ACKNOWLEDGE)
               {
                  if (!("c".equals(tm.getText())))
                  {
                     log.info("Should be c but was " + tm.getText());
                     failed = true;
                     latch.release();
                  }
                  latch.release();
               }
               else
               {
                  //Shouldn't get a 4th messge
                  failed = true;
                  latch.release();
               }
            }
         }
         catch (JMSException e)
         {
            failed = true;
            latch.release();
         }
      }
   }

   private class RedelMessageListenerImpl implements MessageListener
   {
      private Session sess;

      private int count;

      private boolean failed;

      private Latch latch = new Latch();

      private boolean transacted;

      public RedelMessageListenerImpl(boolean transacted)
      {
         this.transacted = transacted;
      }

      /** Blocks the calling thread until at least a message is received */
      public void waitForMessages() throws InterruptedException
      {
         latch.acquire();
         //Thread.sleep(2000); //enough time for postdeliver to be called
      }

      public void onMessage(Message m)
      {
         try
         {
            TextMessage tm = (TextMessage)m;

            log.trace("Got message:" + tm.getText() + " count is " + count);

            if (count == 0)
            {
               if (!("a".equals(tm.getText())))
               {
                  log.trace("Should be a but was " + tm.getText());
                  failed = true;
                  latch.release();
               }
               if (transacted)
               {
                  sess.rollback();
                  log.trace("rollback() called");
               }
               else
               {
                  log.trace("Calling recover");
                  sess.recover();
                  log.trace("recover() called");
               }
            }

            if (count == 1)
            {
               if (!("a".equals(tm.getText())))
               {
                  log.trace("Should be a but was " + tm.getText());
                  failed = true;
                  latch.release();
               }
               if (!tm.getJMSRedelivered())
               {
                  failed = true;
                  latch.release();
               }
            }
            if (count == 2)
            {
               if (!("b".equals(tm.getText())))
               {
                  log.trace("Should be b but was " + tm.getText());
                  failed = true;
                  latch.release();
               }
            }
            if (count == 3)
            {
               if (!("c".equals(tm.getText())))
               {
                  log.trace("Should be c but was " + tm.getText());
                  failed = true;
                  latch.release();
               }
               if (transacted)
               {
                  sess.commit();
               }
               else
               {
                  log.trace("Acknowledging session");
                  tm.acknowledge();
               }
               latch.release();
            }
            count++;
         }
         catch (JMSException e)
         {
            log.trace("Caught JMSException", e);
            failed = true;
            latch.release();
         }
      }
   }

   private class MessageListenerImpl implements MessageListener
   {
      private List messages = Collections.synchronizedList(new ArrayList());
      private Latch latch = new Latch();

      /** Blocks the calling thread until at least a message is received */
      public void waitForMessages() throws InterruptedException
      {
         latch.acquire();
         //Thread.sleep(2000); //enough time for postdeliver to be called
      }

      public void waitForMessages(long timeout) throws InterruptedException
      {
         boolean acquired = latch.attempt(timeout);
         if (!acquired)
         {
            log.trace("unsucessful latch aquire attemnpt");
         }
         //Thread.sleep(2000); //enough time for postdeliver to be called
      }


      public void onMessage(Message m)
      {
         messages.add(m);
         log.trace("Added message " + m + " to my list");

         latch.release();
         //latch = new Latch();
      };

      public Message getNextMessage()
      {
         Iterator i = messages.iterator();
         if (!i.hasNext())
         {
            return null;
         }
         Message m = (Message)i.next();
         i.remove();
         return m;
      }

      public List getMessages()
      {
         return messages;
      }

      public int size()
      {
         return messages.size();
      }

      public void clear()
      {
         messages.clear();
      }
   }
}
TOP

Related Classes of org.jboss.test.messaging.jms.MessageConsumerTest$MessageListenerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.