Package org.jboss.test.messaging.jms

Source Code of org.jboss.test.messaging.jms.AcknowledgementTest

/*
  * 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 javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.management.ObjectName;
import javax.naming.InitialContext;

import org.jboss.jms.client.JBossConnectionFactory;
import org.jboss.jms.client.JBossSession;
import org.jboss.jms.client.delegate.ClientSessionDelegate;
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:tim.fox@jboss.com">Tim Fox</a>
*
* $Id: AcknowledgementTest.java 2386 2007-02-21 18:07:44Z timfox $
*/
public class AcknowledgementTest extends MessagingTestCase
{
   // Constants -----------------------------------------------------

   // Static --------------------------------------------------------
  
   // Attributes ----------------------------------------------------

   protected InitialContext initialContext;
  
   protected JBossConnectionFactory cf;
   protected Destination queue;
   protected Topic topic;

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

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

   // TestCase overrides -------------------------------------------

   public void setUp() throws Exception
   {
      super.setUp();
      ServerManagement.start("all");
                 
      initialContext = new InitialContext(ServerManagement.getJNDIEnvironment());
      cf = (JBossConnectionFactory)initialContext.lookup("/ConnectionFactory");
                
      ServerManagement.undeployQueue("Queue");
      ServerManagement.deployQueue("Queue");
      ServerManagement.undeployTopic("Topic");
      ServerManagement.deployTopic("Topic");
      queue = (Destination)initialContext.lookup("/queue/Queue");
      topic = (Topic)initialContext.lookup("/topic/Topic");    
     
      drainDestination(cf, queue);

      log.debug("setup done");
   }

   public void tearDown() throws Exception
   {
      ServerManagement.undeployQueue("Queue");
      ServerManagement.undeployTopic("Topic");
     
      super.tearDown();
     
   }


   // Public --------------------------------------------------------
  
  
   /* Topics shouldn't hold on to messages if there are no subscribers */
   public void testPersistentMessagesForTopicDropped() throws Exception
   {
      TopicConnection conn = null;
     
      try
      {
         conn = cf.createTopicConnection();
         System.out.println("******   ClientID = " + conn.getClientID());
         TopicSession sess = conn.createTopicSession(true, 0);
         TopicPublisher pub = sess.createPublisher(topic);
         pub.setDeliveryMode(DeliveryMode.PERSISTENT);
        
         Message m = sess.createTextMessage("testing123");
         pub.publish(m);
         sess.commit();
        
         conn.close();
         conn = cf.createTopicConnection();
         conn.start();
        
         TopicSession newsess = conn.createTopicSession(true, 0);
         TopicSubscriber newcons = newsess.createSubscriber(topic);
        
         Message m2 = (Message)newcons.receive(200);
         assertNull(m2);
      }
      finally
      {
         if (conn != null)
         {
            conn.close();
         }
      }
   }
  
   /* Topics shouldn't hold on to messages when the non-durable subscribers close */
   public void testPersistentMessagesForTopicDropped2() throws Exception
   {
      TopicConnection conn = null;
     
      try
      {
         conn = cf.createTopicConnection();
         conn.start();
         TopicSession sess = conn.createTopicSession(true, 0);
         TopicPublisher pub = sess.createPublisher(topic);
         TopicSubscriber sub = sess.createSubscriber(topic);
         pub.setDeliveryMode(DeliveryMode.PERSISTENT);
        
         Message m = sess.createTextMessage("testing123");
         pub.publish(m);
         sess.commit();
        
         //receive but rollback
         TextMessage m2 = (TextMessage)sub.receive(3000);
               
         assertNotNull(m2);
         assertEquals("testing123", m2.getText());
        
         sess.rollback();
        
         conn.close();
         conn = cf.createTopicConnection();
         conn.start();
        
         TopicSession newsess = conn.createTopicSession(true, 0);
         TopicSubscriber newcons = newsess.createSubscriber(topic);
        
         Message m3 = (Message)newcons.receive(200);
         assertNull(m3);
      }
      finally
      {
         if (conn != null)
         {
            conn.close();
         }
      }
   }
  
