use of org.apache.qpid.server.message.MessageReference in project qpid-broker-j by apache.
the class AMQChannel method deliverCurrentMessageIfComplete.
private void deliverCurrentMessageIfComplete() {
// check and deliver if header says body length is zero
if (_currentMessage.allContentReceived()) {
MessagePublishInfo info = _currentMessage.getMessagePublishInfo();
String routingKey = AMQShortString.toString(info.getRoutingKey());
String exchangeName = AMQShortString.toString(info.getExchange());
try {
final MessageDestination destination = _currentMessage.getDestination();
ContentHeaderBody contentHeader = _currentMessage.getContentHeader();
_connection.checkAuthorizedMessagePrincipal(AMQShortString.toString(contentHeader.getProperties().getUserId()));
_publishAuthCache.authorisePublish(destination, routingKey, info.isImmediate(), _connection.getLastReadTime());
if (_confirmOnPublish) {
_confirmedMessageCounter++;
}
long bodySize = _currentMessage.getSize();
long timestamp = contentHeader.getProperties().getTimestamp();
try {
final MessagePublishInfo messagePublishInfo = _currentMessage.getMessagePublishInfo();
final MessageMetaData messageMetaData = new MessageMetaData(messagePublishInfo, contentHeader, getConnection().getLastReadTime());
final MessageHandle<MessageMetaData> handle = _messageStore.addMessage(messageMetaData);
int bodyCount = _currentMessage.getBodyCount();
if (bodyCount > 0) {
for (int i = 0; i < bodyCount; i++) {
ContentBody contentChunk = _currentMessage.getContentChunk(i);
handle.addContent(contentChunk.getPayload());
contentChunk.dispose();
}
}
final StoredMessage<MessageMetaData> storedMessage = handle.allContentAdded();
final AMQMessage amqMessage = new AMQMessage(storedMessage, _connection.getReference());
try (MessageReference reference = amqMessage.newReference()) {
_currentMessage = null;
final boolean immediate = messagePublishInfo.isImmediate();
final InstanceProperties instanceProperties = new InstanceProperties() {
@Override
public Object getProperty(final Property prop) {
switch(prop) {
case EXPIRATION:
return amqMessage.getExpiration();
case IMMEDIATE:
return immediate;
case PERSISTENT:
return amqMessage.isPersistent();
case MANDATORY:
return messagePublishInfo.isMandatory();
case REDELIVERED:
return false;
}
return null;
}
};
final RoutingResult<AMQMessage> result = destination.route(amqMessage, amqMessage.getInitialRoutingAddress(), instanceProperties);
int enqueues = result.send(_transaction, immediate ? _immediateAction : null);
if (enqueues == 0) {
boolean mandatory = amqMessage.isMandatory();
boolean closeOnNoRoute = _connection.isCloseWhenNoRoute();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Unroutable message exchange='{}', routing key='{}', mandatory={}," + " transactionalSession={}, closeOnNoRoute={}, confirmOnPublish={}", exchangeName, routingKey, mandatory, isTransactional(), closeOnNoRoute, _confirmOnPublish);
}
int errorCode = ErrorCodes.NO_ROUTE;
String errorMessage = String.format("No route for message with exchange '%s' and routing key '%s'", exchangeName, routingKey);
if (result.containsReject(RejectType.LIMIT_EXCEEDED)) {
errorCode = ErrorCodes.RESOURCE_ERROR;
errorMessage = errorMessage + ":" + result.getRejectReason();
}
if (mandatory && isTransactional() && !_confirmOnPublish && _connection.isCloseWhenNoRoute()) {
_connection.sendConnectionClose(errorCode, errorMessage, _channelId);
} else {
if (mandatory || amqMessage.isImmediate()) {
if (_confirmOnPublish) {
_connection.writeFrame(new AMQFrame(_channelId, new BasicNackBody(_confirmedMessageCounter, false, false)));
}
_transaction.addPostTransactionAction(new WriteReturnAction(errorCode, errorMessage, amqMessage));
} else {
if (_confirmOnPublish) {
_connection.writeFrame(new AMQFrame(_channelId, new BasicAckBody(_confirmedMessageCounter, false)));
}
message(ExchangeMessages.DISCARDMSG(exchangeName, routingKey));
}
}
} else {
if (_confirmOnPublish) {
recordFuture(Futures.immediateFuture(null), new ServerTransaction.Action() {
private final long _deliveryTag = _confirmedMessageCounter;
@Override
public void postCommit() {
BasicAckBody body = _connection.getMethodRegistry().createBasicAckBody(_deliveryTag, false);
_connection.writeFrame(body.generateFrame(_channelId));
}
@Override
public void onRollback() {
final BasicNackBody body = new BasicNackBody(_deliveryTag, false, false);
_connection.writeFrame(new AMQFrame(_channelId, body));
}
});
}
}
}
} finally {
_connection.registerMessageReceived(bodySize);
if (isTransactional()) {
_connection.registerTransactedMessageReceived();
}
_currentMessage = null;
}
} catch (AccessControlException e) {
_connection.sendConnectionClose(ErrorCodes.ACCESS_REFUSED, e.getMessage(), getChannelId());
}
}
}
use of org.apache.qpid.server.message.MessageReference in project qpid-broker-j by apache.
the class AbstractQueueTestBase method createMessage.
protected ServerMessage createMessage(Long id) {
AMQMessageHeader header = mock(AMQMessageHeader.class);
when(header.getMessageId()).thenReturn(String.valueOf(id));
ServerMessage message = mock(ServerMessage.class);
when(message.getMessageNumber()).thenReturn(id);
when(message.getMessageHeader()).thenReturn(header);
StoredMessage storedMessage = mock(StoredMessage.class);
when(message.getStoredMessage()).thenReturn(storedMessage);
MessageReference ref = mock(MessageReference.class);
when(ref.getMessage()).thenReturn(message);
when(message.newReference()).thenReturn(ref);
when(message.newReference(any(TransactionLogResource.class))).thenReturn(ref);
return message;
}
use of org.apache.qpid.server.message.MessageReference in project qpid-broker-j by apache.
the class FlowToDiskOverflowPolicyHandlerTest method createMessage.
private ServerMessage createMessage(long size) {
ServerMessage message = mock(ServerMessage.class);
when(message.getSizeIncludingHeader()).thenReturn(size);
StoredMessage storedMessage = mock(StoredMessage.class);
when(message.getStoredMessage()).thenReturn(storedMessage);
MessageReference ref = mock(MessageReference.class);
when(ref.getMessage()).thenReturn(message);
when(message.newReference()).thenReturn(ref);
when(message.newReference(any(TransactionLogResource.class))).thenReturn(ref);
return message;
}
use of org.apache.qpid.server.message.MessageReference in project qpid-broker-j by apache.
the class QueueEntryImplTestBase method testGetNext.
/**
* Tests if entries in DEQUEUED or DELETED state are not returned by getNext method.
*/
public void testGetNext() throws Exception {
int numberOfEntries = 5;
QueueEntryImpl[] entries = new QueueEntryImpl[numberOfEntries];
Map<String, Object> queueAttributes = new HashMap<String, Object>();
queueAttributes.put(Queue.ID, UUID.randomUUID());
queueAttributes.put(Queue.NAME, getName());
final QueueManagingVirtualHost virtualHost = BrokerTestHelper.createVirtualHost("testVH");
StandardQueueImpl queue = new StandardQueueImpl(queueAttributes, virtualHost);
queue.open();
OrderedQueueEntryList queueEntryList = queue.getEntries();
// create test entries
for (int i = 0; i < numberOfEntries; i++) {
ServerMessage message = mock(ServerMessage.class);
when(message.getMessageNumber()).thenReturn((long) i);
final MessageReference reference = mock(MessageReference.class);
when(reference.getMessage()).thenReturn(message);
when(message.newReference()).thenReturn(reference);
when(message.newReference(any(TransactionLogResource.class))).thenReturn(reference);
QueueEntryImpl entry = (QueueEntryImpl) queueEntryList.add(message, null);
entries[i] = entry;
}
// test getNext for not acquired entries
for (int i = 0; i < numberOfEntries; i++) {
QueueEntryImpl queueEntry = entries[i];
QueueEntry next = queueEntry.getNextValidEntry();
if (i < numberOfEntries - 1) {
assertEquals("Unexpected entry from QueueEntryImpl#getNext()", entries[i + 1], next);
} else {
assertNull("The next entry after the last should be null", next);
}
}
// discard second
entries[1].acquire();
entries[1].delete();
// discard third
entries[2].acquire();
entries[2].delete();
QueueEntry next = entries[0].getNextValidEntry();
assertEquals("expected forth entry", entries[3], next);
next = next.getNextValidEntry();
assertEquals("expected fifth entry", entries[4], next);
next = next.getNextValidEntry();
assertNull("The next entry after the last should be null", next);
}
use of org.apache.qpid.server.message.MessageReference in project qpid-broker-j by apache.
the class SimpleQueueEntryImplTest method getQueueEntryImpl.
@Override
public QueueEntryImpl getQueueEntryImpl(int msgId) {
ServerMessage message = mock(ServerMessage.class);
when(message.getMessageNumber()).thenReturn((long) msgId);
final MessageReference reference = mock(MessageReference.class);
when(reference.getMessage()).thenReturn(message);
when(message.newReference()).thenReturn(reference);
when(message.newReference(any(TransactionLogResource.class))).thenReturn(reference);
return (QueueEntryImpl) queueEntryList.add(message, null);
}
Aggregations