Search in sources :

Example 11 with MessageInstanceConsumer

use of org.apache.qpid.server.message.MessageInstanceConsumer in project qpid-broker-j by apache.

the class AbstractQueueTestBase method testReleaseMessageThatBecomesExpiredIsNotRedelivered.

/**
 * Tests that a released message that becomes expired is not resent to the subscriber.
 * This tests ensures that SimpleAMQQueue<?>Entry.getNextAvailableEntry avoids expired entries.
 * Verifies also that the QueueContext._releasedEntry is reset to null after the entry has been reset.
 */
public void testReleaseMessageThatBecomesExpiredIsNotRedelivered() throws Exception {
    ServerMessage messageA = createMessage(new Long(24));
    final CountDownLatch sendIndicator = new CountDownLatch(1);
    _consumerTarget = new TestConsumerTarget() {

        @Override
        public void notifyWork() {
            while (processPending()) ;
        }

        @Override
        public void send(MessageInstanceConsumer consumer, MessageInstance entry, boolean batch) {
            try {
                super.send(consumer, entry, batch);
            } finally {
                sendIndicator.countDown();
            }
        }
    };
    _consumer = (QueueConsumer<?, ?>) _queue.addConsumer(_consumerTarget, null, messageA.getClass(), "test", EnumSet.of(ConsumerOption.SEES_REQUEUES, ConsumerOption.ACQUIRES), 0);
    final ArrayList<QueueEntry> queueEntries = new ArrayList<QueueEntry>();
    EntryListAddingAction postEnqueueAction = new EntryListAddingAction(queueEntries);
    /* Enqueue one message with expiration set for a short time in the future */
    final long expiration = System.currentTimeMillis() + 100L;
    when(messageA.getExpiration()).thenReturn(expiration);
    _queue.enqueue(messageA, postEnqueueAction, null);
    assertTrue("Message was not sent during expected time interval", sendIndicator.await(5000, TimeUnit.MILLISECONDS));
    assertEquals("Unexpected total number of messages sent to consumer", 1, _consumerTarget.getMessages().size());
    QueueEntry queueEntry = queueEntries.get(0);
    final CountDownLatch dequeueIndicator = new CountDownLatch(1);
    queueEntry.addStateChangeListener(new StateChangeListener<MessageInstance, MessageInstance.EntryState>() {

        @Override
        public void stateChanged(MessageInstance object, MessageInstance.EntryState oldState, MessageInstance.EntryState newState) {
            if (newState.equals(MessageInstance.DEQUEUED_STATE)) {
                dequeueIndicator.countDown();
            }
        }
    });
    assertFalse("Redelivery flag should not be set", queueEntry.isRedelivered());
    /* Wait a little more to be sure that message will have expired, then release the first message only, causing it to be requeued */
    while (!queueEntry.expired() && System.currentTimeMillis() <= expiration) {
        Thread.sleep(10);
    }
    assertTrue("Expecting the queue entry to be now expired", queueEntry.expired());
    queueEntry.release();
    assertTrue("Message was not de-queued due to expiration", dequeueIndicator.await(5000, TimeUnit.MILLISECONDS));
    assertEquals("Total number of messages sent should not have changed", 1, _consumerTarget.getMessages().size());
    assertFalse("Redelivery flag should not be set", queueEntry.isRedelivered());
    // QueueContext#_releasedEntry is updated after notification, thus, we need to make sure that it is updated
    long waitLoopLimit = 10;
    while (_consumer.getQueueContext().getReleasedEntry() != null && waitLoopLimit-- > 0) {
        Thread.sleep(10);
    }
    assertNull("releasedEntry should be cleared after requeue processed:" + _consumer.getQueueContext().getReleasedEntry(), _consumer.getQueueContext().getReleasedEntry());
}
Also used : ServerMessage(org.apache.qpid.server.message.ServerMessage) ArrayList(java.util.ArrayList) MessageInstanceConsumer(org.apache.qpid.server.message.MessageInstanceConsumer) CountDownLatch(java.util.concurrent.CountDownLatch) TestConsumerTarget(org.apache.qpid.server.consumer.TestConsumerTarget) MessageInstance(org.apache.qpid.server.message.MessageInstance)