   public void testRollbackRecover() throws Exception
   {
      TopicConnection conn = null;
     
      try
      {
         conn = cf.createTopicConnection();
         TopicSession sess = conn.createTopicSession(true, 0);
         TopicPublisher pub = sess.createPublisher(topic);
         TopicSubscriber cons = sess.createSubscriber(topic);
         conn.start();
        
         Message m = sess.createTextMessage("testing123");
         pub.publish(m);
         sess.commit();
        
         TextMessage m2 = (TextMessage)cons.receive(3000);
         assertNotNull(m2);
         assertEquals("testing123", m2.getText());
        
         sess.rollback();
        
         m2 = (TextMessage)cons.receive(3000);
         assertNotNull(m2);
         assertEquals("testing123", m2.getText());
        
         conn.close();
        
         conn = cf.createTopicConnection();
         conn.start();
        
         //test 2
        
         TopicSession newsess = conn.createTopicSession(true, 0);
         TopicPublisher newpub = newsess.createPublisher(topic);
         TopicSubscriber newcons = newsess.createSubscriber(topic);
        
         Message m3 = newsess.createTextMessage("testing456");
         newpub.publish(m3);
         newsess.commit();
        
         TextMessage m4 = (TextMessage)newcons.receive(3000);
         assertNotNull(m4);
         assertEquals("testing456", m4.getText());
        
         newsess.commit();
        
         newpub.publish(m3);
         newsess.commit();
        
         TextMessage m5 = (TextMessage)newcons.receive(3000);
         assertNotNull(m5);
         assertEquals("testing456", m5.getText());
        
         newsess.rollback();
        
         TextMessage m6 = (TextMessage)newcons.receive(3000);
         assertNotNull(m6);
         assertEquals("testing456", m6.getText());
        
         newsess.commit();
        
      }
      finally
      {
         if (conn != null)
         {
            conn.close();
         }
      }
   }
  
   public void testTransactionalAcknowledgement() throws Exception
   {

      Connection conn = cf.createConnection();

      Session producerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
      MessageProducer producer = producerSess.createProducer(queue);

      Session consumerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
      MessageConsumer consumer = consumerSess.createConsumer(queue);
      conn.start();

      final int NUM_MESSAGES = 20;

      //Send some messages
      for (int i = 0; i < NUM_MESSAGES; i++)
      {
         Message m = producerSess.createMessage();
         producer.send(m);
      }

      assertRemainingMessages(0);
     
      producerSess.rollback();
     
      //Send some messages
      for (int i = 0; i < NUM_MESSAGES; i++)
      {
         Message m = producerSess.createMessage();
         producer.send(m);
      }
      assertRemainingMessages(0);
     
      producerSess.commit();

      assertRemainingMessages(NUM_MESSAGES);

      log.trace("Sent messages");

      int count = 0;
      while (true)
      {
         Message m = consumer.receive(200);
         if (m == null) break;
         count++;
      }
     
      assertRemainingMessages(NUM_MESSAGES);

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

      assertEquals(count, NUM_MESSAGES);

      consumerSess.rollback();
     
      assertRemainingMessages(NUM_MESSAGES);

      log.trace("Session rollback called");

      Message m = null;

      int i = 0;
      for(; i < NUM_MESSAGES; i++)
      {
         m = consumer.receive();
         log.trace("Received message " + i);
 
      }
     
      assertRemainingMessages(NUM_MESSAGES);

      // if I don't receive enough messages, the test will timeout

      log.trace("Received " + i +  " messages after recover");
     
      consumerSess.commit();
     
      assertRemainingMessages(0);

      // make sure I don't receive anything else

      m = consumer.receive(200);
      assertNull(m);

      conn.close();

   }

  /**
   * Send some messages, don't acknowledge them and verify that they are re-sent on recovery.
   */
  public void testClientAcknowledgeNoAcknowledgement() throws Exception
   {
    Connection conn = cf.createConnection();

    Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    MessageProducer producer = producerSess.createProducer(queue);

    Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    MessageConsumer consumer = consumerSess.createConsumer(queue);
    conn.start();

    final int NUM_MESSAGES = 20;

    //Send some messages
    for (int i = 0; i < NUM_MESSAGES; i++)
    {
      Message m = producerSess.createMessage();
      producer.send(m);
    }
     
      assertRemainingMessages(NUM_MESSAGES);

    log.trace("Sent messages");

    int count = 0;
    while (true)
    {
      Message m = consumer.receive(200);
      if (m == null) break;
      count++;
    }
     
      assertRemainingMessages(NUM_MESSAGES);

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

    assertEquals(count, NUM_MESSAGES);

    consumerSess.recover();
     
      assertRemainingMessages(NUM_MESSAGES);

    log.trace("Session recover called");

      Message m = null;

      int i = 0;
      for(; i < NUM_MESSAGES; i++)
      {
         m = consumer.receive();
         log.trace("Received message " + i);

      }
     
      assertRemainingMessages(NUM_MESSAGES);

      // if I don't receive enough messages, the test will timeout

    log.trace("Received " + i +  " messages after recover");
     
      m.acknowledge();
     
      assertRemainingMessages(0);

      // make sure I don't receive anything else

      m = consumer.receive(200);
      assertNull(m);

    conn.close();

   }

 
 
