Search in sources :

Example 11 with MessageInstance

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

the class AMQChannel method receiveBasicNack.

@Override
public void receiveBasicNack(final long deliveryTag, final boolean multiple, final boolean requeue) {
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("RECV[" + _channelId + "] BasicNack[" + " deliveryTag: " + deliveryTag + " multiple: " + multiple + " requeue: " + requeue + " ]");
    }
    Map<Long, MessageConsumerAssociation> nackedMessageMap = new LinkedHashMap<>();
    _unacknowledgedMessageMap.collect(deliveryTag, multiple, nackedMessageMap);
    for (MessageConsumerAssociation unackedMessageConsumerAssociation : nackedMessageMap.values()) {
        if (unackedMessageConsumerAssociation == null) {
            LOGGER.warn("Ignoring nack request as message is null for tag:" + deliveryTag);
        } else {
            MessageInstance message = unackedMessageConsumerAssociation.getMessageInstance();
            if (message.getMessage() == null) {
                LOGGER.warn("Message has already been purged, unable to nack.");
            } else {
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Nack-ing: DT:" + deliveryTag + "-" + message.getMessage() + ": Requeue:" + requeue + " on channel:" + debugIdentity());
                }
                if (requeue) {
                    message.decrementDeliveryCount();
                    requeue(deliveryTag);
                } else {
                    message.reject(unackedMessageConsumerAssociation.getConsumer());
                    final boolean maxDeliveryCountEnabled = isMaxDeliveryCountEnabled(deliveryTag);
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("maxDeliveryCountEnabled: " + maxDeliveryCountEnabled + " deliveryTag " + deliveryTag);
                    }
                    if (maxDeliveryCountEnabled) {
                        final boolean deliveredTooManyTimes = isDeliveredTooManyTimes(deliveryTag);
                        if (LOGGER.isDebugEnabled()) {
                            LOGGER.debug("deliveredTooManyTimes: " + deliveredTooManyTimes + " deliveryTag " + deliveryTag);
                        }
                        if (deliveredTooManyTimes) {
                            deadLetter(deliveryTag);
                        } else {
                            message.incrementDeliveryCount();
                            message.release(unackedMessageConsumerAssociation.getConsumer());
                        }
                    } else {
                        requeue(deliveryTag);
                    }
                }
            }
        }
    }
}
Also used : MessageInstance(org.apache.qpid.server.message.MessageInstance) LinkedHashMap(java.util.LinkedHashMap)

Example 12 with MessageInstance

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

the class AMQChannel method deadLetter.

private void deadLetter(long deliveryTag) {
    final UnacknowledgedMessageMap unackedMap = getUnacknowledgedMessageMap();
    final MessageConsumerAssociation association = unackedMap.remove(deliveryTag, true);
    if (association == null) {
        LOGGER.warn("No message found, unable to DLQ delivery tag: " + deliveryTag);
    } else {
        final MessageInstance messageInstance = association.getMessageInstance();
        final ServerMessage msg = messageInstance.getMessage();
        int requeues = 0;
        if (messageInstance.makeAcquisitionUnstealable(association.getConsumer())) {
            requeues = messageInstance.routeToAlternate(new Action<MessageInstance>() {

                @Override
                public void performAction(final MessageInstance requeueEntry) {
                    messageWithSubject(ChannelMessages.DEADLETTERMSG(msg.getMessageNumber(), requeueEntry.getOwningResource().getName()));
                }
            }, null);
        }
        if (requeues == 0) {
            final TransactionLogResource owningResource = messageInstance.getOwningResource();
            if (owningResource instanceof Queue) {
                final Queue<?> queue = (Queue<?>) owningResource;
                final MessageDestination alternateBindingDestination = queue.getAlternateBindingDestination();
                if (alternateBindingDestination == null) {
                    messageWithSubject(ChannelMessages.DISCARDMSG_NOALTEXCH(msg.getMessageNumber(), queue.getName(), msg.getInitialRoutingAddress()));
                } else {
                    messageWithSubject(ChannelMessages.DISCARDMSG_NOROUTE(msg.getMessageNumber(), alternateBindingDestination.getName()));
                }
            }
        }
    }
}
Also used : MessageInstance(org.apache.qpid.server.message.MessageInstance) PrivilegedAction(java.security.PrivilegedAction) Action(org.apache.qpid.server.util.Action) MessageDestination(org.apache.qpid.server.message.MessageDestination) ServerMessage(org.apache.qpid.server.message.ServerMessage) TransactionLogResource(org.apache.qpid.server.store.TransactionLogResource) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) Queue(org.apache.qpid.server.model.Queue)

Example 13 with MessageInstance

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

the class AMQChannel method resend.

/**
 * Called to resend all outstanding unacknowledged messages to this same channel.
 */
