use of org.apache.qpid.server.message.MessageInstance in project qpid-broker-j by apache.
the class PriorityQueueTest method changeMessagesPriority.
@Test
public void changeMessagesPriority() throws Exception {
final PriorityQueue<?> queue = (PriorityQueue<?>) getQueue();
final InternalMessage internalMessage1 = createInternalMessage((byte) 3, 0);
final InternalMessage internalMessage2 = createInternalMessage((byte) 3, 1);
final InternalMessage internalMessage3 = createInternalMessage((byte) 4, 2);
queue.enqueue(internalMessage1, null, null);
queue.enqueue(internalMessage2, null, null);
queue.enqueue(internalMessage3, null, null);
final List<Long> result = queue.reenqueueMessagesForPriorityChange("id in ('2','0')", (byte) 5);
assertEquals("Unexpected operation result", 2, result.size());
final List<MessageInstance> msgs = consumeMessages(queue);
try {
assertEquals(internalMessage3.getMessageNumber() + 1, msgs.get(0).getMessage().getMessageNumber());
assertEquals("2", msgs.get(0).getMessage().getMessageHeader().getHeader("id"));
assertEquals(internalMessage3.getMessageNumber() + 2, msgs.get(1).getMessage().getMessageNumber());
assertEquals("0", msgs.get(1).getMessage().getMessageHeader().getHeader("id"));
assertEquals(internalMessage2.getMessageNumber(), msgs.get(2).getMessage().getMessageNumber());
assertEquals("1", msgs.get(2).getMessage().getMessageHeader().getHeader("id"));
} catch (AssertionFailedError afe) {
showMessageOrderOnFailure(msgs, afe);
}
}
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);
}
}
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, 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()));
}
}
}
}
}
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);
}
}
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);
}
}
}
}
}
}
Aggregations