  /**
   * Send some messages, acknowledge them individually and verify they are not resent after
    * recovery.
   */
  public void testIndividualClientAcknowledge() throws Exception
   {
   
    Connection conn = cf.createConnection();
      for (int i=0; i<20; i++) System.out.println("*******************************************");
      System.out.println("clientID = " + conn.getClientID());

      Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    MessageProducer producer = producerSess.createProducer(queue);
   
    Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    MessageConsumer consumer = consumerSess.createConsumer(queue);
    conn.start();
   
    final int NUM_MESSAGES = 20;
   
    for (int i = 0; i < NUM_MESSAGES; i++)
    {
      Message m = producerSess.createMessage();
      producer.send(m);
    }
     
      assertRemainingMessages(NUM_MESSAGES);
   
    log.trace("Sent " + NUM_MESSAGES + " messages");
   
    int count = 0;
    while (true)   
    {
      Message m = consumer.receive(200);
         log.trace("Received message " + m);
      if (m == null)
         {
            break;
         }
         log.trace("Acking session");
        
         assertRemainingMessages(NUM_MESSAGES - count);
        
      m.acknowledge();
        
         assertRemainingMessages(NUM_MESSAGES - (count + 1));
      count++;
    }

      assertRemainingMessages(0);
     
      assertEquals(NUM_MESSAGES, count);
      log.trace("received and acknowledged " + count +  " messages");

      Message m = consumer.receive(200);
    assertNull(m);
     
      log.trace("mesage is " + m);

      log.trace("calling session recover()");
    consumerSess.recover();
    log.trace("recover called");
   
    m = consumer.receive(200);
    assertNull(m);
   
    conn.close();
   
   }


  /**
   * Send some messages, acknowledge them once after all have been received verify they are not
    * resent after recovery
   */
  public void testBulkClientAcknowledge() throws Exception
   {

    Connection conn = cf.createConnection();

    Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    MessageProducer producer = producerSess.createProducer(queue);

    Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    MessageConsumer consumer = consumerSess.createConsumer(queue);
    conn.start();

    final int NUM_MESSAGES = 20;

    //Send some messages
    for (int i = 0; i < NUM_MESSAGES; i++)
    {
      Message m = producerSess.createMessage();
      producer.send(m);
    }
     
      assertRemainingMessages(NUM_MESSAGES);

    log.trace("Sent messages");

    Message m = null;
    int count = 0;
    for (int i = 0; i < NUM_MESSAGES; i++)
    {
      m = consumer.receive(200);
      if (m == null) break;
      count++;
    }
     
      assertRemainingMessages(NUM_MESSAGES);

    assertNotNull(m);

    m.acknowledge();
     
      assertRemainingMessages(0);

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

    assertEquals(count, NUM_MESSAGES);

    consumerSess.recover();

    log.trace("Session recover called");

    m = consumer.receive(200);

    log.trace("Message is:" + m);

    assertNull(m);

    conn.close();

   }


  /**
   * Send some messages, acknowledge some of them, and verify that the others are resent after
    * delivery
   */
  public void testPartialClientAcknowledge() throws Exception
   {

    Connection conn = cf.createConnection();

    Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    MessageProducer producer = producerSess.createProducer(queue);

    Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    MessageConsumer consumer = consumerSess.createConsumer(queue);
    conn.start();

    final int NUM_MESSAGES = 20;
    final int ACKED_MESSAGES = 11;

    //Send some messages
    for (int i = 0; i < NUM_MESSAGES; i++)
    {
      Message m = producerSess.createMessage();
      producer.send(m);
    }
     
      assertRemainingMessages(NUM_MESSAGES);

    log.trace("Sent messages");

    int count = 0;

    Message m = null;
    for (int i = 0; i < NUM_MESSAGES; i++)
    {
      m = consumer.receive(200);
      if (m == null)
         {
            break;
         }
      if (count == ACKED_MESSAGES -1)
         {
            m.acknowledge();
         }
      count++;
    }
     
      assertRemainingMessages(NUM_MESSAGES - ACKED_MESSAGES);
     
    assertNotNull(m);

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

    assertEquals(count, NUM_MESSAGES);

    consumerSess.recover();

    log.trace("Session recover called");

    count = 0;
    while (true)
    {
      m = consumer.receive(200);
      if (m == null) break;
      count++;
    }

    assertEquals(NUM_MESSAGES - ACKED_MESSAGES, count);           

    conn.close();

   }



