Package org.jboss.test.messaging.core.plugin.postoffice.cluster

Source Code of org.jboss.test.messaging.core.plugin.postoffice.cluster.RedistributionWithDefaultMessagePullPolicyTest$ThrottleReceiver

/*
  * 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.core.plugin.postoffice.cluster;

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

import org.jboss.messaging.core.Channel;
import org.jboss.messaging.core.Delivery;
import org.jboss.messaging.core.DeliveryObserver;
import org.jboss.messaging.core.Receiver;
import org.jboss.messaging.core.SimpleDelivery;
import org.jboss.messaging.core.message.Message;
import org.jboss.messaging.core.message.MessageReference;
import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultMessagePullPolicy;
import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
import org.jboss.messaging.core.tx.Transaction;
import org.jboss.test.messaging.core.SimpleCondition;
import org.jboss.test.messaging.core.SimpleReceiver;
import org.jboss.test.messaging.core.plugin.base.PostOfficeTestBase;
import org.jboss.test.messaging.util.CoreMessageFactory;

import EDU.oswego.cs.dl.util.concurrent.Executor;
import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;

/**
* A RedistributionWithDefaultMessagePullPolicyTest
*
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
* @author <a href="mailto:ovidiu@jboss.org">Oviidu Feodorov</a>
* @version <tt>$Revision: 2491 $</tt>
*
* $Id: RedistributionWithDefaultMessagePullPolicyTest.java 2491 2007-02-28 06:54:10Z ovidiu.feodorov@jboss.com $
*/
public class RedistributionWithDefaultMessagePullPolicyTest extends PostOfficeTestBase
{
   // Constants ------------------------------------------------------------------------------------

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

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

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

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

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

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

   public void tearDown() throws Exception
   {
      super.tearDown();
   }

   public void testConsumeAllNonPersistentNonRecoverable() throws Throwable
   {
      consumeAll(false, false);
   }

   public void testConsumeAllPersistentNonRecoverable() throws Throwable
   {
      consumeAll(true, false);
   }

   public void testConsumeAllNonPersistentRecoverable() throws Throwable
   {
      consumeAll(false, true);
   }

   public void testConsumeAllPersistentRecoverable() throws Throwable
   {
      consumeAll(true, true);
   }

   public void testConsumeBitByBitNonPersistentNonRecoverable() throws Throwable
   {
      consumeBitByBit(false, false);
   }

   public void testConsumeBitByBitPersistentNonRecoverable() throws Throwable
   {
      consumeBitByBit(true, false);
   }

   public void testConsumeBitByBitNonPersistentRecoverable() throws Throwable
   {
      consumeBitByBit(false, true);
   }

   public void testConsumeBitByBitPersistentRecoverable() throws Throwable
   {
      consumeBitByBit(true, true);
   }

   public void testSimpleMessagePull() throws Throwable
   {
      DefaultClusteredPostOffice office1 = null;
      DefaultClusteredPostOffice office2 = null;

      try
      {
         office1 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office2 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         LocalClusteredQueue queue1 =
            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
                                    true, true, -1, null, tr);

         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);