private void resend() {
    final Map<Long, MessageConsumerAssociation> msgToRequeue = new LinkedHashMap<>();
    final Map<Long, MessageConsumerAssociation> msgToResend = new LinkedHashMap<>();
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Unacknowledged messages: {}", _unacknowledgedMessageMap.size());
    }
    _unacknowledgedMessageMap.visit(new Visitor() {

        @Override
        public boolean callback(final long deliveryTag, final MessageConsumerAssociation association) {
            if (association.getConsumer().isClosed()) {
                // consumer has gone
                msgToRequeue.put(deliveryTag, association);
            } else {
                // Consumer still exists
                msgToResend.put(deliveryTag, association);
            }
            return false;
        }

        @Override
        public void visitComplete() {
        }
    });
    for (Map.Entry<Long, MessageConsumerAssociation> entry : msgToResend.entrySet()) {
        long deliveryTag = entry.getKey();
        MessageInstance message = entry.getValue().getMessageInstance();
        MessageInstanceConsumer consumer = entry.getValue().getConsumer();
        // Without any details from the client about what has been processed we have to mark
        // all messages in the unacked map as redelivered.
        message.setRedelivered();
        if (message.makeAcquisitionUnstealable(consumer)) {
            message.decrementDeliveryCount();
            consumer.getTarget().send(consumer, message, false);
            // remove from unacked map - don't want to restore credit though(!)
            _unacknowledgedMessageMap.remove(deliveryTag, false);
        } else {
            msgToRequeue.put(deliveryTag, entry.getValue());
        }
    }
    // Process Messages to Requeue at the front of the queue
    for (Map.Entry<Long, MessageConsumerAssociation> entry : msgToRequeue.entrySet()) {
        long deliveryTag = entry.getKey();
        MessageInstance message = entry.getValue().getMessageInstance();
        MessageInstanceConsumer consumer = entry.getValue().getConsumer();
        // Amend the delivery counter as the client hasn't seen these messages yet.
        message.decrementDeliveryCount();
        // here we do wish to restore credit
        _unacknowledgedMessageMap.remove(deliveryTag, true);
        message.setRedelivered();
        message.release(consumer);
    }
}
Also used : MessageInstance(org.apache.qpid.server.message.MessageInstance) Visitor(org.apache.qpid.server.protocol.v0_8.UnacknowledgedMessageMap.Visitor) MessageInstanceConsumer(org.apache.qpid.server.message.MessageInstanceConsumer) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) LinkedHashMap(java.util.LinkedHashMap)

Example 14 with MessageInstance

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

the class AMQChannel method isDeliveredTooManyTimes.

private boolean isDeliveredTooManyTimes(final long deliveryTag) {
    final MessageInstance queueEntry = _unacknowledgedMessageMap.get(deliveryTag);
    if (queueEntry != null) {
        final int maximumDeliveryCount = queueEntry.getMaximumDeliveryCount();
        final int numDeliveries = queueEntry.getDeliveryCount();
        return maximumDeliveryCount != 0 && numDeliveries >= maximumDeliveryCount;
    }
    return false;
}
Also used : MessageInstance(org.apache.qpid.server.message.MessageInstance)

Example 15 with MessageInstance

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

the class AMQChannel method requeue.

/**
 * Requeue a single message
 *
 * @param deliveryTag The message to requeue
 */
private void requeue(long deliveryTag) {
    final MessageConsumerAssociation association = _unacknowledgedMessageMap.remove(deliveryTag, true);
    if (association != null) {
        MessageInstance unacked = association.getMessageInstance();
        // Mark message redelivered
        unacked.setRedelivered();
        // Ensure message is released for redelivery
        unacked.release(association.getConsumer());
    } else {
        LOGGER.warn("Requested requeue of message: {} but no such delivery tag exists.", deliveryTag);
    }
}
Also used : MessageInstance(org.apache.qpid.server.message.MessageInstance)

Aggregations

MessageInstance (org.apache.qpid.server.message.MessageInstance)24 MessageInstanceConsumer (org.apache.qpid.server.message.MessageInstanceConsumer)8 ServerMessage (org.apache.qpid.server.message.ServerMessage)8 MessageEnqueueRecord (org.apache.qpid.server.store.MessageEnqueueRecord)5 TransactionLogResource (org.apache.qpid.server.store.TransactionLogResource)5 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 LinkedHashMap (java.util.LinkedHashMap)4 Map (java.util.Map)3 TestConsumerTarget (org.apache.qpid.server.consumer.TestConsumerTarget)3 Action (org.apache.qpid.server.util.Action)3 CountDownLatch (java.util.concurrent.CountDownLatch)2 MessageDestination (org.apache.qpid.server.message.MessageDestination)2 MessageSource (org.apache.qpid.server.message.MessageSource)2 Queue (org.apache.qpid.server.model.Queue)2 Visitor (org.apache.qpid.server.protocol.v0_8.UnacknowledgedMessageMap.Visitor)2 MockMessageInstance (org.apache.qpid.server.queue.MockMessageInstance)2 Transaction (org.apache.qpid.server.store.Transaction)2 PrivilegedAction (java.security.PrivilegedAction)1 List (java.util.List)1