  /*
   * Send some messages, consume them and verify the messages are not sent upon recovery
   *
   */
  public void testAutoAcknowledge() throws Exception
   {

    Connection conn = cf.createConnection();

    Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
    MessageProducer producer = producerSess.createProducer(queue);

    Session consumerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
    MessageConsumer consumer = consumerSess.createConsumer(queue);
    conn.start();

    final int NUM_MESSAGES = 20;

    //Send some messages
    for (int i = 0; i < NUM_MESSAGES; i++)
    {
      Message m = producerSess.createMessage();
      producer.send(m);
    }
     
      assertRemainingMessages(NUM_MESSAGES);

    log.trace("Sent messages");

    int count = 0;

    Message m = null;
    for (int i = 0; i < NUM_MESSAGES; i++)
    {
         assertRemainingMessages(NUM_MESSAGES - i);
        
      m = consumer.receive(200);
        
         assertRemainingMessages(NUM_MESSAGES - (i + 1));
        
      if (m == null) break;
      count++;
    }
     
      assertRemainingMessages(0);         

    assertNotNull(m);

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

    assertEquals(count, NUM_MESSAGES);

    consumerSess.recover();

    log.trace("Session recover called");

    m = consumer.receive(200);

    log.trace("Message is:" + m);

    assertNull(m);

    conn.close();

   }
  
   public void testDupsOKBatchDefault() throws Exception
   {
      //test default
      Connection conn = cf.createConnection();
     
      JBossSession sess = (JBossSession)conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
     
      ClientSessionDelegate del = (ClientSessionDelegate)sess.getDelegate();
     
      assertEquals(1000, del.getDupsOKBatchSize());
     
      conn.close();
   }
     
   public void testDupsOKAcknowledge() throws Exception
   {
     
      final int BATCH_SIZE = 10;
     
      String mbeanConfig =
         "<mbean code=\"org.jboss.jms.server.connectionfactory.ConnectionFactory\"\n" +
         "       name=\"jboss.messaging.destination:service=MyConnectionFactory\"\n" +
         "       xmbean-dd=\"xmdesc/ConnectionFactory-xmbean.xml\">\n" +
         "       <depends optional-attribute-name=\"ServerPeer\">jboss.messaging:service=ServerPeer</depends>\n" +
         "       <depends optional-attribute-name=\"Connector\">jboss.messaging:service=Connector,transport=bisocket</depends>\n" +
         "       <attribute name=\"JNDIBindings\">\n" +
         "          <bindings>\n" +
         "            <binding>/mycf</binding>\n" +
         "          </bindings>\n" +
         "       </attribute>\n" +
         "       <attribute name=\"DupsOKBatchSize\">" + BATCH_SIZE  + "</attribute>" +
         " </mbean>";

      ObjectName on = ServerManagement.deploy(mbeanConfig);
      ServerManagement.invoke(on, "create", new Object[0], new String[0]);
      ServerManagement.invoke(on, "start", new Object[0], new String[0]);
     
      ConnectionFactory myCF = (ConnectionFactory)initialContext.lookup("/mycf");
     
      Connection conn = myCF.createConnection();

      Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
      MessageProducer producer = producerSess.createProducer(queue);

      Session consumerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
      MessageConsumer consumer = consumerSess.createConsumer(queue);
      conn.start();

      //Send some messages
      for (int i = 0; i < 19; i++)
      {
         Message m = producerSess.createMessage();
         producer.send(m);
      }
     
      assertRemainingMessages(19);

      log.trace("Sent messages");

      Message m = null;
      for (int i = 0; i < 10; i++)
      {
         m = consumer.receive(200);
        
         assertNotNull(m);
         
         if (i == 9)
         {
            assertRemainingMessages(9);
         }
         else
         {
            assertRemainingMessages(19);
         }
      }
     
      for (int i = 0; i < 9; i++)
      {
         m = consumer.receive(200);
        
         assertNotNull(m);
        
         assertRemainingMessages(9);
      }
     
      //Make sure the last are acked on close
     
      consumerSess.close();
     
      assertRemainingMessages(0);
     
      conn.close();

   }


