Package org.jboss.test.messaging.jms

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

/*
  * 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.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.TopicConnection;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.management.ObjectName;

import org.jboss.jms.client.JBossSession;
import org.jboss.jms.client.delegate.ClientSessionDelegate;
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 8333 2011-06-14 02:20:56Z gaohoward $
*/
public class AcknowledgementTest extends JMSTestCase
{
   // Constants -----------------------------------------------------

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

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

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

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

   // 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();
         TopicSession sess = conn.createTopicSession(true, 0);
         TopicPublisher pub = sess.createPublisher(topic1);
         pub.setDeliveryMode(DeliveryMode.PERSISTENT);
        
         Message m = sess.createTextMessage("testing123");
         pub.publish(m);
         sess.commit();
        
         conn.close();
        
         checkEmpty(topic1);
      }
      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(topic1);
         TopicSubscriber sub = sess.createSubscriber(topic1);
         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();
        
         checkEmpty(topic1);
      }
      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(topic1);
         TopicSubscriber cons = sess.createSubscriber(topic1);
         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(topic1);
         TopicSubscriber newcons = newsess.createSubscriber(topic1);
        
         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 = null;
     
      try
      {
       
        conn = cf.createConnection();
 
        Session producerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
        MessageProducer producer = producerSess.createProducer(queue1);
 
        Session consumerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
        MessageConsumer consumer = consumerSess.createConsumer(queue1);
        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");
 
        int i = 0;
        for(; i < NUM_MESSAGES; i++)
        {
           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);
 
        checkEmpty(queue1);
      }
      finally
      {
        if (conn != null)
        {
          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 = null;
   
    try
    {   
      conn = cf.createConnection();
 
      Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageProducer producer = producerSess.createProducer(queue1);
 
      Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageConsumer consumer = consumerSess.createConsumer(queue1);
      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
 
        checkEmpty(queue1);
 
      conn.close();
    }
    finally
    {
      if (conn != null)
      {
        conn.close();
      }
    }
   }

 
 
  /**
   * Send some messages, acknowledge them individually and verify they are not resent after
    * recovery.
   */
  public void testIndividualClientAcknowledge() throws Exception
   {   
    Connection conn = null;
   
    try
    {     
      conn = cf.createConnection();
 
        Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageProducer producer = producerSess.createProducer(queue1);
     
      Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageConsumer consumer = consumerSess.createConsumer(queue1);
      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);
     
      for (int i = 0; i < NUM_MESSAGES; i++)
      {
        Message m = consumer.receive(200);
       
        assertNotNull(m);
     
           assertRemainingMessages(NUM_MESSAGES - i);
          
        m.acknowledge();
          
           assertRemainingMessages(NUM_MESSAGES - (i + 1));
      }
 
        assertRemainingMessages(0);
        
      consumerSess.recover();
     
      Message m = consumer.receive(200);
      assertNull(m);
    }
    finally
    {
      if (conn != null)
      {
        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 = null;
   
    try
    {
      conn = cf.createConnection();
 
      Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageProducer producer = producerSess.createProducer(queue1);
 
      Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageConsumer consumer = consumerSess.createConsumer(queue1);
      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);
    }
    finally
    {
      if (conn != null)
      {
        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 = null;
   
    try
    {
     
      conn = cf.createConnection();
 
      Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageProducer producer = producerSess.createProducer(queue1);
 
      Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      MessageConsumer consumer = consumerSess.createConsumer(queue1);
      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);           
    }
    finally
    {
      if (conn != null)
      {
        conn.close();
      }
     
      removeAllMessages(queue1.getQueueName(), true, 0);
    }
   }



  /*
   * Send some messages, consume them and verify the messages are not sent upon recovery
   *
   */
  public void testAutoAcknowledge() throws Exception
   {
    Connection conn = null;
   
    try
    {
     
      conn = cf.createConnection();
 
      Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
      MessageProducer producer = producerSess.createProducer(queue1);
 
      Session consumerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
      MessageConsumer consumer = consumerSess.createConsumer(queue1);
      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(2000);
          
           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(2000);
 
      log.trace("Message is:" + m);
 
      assertNull(m);
    }
    finally
    {
      if (conn != null)
      {
        conn.close();
      }
    }

   }
  
   public void testDupsOKBatchDefault() throws Exception
   {
      //test default
      Connection conn = null;
     
      try
      {       
        conn = cf.createConnection();
       
        JBossSession sess = (JBossSession)conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
       
        ClientSessionDelegate del = (ClientSessionDelegate)sess.getDelegate();
       
        assertEquals(1000, del.getDupsOKBatchSize());
      }
      finally
      {
        if (conn != null)
        {
          conn.close();
        }
      }
   }
     
   public void testDupsOKAcknowledgeQueue() 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]);
     
      Connection conn = null;
     
      try
      {
       
        ConnectionFactory myCF = (ConnectionFactory)ic.lookup("/mycf");
       
        conn = myCF.createConnection();
 
        Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer producer = producerSess.createProducer(queue1);
 
        Session consumerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
        MessageConsumer consumer = consumerSess.createConsumer(queue1);
        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(2000);
          
           assertNotNull(m);
           
           if (i == 9)
           {
              assertRemainingMessages(9);
           }
           else
           {
              assertRemainingMessages(19);
           }
        }
       
        for (int i = 0; i < 9; i++)
        {
           m = consumer.receive(2000);
          
           assertNotNull(m);
          
           assertRemainingMessages(9);
        }
       
        //Make sure the last are acked on close
       
        consumerSess.close();
       
        assertRemainingMessages(0);
      }
      finally
      {
     
        if (conn != null)
        {
          conn.close();
        }
       
        ServerManagement.invoke(on, "stop", new Object[0], new String[0]);
         ServerManagement.invoke(on, "destroy", new Object[0], new String[0]);
      }
     

   }
  
  
   public void testDupsOKAcknowledgeTopic() throws Exception
   {      
      final int BATCH_SIZE = 10;
     
      String mbeanConfig =
         "<mbean code=\"org.jboss.jms.server.connectionfactory.ConnectionFactory\"\n" +
         "       name=\"jboss.messaging.destination:service=MyConnectionFactory2\"\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]);
     
      Connection conn = null;
     
      try
      {
       
        ConnectionFactory myCF = (ConnectionFactory)ic.lookup("/mycf");
       
        conn = myCF.createConnection();
 
        Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer producer = producerSess.createProducer(topic1);
 
        Session consumerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
        MessageConsumer consumer = consumerSess.createConsumer(topic1);
        conn.start();
 
        //Send some messages
        for (int i = 0; i < 19; i++)
        {
           Message m = producerSess.createMessage();
           producer.send(m);
        }
       
        log.trace("Sent messages");
 
        Message m = null;
        for (int i = 0; i < 19; i++)
        {
           m = consumer.receive(200);
          
           assertNotNull(m);
        }
                    
        consumerSess.close();
      }
      finally
      {
     
        if (conn != null)
        {
          conn.close();
        }
       
        ServerManagement.invoke(on, "stop", new Object[0], new String[0]);
         ServerManagement.invoke(on, "destroy", new Object[0], new String[0]);
      }
     

   }
  
  
  
  /*
   * Send some messages, consume them and verify the messages are not sent upon recovery
   *
   */
  public void testLazyAcknowledge() throws Exception
   {
    Connection conn = null;
   
    try
    {
     
      conn = cf.createConnection();
 
      Session producerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
      MessageProducer producer = producerSess.createProducer(queue1);
 
      Session consumerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
      MessageConsumer consumer = consumerSess.createConsumer(queue1);
      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);
    }
    finally
    {
      if (conn != null)
      {
        conn.close();
      }
    }

   }
  
   public void testMessageListenerAutoAck() throws Exception
   {
      Connection conn = null;
     
      try
      {       
        conn = cf.createConnection();
        Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer prod = sessSend.createProducer(queue1);
 
        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(queue1);
       
        log.trace("Created consumer");
       
        MessageListenerAutoAck listener = new MessageListenerAutoAck(sessReceive);
       
        log.trace("Setting message listener");
       
        cons.setMessageListener(listener);
       
        log.trace("Set message listener");
 
        listener.waitForMessages();
                   
        Thread.sleep(500);
       
        assertRemainingMessages(0);
       
        assertFalse(listener.failed);
      }
      finally
      {
        if (conn != null)
        {
          conn.close();
        }
      }
   }

   /*
    *   This test will:
    *     - Send two messages over a producer
    *     - Receive one message over a consumer
    *     - Call Recover
    *     - Receive the second message
    *     - The queue should be empty after that
    *   Note: testMessageListenerAutoAck will test a similar case using MessageListeners
    */
   public void testRecoverAutoACK() throws Exception
   {
      Connection conn = null;

      try
      {
         conn = cf.createConnection();
         Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer p = s.createProducer(queue1);
         p.setDeliveryMode(DeliveryMode.PERSISTENT);
         Message m = s.createTextMessage("one");
         p.send(m);
         m = s.createTextMessage("two");
         p.send(m);
         conn.close();

         conn = null;

         assertRemainingMessages(2);

         conn = cf.createConnection();

         conn.start();

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

         MessageConsumer consumer = session.createConsumer(queue1);

         TextMessage messageReceived = (TextMessage)consumer.receive(1000);

         assertNotNull(messageReceived);

         assertEquals("one", messageReceived.getText());

         session.recover();

         messageReceived = (TextMessage)consumer.receive(1000);

         assertEquals("two", messageReceived.getText());

         consumer.close();

         // I can't call xasession.close for this test as JCA layer would cache the session
         // So.. keep this close commented!
         //xasession.close();

         assertRemainingMessages(0);

      }
      finally
      {
         if (conn != null)
         {
            conn.close();
         }
         ServerManagement.undeployQueue("MyQueue2");
      }
   }


  
   public void testMessageListenerDupsOK() throws Exception
   {
      Connection conn = null;
     
      try
      {
       
        conn = cf.createConnection();
        Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer prod = sessSend.createProducer(queue1);

        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(queue1);
       
        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();
       
        Thread.sleep(500);
       
        assertRemainingMessages(0);
        assertFalse(listener.failed);
      }
      finally
      {
        if (conn != null)
        {
          conn.close();
        }
      }
   }
  
   public void testMessageListenerClientAck() throws Exception
   {
      Connection conn = null;
     
      try
      {     
        conn = cf.createConnection();
        Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer prod = sessSend.createProducer(queue1);

        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(queue1);
        MessageListenerClientAck listener = new MessageListenerClientAck(sessReceive);
        cons.setMessageListener(listener);
       
        listener.waitForMessages();
       
        Thread.sleep(500);
       
        assertRemainingMessages(0);
       
        conn.close();
       
        assertFalse(listener.failed);
      }
      finally
      {
        if (conn != null)
        {
          conn.close();
        }
      }
   }
  
  
   public void testMessageListenerTransactionalAck() throws Exception
   {
      Connection conn = null;
     
      try
      {       
        conn = cf.createConnection();
        Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer prod = sessSend.createProducer(queue1);

        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(queue1);
        MessageListenerTransactionalAck listener = new MessageListenerTransactionalAck(sessReceive);
        cons.setMessageListener(listener);
        listener.waitForMessages();
       
        Thread.sleep(500);
       
        assertRemainingMessages(0);
       
        conn.close();
       
        assertFalse(listener.failed);
      }
      finally
      {
        if (conn != null)
        {
          conn.close();
        }
      }
   }
  
   // Package protected ---------------------------------------------
  
   // Protected -----------------------------------------------------
  
   // Private -------------------------------------------------------
  
   // Inner classes -------------------------------------------------


   private abstract class LatchListener implements MessageListener
   {
      protected Latch latch = new Latch();

      protected Session sess;

      protected int count = 0;

      boolean failed;

      LatchListener(Session sess)
      {
         this.sess = sess;
      }

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

      public abstract void onMessage(Message m);
     
   }
  
   private class MessageListenerAutoAck extends LatchListener
   {
     
      MessageListenerAutoAck(Session sess)
      {
         super(sess);
      }
     
      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  extends LatchListener
   {
     
      MessageListenerDupsOK(Session sess)
      {
         super(sess);
      }

      public void onMessage(Message m)
      {
         try
         {
            count++;
                 
            TextMessage tm = (TextMessage)m;
                      
            // 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 extends LatchListener
   {
     
      MessageListenerClientAck(Session sess)
      {
         super(sess);
      }


      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 extends LatchListener
   {
     
      MessageListenerTransactionalAck(Session sess)
      {
         super(sess);
      }

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

TOP

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

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.