         LocalClusteredQueue queue2 =
            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
                                    true, true, -1, null, tr);
         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);

         Message msg = CoreMessageFactory.createCoreMessage(1, true, null);

         MessageReference ref = ms.reference(msg);

         office1.route(ref, new SimpleCondition("queue1"), null);

         Thread.sleep(2000);

         // Messages should all be in queue1

         List msgs = queue1.browse();
         assertEquals(1, msgs.size());

         msgs = queue2.browse();
         assertTrue(msgs.isEmpty());

         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         receiver1.setMaxRefs(0);
         queue1.add(receiver1);
         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         receiver2.setMaxRefs(0);
         queue2.add(receiver2);

         // Prompt delivery so the channels know if the receivers are ready
         queue1.deliver();
         Thread.sleep(2000);

         // Pull from 1 to 2

         receiver2.setMaxRefs(1);

         log.trace("delivering");
         queue2.deliver();

         Thread.sleep(3000);

         assertTrue(office1.getHoldingTransactions().isEmpty());
         assertTrue(office2.getHoldingTransactions().isEmpty());

         log.trace("r2 " + receiver2.getMessages().size());

         log.trace("queue1 refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2 refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());

         assertEquals(0, queue1.memoryRefCount());
         assertEquals(0, queue1.getDeliveringCount());

         assertEquals(0, queue2.memoryRefCount());
         assertEquals(1, queue2.getDeliveringCount());

         this.acknowledgeAll(receiver2);

         assertEquals(0, queue2.memoryRefCount());
         assertEquals(0, queue2.getDeliveringCount());

         assertTrue(office1.getHoldingTransactions().isEmpty());
         assertTrue(office2.getHoldingTransactions().isEmpty());

      }
      finally
      {
         if (office1 != null)
         {
            office1.stop();
         }

         if (office2 != null)
         {
            office2.stop();
         }
      }
   }

   public void testSimpleMessagePullCrashBeforeCommit() throws Throwable
   {
      DefaultClusteredPostOffice office1 = null;
      DefaultClusteredPostOffice office2 = null;

      try
      {
         office1 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office2 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         LocalClusteredQueue queue1 =
            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
                                    true, true, -1, null, tr);
         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);

         LocalClusteredQueue queue2 =
            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
                                    true, true, -1, null, tr);
         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);

         Message msg = CoreMessageFactory.createCoreMessage(1, true, null);

         MessageReference ref = ms.reference(msg);

         office1.route(ref, new SimpleCondition("queue1"), null);

         Thread.sleep(2000);

         //Messages should all be in queue1

         List msgs = queue1.browse();
         assertEquals(1, msgs.size());

         msgs = queue2.browse();
         assertTrue(msgs.isEmpty());

         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         receiver1.setMaxRefs(0);
         queue1.add(receiver1);
         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         receiver2.setMaxRefs(0);
         queue2.add(receiver2);

         //Prompt delivery so the channels know if the receivers are ready
         queue1.deliver();
         Thread.sleep(2000);

         //Pull from 1 to 2

         receiver2.setMaxRefs(1);

         //Force a failure before commit
         office2.setFail(true, false, false);

         log.trace("delivering");
         queue2.deliver();

         Thread.sleep(3000);

         assertEquals(1, office1.getHoldingTransactions().size());
         assertTrue(office2.getHoldingTransactions().isEmpty());

         log.trace("queue1 refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2 refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());

         assertEquals(0, queue1.memoryRefCount());
         assertEquals(1, queue1.getDeliveringCount());

         assertEquals(0, queue2.memoryRefCount());
         assertEquals(0, queue2.getDeliveringCount());

         //Now kill office 2 - this should cause office1 to remove the dead held transaction

         office2.stop();
         Thread.sleep(2000);

         assertTrue(office1.getHoldingTransactions().isEmpty());

         //The delivery should be cancelled back to the queue too

         assertEquals(1, queue1.memoryRefCount());
         assertEquals(0, queue1.getDeliveringCount());


      }
      finally
      {
         if (office1 != null)
         {
            office1.stop();
         }

         if (office2 != null)
         {
            office2.stop();
         }
      }
   }

   public void testSimpleMessagePullCrashAfterCommit() throws Throwable
   {
      DefaultClusteredPostOffice office1 = null;
      DefaultClusteredPostOffice office2 = null;

      try
      {
         office1 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office2 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         LocalClusteredQueue queue1 =
            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
                                    true, true, -1, null, tr);
         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);

         LocalClusteredQueue queue2 =
            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
                                    true, true, -1, null, tr);
         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);

         Message msg = CoreMessageFactory.createCoreMessage(1, true, null);

         MessageReference ref = ms.reference(msg);

         office1.route(ref, new SimpleCondition("queue1"), null);

         Thread.sleep(2000);

         //Messages should all be in queue1

         List msgs = queue1.browse();
         assertEquals(1, msgs.size());

         msgs = queue2.browse();
         assertTrue(msgs.isEmpty());

         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         receiver1.setMaxRefs(0);
         queue1.add(receiver1);
         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         receiver2.setMaxRefs(0);
         queue2.add(receiver2);

         //Prompt delivery so the channels know if the receivers are ready
         queue1.deliver();
         Thread.sleep(2000);

         //Pull from 1 to 2

         receiver2.setMaxRefs(1);

         //Force a failure after commit the ack to storage
         office2.setFail(false, true, false);

         log.trace("delivering");
         queue2.deliver();

         Thread.sleep(3000);

         assertEquals(1, office1.getHoldingTransactions().size());
         assertTrue(office2.getHoldingTransactions().isEmpty());

         log.trace("queue1 refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2 refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());

         assertEquals(0, queue1.memoryRefCount());
         assertEquals(1, queue1.getDeliveringCount());

         //Now kill office 2 - this should cause office1 to remove the dead held transaction

         office2.stop();
         Thread.sleep(2000);

         assertTrue(office1.getHoldingTransactions().isEmpty());

         //The delivery should be committed

         assertEquals(0, queue1.memoryRefCount());
         assertEquals(0, queue1.getDeliveringCount());

      }
      finally
      {
         if (office1 != null)
         {
            office1.stop();
         }

         if (office2 != null)
         {
            office2.stop();
         }
      }
   }

   public void testFailHandleMessagePullResult() throws Throwable
   {
      DefaultClusteredPostOffice office1 = null;
      DefaultClusteredPostOffice office2 = null;

      try
      {
         office1 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office2 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         LocalClusteredQueue queue1 =
            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
                                    true, true, -1, null, tr);
         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);

         LocalClusteredQueue queue2 =
            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
                                    true, true, -1, null, tr);
         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);

         Message msg = CoreMessageFactory.createCoreMessage(1, true, null);

         MessageReference ref = ms.reference(msg);

         office1.route(ref, new SimpleCondition("queue1"), null);

         Thread.sleep(2000);

         //Messages should all be in queue1

         List msgs = queue1.browse();
         assertEquals(1, msgs.size());

         msgs = queue2.browse();
         assertTrue(msgs.isEmpty());

         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         receiver1.setMaxRefs(0);
         queue1.add(receiver1);
         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         receiver2.setMaxRefs(0);
         queue2.add(receiver2);

         //Prompt delivery so the channels know if the receivers are ready
         queue1.deliver();
         Thread.sleep(2000);

         //Pull from 1 to 2

         receiver2.setMaxRefs(1);

         office2.setFail(false, false, true);

         log.trace("delivering");
         queue2.deliver();

         Thread.sleep(3000);

         //The delivery should be rolled back

         assertTrue(office2.getHoldingTransactions().isEmpty());
         assertTrue(office2.getHoldingTransactions().isEmpty());

         log.trace("queue1 refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2 refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());

         assertEquals(1, queue1.memoryRefCount());
         assertEquals(0, queue1.getDeliveringCount());

         assertEquals(0, queue2.memoryRefCount());
         assertEquals(0, queue2.getDeliveringCount());
      }
      finally
      {
         if (office1 != null)
         {
            office1.stop();
         }

         if (office2 != null)
         {
            office2.stop();
         }
      }
   }

   protected void consumeAll(boolean persistent, boolean recoverable) throws Throwable
   {
      DefaultClusteredPostOffice office1 = null;
      DefaultClusteredPostOffice office2 = null;
      DefaultClusteredPostOffice office3 = null;
      DefaultClusteredPostOffice office4 = null;
      DefaultClusteredPostOffice office5 = null;

      boolean readOK;

      try
      {
         log.trace("Creating post offices");

         office1 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office2 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office3 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(3, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office4 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(4, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office5 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(5, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         log.trace("Created postoffices");

         LocalClusteredQueue queue1 =
            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
                                    true, recoverable, -1, null, tr);
         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);

         LocalClusteredQueue queue2 =
            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
                                    true, recoverable, -1, null, tr);
         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);

         LocalClusteredQueue queue3 =
            new LocalClusteredQueue(office3, 3, "queue1", channelIDManager.getID(), ms, pm,
                                    true, recoverable, -1, null, tr);
         office3.bindClusteredQueue(new SimpleCondition("queue1"), queue3);

         LocalClusteredQueue queue4 =
            new LocalClusteredQueue(office4, 4, "queue1", channelIDManager.getID(), ms, pm,
                                    true, recoverable, -1, null, tr);
         office4.bindClusteredQueue(new SimpleCondition("queue1"), queue4);

         LocalClusteredQueue queue5 =
            new LocalClusteredQueue(office5, 5, "queue1", channelIDManager.getID(), ms, pm,
                                    true, recoverable, -1, null, tr);
         office5.bindClusteredQueue(new SimpleCondition("queue1"), queue5);

         log.trace("Created and bound queues");

         final int NUM_MESSAGES = 100;

         log.trace("sending messages");
         this.sendMessages("queue1", persistent, office1, NUM_MESSAGES, null);
         this.sendMessages("queue1", persistent, office2, NUM_MESSAGES, null);
         this.sendMessages("queue1", persistent, office3, NUM_MESSAGES, null);
         this.sendMessages("queue1", persistent, office4, NUM_MESSAGES, null);
         this.sendMessages("queue1", persistent, office5, NUM_MESSAGES, null);

         log.trace("sent messages");

         Thread.sleep(2000);


         log.trace("Finished small sleep");

         //Check the sizes

         log.trace("Here are the sizes:");
         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());

         assertEquals(NUM_MESSAGES, queue1.memoryRefCount());
         assertEquals(0, queue1.getDeliveringCount());

         assertEquals(NUM_MESSAGES, queue2.memoryRefCount());
         assertEquals(0, queue2.getDeliveringCount());

         assertEquals(NUM_MESSAGES, queue3.memoryRefCount());
         assertEquals(0, queue3.getDeliveringCount());

         assertEquals(NUM_MESSAGES, queue4.memoryRefCount());
         assertEquals(0, queue4.getDeliveringCount());

         assertEquals(NUM_MESSAGES, queue5.memoryRefCount());
         assertEquals(0, queue5.getDeliveringCount());

         log.trace("Creating receiver");

         SimpleReceiver receiver = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING);

         log.trace("Created receiver");

         queue1.add(receiver);

         log.trace("Added receiver");

         queue1.deliver();

         log.trace("Called deliver");

         log.trace("Waiting for handleInvocations");
         long start = System.currentTimeMillis();
         readOK = receiver.waitForHandleInvocations(NUM_MESSAGES * 5, 60000);
         long end = System.currentTimeMillis();
         log.trace("I waited for " + (end - start) + " ms");

         assertTrue(readOK);

         Thread.sleep(2000);


         log.trace("Here are the sizes:");
         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());

         assertEquals(0, queue1.memoryRefCount());
         assertEquals(NUM_MESSAGES * 5, queue1.getDeliveringCount());

         assertEquals(0, queue2.memoryRefCount());
         assertEquals(0, queue2.getDeliveringCount());

         assertEquals(0, queue3.memoryRefCount());
         assertEquals(0, queue3.getDeliveringCount());

         assertEquals(0, queue4.memoryRefCount());
         assertEquals(0, queue4.getDeliveringCount());

         assertEquals(0, queue5.memoryRefCount());
         assertEquals(0, queue5.getDeliveringCount());

         List messages = receiver.getMessages();

         assertNotNull(messages);

         assertEquals(NUM_MESSAGES * 5, messages.size());

         Iterator iter = messages.iterator();

         log.trace("Acknowledging messages");

         while (iter.hasNext())
         {
            Message msg = (Message) iter.next();

            receiver.acknowledge(msg, null);
         }

         log.trace("Acknowledged messages");

         receiver.clear();

         assertEquals(0, queue1.memoryRefCount());
         assertEquals(0, queue1.getDeliveringCount());

         assertTrue(office1.getHoldingTransactions().isEmpty());
         assertTrue(office2.getHoldingTransactions().isEmpty());
         assertTrue(office3.getHoldingTransactions().isEmpty());
         assertTrue(office4.getHoldingTransactions().isEmpty());
         assertTrue(office5.getHoldingTransactions().isEmpty());

         if (checkNoMessageData())
         {
            fail("Message data still in database");
         }
      }
      finally
      {
         if (office1 != null)
         {
            office1.stop();
         }

         if (office2 != null)
         {
            office2.stop();
         }

         if (office3 != null)
         {
            office3.stop();
         }

         if (office4 != null)
         {
            office4.stop();
         }

         if (office5 != null)
         {
            office5.stop();
         }
      }
   }

   protected void consumeBitByBit(boolean persistent, boolean recoverable) throws Throwable
   {
      DefaultClusteredPostOffice office1 = null;
      DefaultClusteredPostOffice office2 = null;
      DefaultClusteredPostOffice office3 = null;
      DefaultClusteredPostOffice office4 = null;
      DefaultClusteredPostOffice office5 = null;

      boolean readOK;

      try
      {
         office1 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(1, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office2 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(2, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office3 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(3, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office4 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(4, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         office5 = (DefaultClusteredPostOffice)
            createClusteredPostOffice(5, "testgroup", 10000, 10000, new DefaultMessagePullPolicy(),
                                      sc, ms, pm, tr);

         LocalClusteredQueue queue1 =
            new LocalClusteredQueue(office1, 1, "queue1", channelIDManager.getID(), ms, pm,
                                    true, recoverable, -1, null, tr);
         office1.bindClusteredQueue(new SimpleCondition("queue1"), queue1);

         LocalClusteredQueue queue2 =
            new LocalClusteredQueue(office2, 2, "queue1", channelIDManager.getID(), ms, pm,
                                    true, recoverable, -1, null, tr);
         office2.bindClusteredQueue(new SimpleCondition("queue1"), queue2);

         LocalClusteredQueue queue3 =
            new LocalClusteredQueue(office3, 3, "queue1", channelIDManager.getID(), ms, pm,
                                    true, recoverable, -1, null, tr);
         office3.bindClusteredQueue(new SimpleCondition("queue1"), queue3);

         LocalClusteredQueue queue4 =
            new LocalClusteredQueue(office4, 4, "queue1", channelIDManager.getID(), ms, pm,
                                    true, recoverable, -1, null, tr);
         office4.bindClusteredQueue(new SimpleCondition("queue1"), queue4);

         LocalClusteredQueue queue5 =
            new LocalClusteredQueue(office5, 5, "queue1", channelIDManager.getID(), ms, pm,
                                    true, recoverable, -1, null, tr);
         office5.bindClusteredQueue(new SimpleCondition("queue1"), queue5);

         final int NUM_MESSAGES = 100;

         this.sendMessages("queue1", persistent, office1, NUM_MESSAGES, null);
         this.sendMessages("queue1", persistent, office2, NUM_MESSAGES, null);
         this.sendMessages("queue1", persistent, office3, NUM_MESSAGES, null);
         this.sendMessages("queue1", persistent, office4, NUM_MESSAGES, null);
         this.sendMessages("queue1", persistent, office5, NUM_MESSAGES, null);

         Thread.sleep(2000);

         // Check the sizes

         log.trace("Here are the sizes 1:");
         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());

         assertEquals(NUM_MESSAGES, queue1.memoryRefCount());
         assertEquals(0, queue1.getDeliveringCount());

         assertEquals(NUM_MESSAGES, queue2.memoryRefCount());
         assertEquals(0, queue2.getDeliveringCount());

         assertEquals(NUM_MESSAGES, queue3.memoryRefCount());
         assertEquals(0, queue3.getDeliveringCount());

         assertEquals(NUM_MESSAGES, queue4.memoryRefCount());
         assertEquals(0, queue4.getDeliveringCount());

         assertEquals(NUM_MESSAGES, queue5.memoryRefCount());
         assertEquals(0, queue5.getDeliveringCount());

         assertTrue(office1.getHoldingTransactions().isEmpty());
         assertTrue(office2.getHoldingTransactions().isEmpty());
         assertTrue(office3.getHoldingTransactions().isEmpty());
         assertTrue(office4.getHoldingTransactions().isEmpty());
         assertTrue(office5.getHoldingTransactions().isEmpty());

         SimpleReceiver receiver1 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         queue1.add(receiver1);
         SimpleReceiver receiver2 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         queue2.add(receiver2);
         SimpleReceiver receiver3 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         queue3.add(receiver3);
         SimpleReceiver receiver4 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         queue4.add(receiver4);
         SimpleReceiver receiver5 = new SimpleReceiver("blah", SimpleReceiver.ACCEPTING_TO_MAX);
         queue5.add(receiver5);

         receiver1.setMaxRefs(5);
         queue1.deliver();
         readOK = receiver1.waitForHandleInvocations(5, 20000);
         assertTrue(readOK);
         Thread.sleep(1000);
         assertEquals(NUM_MESSAGES - 5, queue1.memoryRefCount());
         assertEquals(5, queue1.getDeliveringCount());

         acknowledgeAll(receiver1);
         assertEquals(0, queue1.getDeliveringCount());
         receiver1.setMaxRefs(0);

         receiver2.setMaxRefs(10);
         queue2.deliver();
         readOK = receiver2.waitForHandleInvocations(10, 20000);
         assertTrue(readOK);
         Thread.sleep(1000);
         assertEquals(NUM_MESSAGES - 10, queue2.memoryRefCount());
         assertEquals(10, queue2.getDeliveringCount());
         acknowledgeAll(receiver2);
         receiver2.setMaxRefs(0);

         receiver3.setMaxRefs(15);
         queue3.deliver();
         readOK = receiver3.waitForHandleInvocations(15, 20000);
         Thread.sleep(1000);
         assertEquals(NUM_MESSAGES - 15, queue3.memoryRefCount());
         assertEquals(15, queue3.getDeliveringCount());
         acknowledgeAll(receiver3);
         receiver3.setMaxRefs(0);

         receiver4.setMaxRefs(20);
         queue4.deliver();
         readOK = receiver4.waitForHandleInvocations(20, 20000);
         assertTrue(readOK);
         Thread.sleep(1000);
         assertEquals(NUM_MESSAGES - 20, queue4.memoryRefCount());
         assertEquals(20, queue4.getDeliveringCount());
         acknowledgeAll(receiver4);
         receiver4.setMaxRefs(0);

         receiver5.setMaxRefs(25);
         queue5.deliver();
         readOK = receiver5.waitForHandleInvocations(25, 20000);
         assertTrue(readOK);
         Thread.sleep(1000);
         assertEquals(NUM_MESSAGES - 25, queue5.memoryRefCount());
         assertEquals(25, queue5.getDeliveringCount());
         acknowledgeAll(receiver5);
         receiver5.setMaxRefs(0);

         assertTrue(office1.getHoldingTransactions().isEmpty());
         assertTrue(office2.getHoldingTransactions().isEmpty());
         assertTrue(office3.getHoldingTransactions().isEmpty());
         assertTrue(office4.getHoldingTransactions().isEmpty());
         assertTrue(office5.getHoldingTransactions().isEmpty());

         log.trace("Here are the sizes 2:");
         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());

         // Consume the rest from queue 5
         receiver5.setMaxRefs(NUM_MESSAGES - 25);
         queue5.deliver();
         readOK = receiver5.waitForHandleInvocations(NUM_MESSAGES - 25, 20000);
         assertTrue(readOK);

         Thread.sleep(2000);

         log.trace("receiver5 msgs:" + receiver5.getMessages().size());

         log.trace("Here are the sizes 3:");
         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());

         // This will result in an extra one being pulled from queue1 - we cannot avoid this. This
         // is because the channel does not know that the receiver is full unless it tries with a
         // ref so it needs to retrieve one

                                                                   // http://jira.jboss.org/jira/browse/JBMESSAGING-901                                                                         
         assertEquals(NUM_MESSAGES - 6, queue1.memoryRefCount())// <-  expected:<94> but was:<93>
         assertEquals(0, queue1.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 10, queue2.memoryRefCount());
         assertEquals(0, queue2.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 15, queue3.memoryRefCount());
         assertEquals(0, queue3.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 20, queue4.memoryRefCount());
         assertEquals(0, queue4.getDeliveringCount());

         assertEquals(1, queue5.memoryRefCount());
         assertEquals(NUM_MESSAGES - 25, queue5.getDeliveringCount());

         acknowledgeAll(receiver5);

         assertEquals(0, queue5.getDeliveringCount());

         receiver5.setMaxRefs(0);

         assertTrue(office1.getHoldingTransactions().isEmpty());
         assertTrue(office2.getHoldingTransactions().isEmpty());
         assertTrue(office3.getHoldingTransactions().isEmpty());
         assertTrue(office4.getHoldingTransactions().isEmpty());
         assertTrue(office5.getHoldingTransactions().isEmpty());

         // Now consume 5 more from queue5, they should come from queue1 which has the most messages

         log.trace("Consume 5 more from queue 5");

         receiver5.setMaxRefs(5);
         queue5.deliver();
         readOK = receiver5.waitForHandleInvocations(5, 20000);
         assertTrue(readOK);

         Thread.sleep(4000);

         log.trace("Here are the sizes 4:");
         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 11, queue1.memoryRefCount()); // <--  expected:<89> but was:<88>

         assertEquals(0, queue1.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 10, queue2.memoryRefCount());
         assertEquals(0, queue2.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 15, queue3.memoryRefCount());
         assertEquals(0, queue3.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 20, queue4.memoryRefCount());
         assertEquals(0, queue4.getDeliveringCount());

         assertEquals(1, queue5.memoryRefCount());
         assertEquals(5, queue5.getDeliveringCount());

         acknowledgeAll(receiver5);

         assertEquals(0, queue5.getDeliveringCount());

         receiver1.setMaxRefs(0);

         assertTrue(office1.getHoldingTransactions().isEmpty());
         assertTrue(office2.getHoldingTransactions().isEmpty());
         assertTrue(office3.getHoldingTransactions().isEmpty());
         assertTrue(office4.getHoldingTransactions().isEmpty());
         assertTrue(office5.getHoldingTransactions().isEmpty());

         // Consume 1 more - should pull one from queue2

         receiver5.setMaxRefs(1);
         queue5.deliver();
         readOK = receiver5.waitForHandleInvocations(1, 20000);
         assertTrue(readOK);

         Thread.sleep(2000);

         log.trace("Here are the sizes 5:");
         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 11, queue1.memoryRefCount());
         assertEquals(0, queue1.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 11, queue2.memoryRefCount());
         assertEquals(0, queue2.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 15, queue3.memoryRefCount());
         assertEquals(0, queue3.getDeliveringCount());

         assertEquals(NUM_MESSAGES - 20, queue4.memoryRefCount());
         assertEquals(0, queue4.getDeliveringCount());

         assertEquals(1, queue5.memoryRefCount());
         assertEquals(1, queue5.getDeliveringCount());

         acknowledgeAll(receiver5);

         assertEquals(0, queue5.getDeliveringCount());

         receiver5.setMaxRefs(0);

         assertTrue(office1.getHoldingTransactions().isEmpty());
         assertTrue(office2.getHoldingTransactions().isEmpty());
         assertTrue(office3.getHoldingTransactions().isEmpty());
         assertTrue(office4.getHoldingTransactions().isEmpty());
         assertTrue(office5.getHoldingTransactions().isEmpty());

         // From queue 4 consume everything else

         int num = NUM_MESSAGES - 15 + NUM_MESSAGES - 20 + NUM_MESSAGES - 11 + NUM_MESSAGES - 11 + 1;
         receiver4.setMaxRefs(num);
         queue4.deliver();
         readOK = receiver4.waitForHandleInvocations(num, 20000);
         assertTrue(readOK);

         Thread.sleep(2000);

         log.trace("Here are the sizes 6:");
         log.trace("queue1, refs:" + queue1.memoryRefCount() + " dels:" + queue1.getDeliveringCount());
         log.trace("queue2, refs:" + queue2.memoryRefCount() + " dels:" + queue2.getDeliveringCount());
         log.trace("queue3, refs:" + queue3.memoryRefCount() + " dels:" + queue3.getDeliveringCount());
         log.trace("queue4, refs:" + queue4.memoryRefCount() + " dels:" + queue4.getDeliveringCount());
         log.trace("queue5, refs:" + queue5.memoryRefCount() + " dels:" + queue5.getDeliveringCount());

         assertEquals(0, queue1.memoryRefCount());
         assertEquals(0, queue1.getDeliveringCount());

         assertEquals(0, queue2.memoryRefCount());
         assertEquals(0, queue2.getDeliveringCount());

         assertEquals(0, queue3.memoryRefCount()); // <- sometimes, there is still 1 message left in this queue
         assertEquals(0, queue3.getDeliveringCount());

         assertEquals(0, queue4.memoryRefCount());
         assertEquals(NUM_MESSAGES - 15 + NUM_MESSAGES - 20 + NUM_MESSAGES - 11 + NUM_MESSAGES - 11 + 1, queue4.getDeliveringCount());

         assertEquals(0, queue5.memoryRefCount());
         assertEquals(0, queue5.getDeliveringCount());

         acknowledgeAll(receiver4);

         assertEquals(0, queue4.getDeliveringCount());

         assertTrue(office1.getHoldingTransactions().isEmpty());
         assertTrue(office2.getHoldingTransactions().isEmpty());
         assertTrue(office3.getHoldingTransactions().isEmpty());
         assertTrue(office4.getHoldingTransactions().isEmpty());
         assertTrue(office5.getHoldingTransactions().isEmpty());

         if (checkNoMessageData())
         {
            fail("Message data still in database");
         }
      }
      finally
      {
         if (office1 != null)
         {
            office1.stop();
         }

         if (office2 != null)
         {
            office2.stop();
         }

         if (office3 != null)
         {
            office3.stop();
         }

         if (office4 != null)
         {
            office4.stop();
         }

         if (office5 != null)
         {
            office5.stop();
         }
      }
   }

   class ThrottleReceiver implements Receiver, Runnable
   {
      long pause;

      volatile int totalCount;

      int count;

      int maxSize;

      volatile boolean full;

      Executor executor;

      List dels;

      Channel queue;

      int getTotalCount()
      {
         return totalCount;
      }

      ThrottleReceiver(Channel queue, long pause, int maxSize)
      {
         this.queue = queue;

         this.pause = pause;

         this.maxSize = maxSize;

         this.executor = new QueuedExecutor();

         this.dels = new ArrayList();
      }

      public Delivery handle(DeliveryObserver observer, MessageReference reference, Transaction tx)
      {
         if (full)
         {
            return null;
         }

         //log.trace(this + " got ref");

         //log.trace("cnt:" + totalCount);

         SimpleDelivery del = new SimpleDelivery(observer, reference);

         dels.add(del);

         count++;

         totalCount++;

         if (count == maxSize)
         {
            full = true;

            count = 0;

            try
            {
               executor.execute(this);
            }
            catch (InterruptedException e)
            {
               //Ignore
            }
         }

         return del;

      }

      public void run()
      {
         //Simulate processing of messages

         try
         {
            Thread.sleep(pause);
         }
         catch (InterruptedException e)
         {
            //Ignore
         }

         Iterator iter = dels.iterator();

         while (iter.hasNext())
         {
            Delivery del = (Delivery) iter.next();

            try
            {
               del.acknowledge(null);
            }
            catch (Throwable t)
            {
               //Ignore
            }
         }

         dels.clear();

         full = false;

         queue.deliver();
      }

   }

   private void acknowledgeAll(SimpleReceiver receiver) throws Throwable
   {
      List messages = receiver.getMessages();

      Iterator iter = messages.iterator();

      while (iter.hasNext())
      {
         Message msg = (Message) iter.next();

         receiver.acknowledge(msg, null);
      }

      receiver.clear();
   }


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

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

}




TOP

Related Classes of org.jboss.test.messaging.core.plugin.postoffice.cluster.RedistributionWithDefaultMessagePullPolicyTest$ThrottleReceiver

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.