  /*
   * Send some messages, consume them and verify the messages are not sent upon recovery
   *
   */
  public void testLazyAcknowledge() throws Exception
   {

    Connection conn = cf.createConnection();

    Session producerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
    MessageProducer producer = producerSess.createProducer(queue);

    Session consumerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
    MessageConsumer consumer = consumerSess.createConsumer(queue);
    conn.start();

    final int NUM_MESSAGES = 20;

    //Send some messages
    for (int i = 0; i < NUM_MESSAGES; i++)
    {
      Message m = producerSess.createMessage();
      producer.send(m);
    }

      assertRemainingMessages(NUM_MESSAGES);
     
    log.trace("Sent messages");

    int count = 0;

    Message m = null;
    for (int i = 0; i < NUM_MESSAGES; i++)
    {
      m = consumer.receive(200);
      if (m == null) break;
      count++;
    }
     
    assertNotNull(m);
     
      assertRemainingMessages(NUM_MESSAGES);

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

    assertEquals(count, NUM_MESSAGES);

    consumerSess.recover();

    log.trace("Session recover called");

    m = consumer.receive(200);

    log.trace("Message is:" + m);

    assertNull(m);

    conn.close();

   }
  
   public void testMessageListenerAutoAck() throws Exception
   {
      Connection conn = cf.createConnection();
      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
      MessageProducer prod = sessSend.createProducer(queue);
      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
     
      log.trace("Sending messages");
     
      TextMessage tm1 = sessSend.createTextMessage("a");
      TextMessage tm2 = sessSend.createTextMessage("b");
      TextMessage tm3 = sessSend.createTextMessage("c");
      prod.send(tm1);
      prod.send(tm2);
      prod.send(tm3);
     
      log.trace("Sent messages");
     
      sessSend.close();
     
      assertRemainingMessages(3);
  
      conn.start();

      Session sessReceive = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
     
      log.trace("Creating consumer");
     
      MessageConsumer cons = sessReceive.createConsumer(queue);
     
      log.trace("Created consumer");
     
      MessageListenerAutoAck listener = new MessageListenerAutoAck(sessReceive);
     
      log.trace("Setting message listener");
     
      cons.setMessageListener(listener);
     
      log.trace("Set message listener");

      listener.waitForMessages();
     
      assertRemainingMessages(0);
     
      conn.close();
      assertFalse(listener.failed);
   }
  
   public void testMessageListenerDupsOK() throws Exception
   {
      Connection conn = cf.createConnection();
      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
      MessageProducer prod = sessSend.createProducer(queue);
      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
     
      log.trace("Sending messages");
     
      TextMessage tm1 = sessSend.createTextMessage("a");
      TextMessage tm2 = sessSend.createTextMessage("b");
      TextMessage tm3 = sessSend.createTextMessage("c");
      prod.send(tm1);
      prod.send(tm2);
      prod.send(tm3);
     
      log.trace("Sent messages");
     
      sessSend.close();
     
      assertRemainingMessages(3);
  
      conn.start();

      Session sessReceive = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
     
      log.trace("Creating consumer");
     
      MessageConsumer cons = sessReceive.createConsumer(queue);
     
      log.trace("Created consumer");
     
      MessageListenerDupsOK listener = new MessageListenerDupsOK(sessReceive);
     
      log.trace("Setting message listener");
     
      cons.setMessageListener(listener);
     
      log.trace("Set message listener");

      listener.waitForMessages();
     
      assertRemainingMessages(3);
     
      conn.close();
     
      assertRemainingMessages(0);
      assertFalse(listener.failed);
   }
  