Example 12 with MessageInstanceConsumer

use of org.apache.qpid.server.message.MessageInstanceConsumer in project qpid-broker-j by apache.

the class StandardQueueTest method testProcessQueueWithDequeuedEntry.

/**
 * Tests whether dequeued entry is sent to subscriber
 */
public void testProcessQueueWithDequeuedEntry() throws Exception {
    // total number of messages to send
    int messageNumber = 4;
    int dequeueMessageIndex = 1;
    Map<String, Object> queueAttributes = new HashMap<>();
    queueAttributes.put(Queue.NAME, "test");
    // create queue with overridden method deliverAsync
    StandardQueueImpl testQueue = new StandardQueueImpl(queueAttributes, getVirtualHost());
    testQueue.create();
    // put messages
    List<StandardQueueEntry> entries = (List<StandardQueueEntry>) enqueueGivenNumberOfMessages(testQueue, messageNumber);
    // dequeue message
    dequeueMessage(testQueue, dequeueMessageIndex);
    // latch to wait for message receipt
    final CountDownLatch latch = new CountDownLatch(messageNumber - 1);
    // create a consumer
    TestConsumerTarget consumer = new TestConsumerTarget() {

        @Override
        public void notifyWork() {
            while (processPending()) ;
        }

        /**
         * Send a message and decrement latch
         * @param consumer
         * @param entry
         * @param batch
         */
        @Override
        public void send(final MessageInstanceConsumer consumer, MessageInstance entry, boolean batch) {
            super.send(consumer, entry, batch);
            latch.countDown();
        }
    };
    // subscribe
    testQueue.addConsumer(consumer, null, entries.get(0).getMessage().getClass(), "test", EnumSet.of(ConsumerOption.ACQUIRES, ConsumerOption.SEES_REQUEUES), 0);
    // wait up to 1 minute for message receipt
    try {
        latch.await(1, TimeUnit.MINUTES);
    } catch (InterruptedException e1) {
        Thread.currentThread().interrupt();
    }
    List<MessageInstance> expected = Arrays.asList((MessageInstance) entries.get(0), entries.get(2), entries.get(3));
    verifyReceivedMessages(expected, consumer.getMessages());
}
Also used : HashMap(java.util.HashMap) MessageInstanceConsumer(org.apache.qpid.server.message.MessageInstanceConsumer) CountDownLatch(java.util.concurrent.CountDownLatch) TestConsumerTarget(org.apache.qpid.server.consumer.TestConsumerTarget) MessageInstance(org.apache.qpid.server.message.MessageInstance) List(java.util.List)

Aggregations

MessageInstanceConsumer (org.apache.qpid.server.message.MessageInstanceConsumer)12 MessageInstance (org.apache.qpid.server.message.MessageInstance)8 HashMap (java.util.HashMap)4 Map (java.util.Map)3 MessageContainer (org.apache.qpid.server.message.MessageContainer)3 ServerMessage (org.apache.qpid.server.message.ServerMessage)3 ArrayList (java.util.ArrayList)2 LinkedHashMap (java.util.LinkedHashMap)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 ConsumerOption (org.apache.qpid.server.consumer.ConsumerOption)2 ConsumerTarget (org.apache.qpid.server.consumer.ConsumerTarget)2 TestConsumerTarget (org.apache.qpid.server.consumer.TestConsumerTarget)2 MessageSource (org.apache.qpid.server.message.MessageSource)2 Visitor (org.apache.qpid.server.protocol.v0_8.UnacknowledgedMessageMap.Visitor)2 List (java.util.List)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 QpidByteBuffer (org.apache.qpid.server.bytebuffer.QpidByteBuffer)1 NamedAddressSpace (org.apache.qpid.server.model.NamedAddressSpace)1