   public void testMessageListenerClientAck() throws Exception
   {
      Connection conn = cf.createConnection();
      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
      MessageProducer prod = sessSend.createProducer(queue);
      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
      TextMessage tm1 = sessSend.createTextMessage("a");
      TextMessage tm2 = sessSend.createTextMessage("b");
      TextMessage tm3 = sessSend.createTextMessage("c");
      prod.send(tm1);
      prod.send(tm2);
      prod.send(tm3);
      sessSend.close();
     
      assertRemainingMessages(3);
     
      conn.start();
      Session sessReceive = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageConsumer cons = sessReceive.createConsumer(queue);
      MessageListenerClientAck listener = new MessageListenerClientAck(sessReceive);
      cons.setMessageListener(listener);
     
      listener.waitForMessages();
     
      assertRemainingMessages(0);
     
      conn.close();
     
      assertFalse(listener.failed);
   }
  
  
   public void testMessageListenerTransactionalAck() throws Exception
   {
      Connection conn = cf.createConnection();
      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
      MessageProducer prod = sessSend.createProducer(queue);
      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
      TextMessage tm1 = sessSend.createTextMessage("a");
      TextMessage tm2 = sessSend.createTextMessage("b");
      TextMessage tm3 = sessSend.createTextMessage("c");
      prod.send(tm1);
      prod.send(tm2);
      prod.send(tm3);
      sessSend.close();
     
      assertRemainingMessages(3);
     
      conn.start();
      Session sessReceive = conn.createSession(true, Session.SESSION_TRANSACTED);
      MessageConsumer cons = sessReceive.createConsumer(queue);
      MessageListenerTransactionalAck listener = new MessageListenerTransactionalAck(sessReceive);
      cons.setMessageListener(listener);
      listener.waitForMessages();
     
      assertRemainingMessages(0);
     
      conn.close();
     
      assertFalse(listener.failed);
   }
  
  
   // Package protected ---------------------------------------------
  
   // Protected -----------------------------------------------------
  
   // Private -------------------------------------------------------
  
   // Inner classes -------------------------------------------------
  
  
   private class MessageListenerAutoAck implements MessageListener
   {
     
      private Latch latch = new Latch();
     
      private Session sess;
     
      private int count = 0;
     
      boolean failed;
     
      MessageListenerAutoAck(Session sess)
      {
         this.sess = sess;
      }
     
      public void waitForMessages() throws InterruptedException
      {
         latch.acquire();
         Thread.sleep(500);
      }

      public void onMessage(Message m)
      {
         try
         {
            count++;
                 
            TextMessage tm = (TextMessage)m;
           
            log.trace("Got message: " + tm.getText());           
                     
            // Receive first three messages then recover() session
            // Only last message should be redelivered
            if (count == 1)
            {
               assertRemainingMessages(3);
              
               if (!"a".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }
            }
            if (count == 2)
            {
               assertRemainingMessages(2);
              
               if (!"b".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }
            }
            if (count == 3)
            {
               assertRemainingMessages(1);
              
               if (!"c".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }
               sess.recover();
            }
            if (count == 4)
            {
               assertRemainingMessages(1);
              
               if (!"c".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }              
               latch.release();
            }           
              
         }
         catch (Exception e)
         {
            failed = true;
            latch.release();
         }
      }
           
   }
  
   private class MessageListenerDupsOK implements MessageListener
   {
     
      private Latch latch = new Latch();
     
      private Session sess;
     
      private int count = 0;
     
      boolean failed;
     
      MessageListenerDupsOK(Session sess)
      {
         this.sess = sess;
      }
     
      public void waitForMessages() throws InterruptedException
      {
         latch.acquire();
         Thread.sleep(500);
      }

      public void onMessage(Message m)
      {
         try
         {
            count++;
                 
            TextMessage tm = (TextMessage)m;
           
            log.info("Got message: " + tm.getText());           
                     
            // Receive first three messages then recover() session
            // Only last message should be redelivered
            if (count == 1)
            {
               assertRemainingMessages(3);
              
               if (!"a".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }
            }
            if (count == 2)
            {
               assertRemainingMessages(3);
              
               if (!"b".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }
            }
            if (count == 3)
            {
               assertRemainingMessages(3);
              
               if (!"c".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }
               sess.recover();
            }
            if (count == 4)
            {
               assertRemainingMessages(3);
              
               if (!"c".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }              
               latch.release();
            }           
              
         }
         catch (Exception e)
         {
            failed = true;
            latch.release();
         }
      }
           
   }
  
  
   private class MessageListenerClientAck implements MessageListener
   {
     
      private Latch latch = new Latch();
     
      private Session sess;
     
      private int count = 0;
     
      boolean failed;
     
      MessageListenerClientAck(Session sess)
      {
         this.sess = sess;
      }

     
      public void waitForMessages() throws InterruptedException
      {
         latch.acquire();
         Thread.sleep(500);
      }

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

            if (count == 1)
            {
               assertRemainingMessages(3);
               if (!"a".equals(tm.getText()))
               {
                  log.trace("Expected a but got " + tm.getText());
                  failed = true;
                  latch.release();
               }              
            }
            if (count == 2)
            {
               assertRemainingMessages(3);
               if (!"b".equals(tm.getText()))
               {
                  log.trace("Expected b but got " + tm.getText());
                  failed = true;
                  latch.release();
               }              
            }
            if (count == 3)
            {
               assertRemainingMessages(3);
               if (!"c".equals(tm.getText()))
               {
                  log.trace("Expected c but got " + tm.getText());
                  failed = true;
                  latch.release();
               }
               sess.recover();
            }
            if (count == 4)
            {
               assertRemainingMessages(3);
               if (!"a".equals(tm.getText()))
               {
                  log.trace("Expected a but got " + tm.getText());
                  failed = true;
                  latch.release();
               }    
               tm.acknowledge();
               assertRemainingMessages(2);
               sess.recover();
            }
            if (count == 5)
            {
               assertRemainingMessages(2);
               if (!"b".equals(tm.getText()))
               {
                  log.trace("Expected b but got " + tm.getText());
                  failed = true;
                  latch.release();
              
               sess.recover();
            }
            if (count == 6)
            {
               assertRemainingMessages(2);
               if (!"b".equals(tm.getText()))
               {
                  log.trace("Expected b but got " + tm.getText());
                  failed = true;
                  latch.release();
               }              
            }
            if (count == 7)
            {
               assertRemainingMessages(2);
               if (!"c".equals(tm.getText()))
               {
                  log.trace("Expected c but got " + tm.getText());
                  failed = true;
                  latch.release();
               }
               tm.acknowledge();
               assertRemainingMessages(0);
               latch.release();
            }
              
         }
         catch (Exception e)
         {
            log.error("Caught exception", e);
            failed = true;
            latch.release();
         }
      }
           
   }
  
   private class MessageListenerTransactionalAck implements MessageListener
   {
     
      private Latch latch = new Latch();
     
      private Session sess;
     
      private int count = 0;
     
      boolean failed;
     
      MessageListenerTransactionalAck(Session sess)
      {
         this.sess = sess;
      }

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

      public void onMessage(Message m)
      {
         try
         {
            count++;
           
            TextMessage tm = (TextMessage)m;
                  
            if (count == 1)
            {
               assertRemainingMessages(3);
               if (!"a".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }              
            }
            if (count == 2)
            {
               assertRemainingMessages(3);
               if (!"b".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }              
            }
            if (count == 3)
            {
               assertRemainingMessages(3);
               if (!"c".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }
               log.trace("Rollback");
               sess.rollback();
            }
            if (count == 4)
            {
               assertRemainingMessages(3);
               if (!"a".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
               }    
            }
            if (count == 5)
            {
               assertRemainingMessages(3);
               if (!"b".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
              
               log.trace("commit");
               sess.commit();
               assertRemainingMessages(1);
            }
            if (count == 6)
            {
               assertRemainingMessages(1);
               if (!"c".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
              
               log.trace("recover");
               sess.rollback();
            }
            if (count == 7)
            {
               assertRemainingMessages(1);
               if (!"c".equals(tm.getText()))
               {
                  failed = true;
                  latch.release();
              
               log.trace("Commit");
               sess.commit();
               assertRemainingMessages(0);
               latch.release();
            }       
         }
         catch (Exception e)
         {
            //log.error(e);
            failed = true;
            latch.release();
         }
      }
           
   }
  
   private boolean assertRemainingMessages(int expected) throws Exception
   {
      //Need to pause since delivery may still be in progress
      Thread.sleep(500);
      ObjectName destObjectName =
         new ObjectName("jboss.messaging.destination:service=Queue,name=Queue");
      Integer messageCount = (Integer)ServerManagement.getAttribute(destObjectName, "MessageCount");
     
      log.trace("There are " + messageCount + " messages");
     
      assertEquals(expected, messageCount.intValue());     
      return expected == messageCount.intValue();
   }
  

}


TOP

Related Classes of org.jboss.test.messaging.jms.AcknowledgementTest

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.