use of org.apache.qpid.server.message.MessageReference in project qpid-broker-j by apache.
the class ServerSessionDelegate method messageTransfer.
@Override
public void messageTransfer(ServerSession ssn, final MessageTransfer xfr) {
try {
if (ssn.blockingTimeoutExceeded()) {
getEventLogger(ssn).message(ChannelMessages.FLOW_CONTROL_IGNORED());
ssn.close(ErrorCodes.MESSAGE_TOO_LARGE, "Session flow control was requested, but not enforced by sender");
} else if (xfr.getBodySize() > ssn.getConnection().getMaxMessageSize()) {
exception(ssn, xfr, ExecutionErrorCode.RESOURCE_LIMIT_EXCEEDED, "Message size of " + xfr.getBodySize() + " greater than allowed maximum of " + ssn.getConnection().getMaxMessageSize());
} else {
final MessageDestination destination = getDestinationForMessage(ssn, xfr);
final DeliveryProperties delvProps = xfr.getHeader() == null ? null : xfr.getHeader().getDeliveryProperties();
if (delvProps != null && delvProps.hasTtl() && !delvProps.hasExpiration()) {
delvProps.setExpiration(System.currentTimeMillis() + delvProps.getTtl());
}
final MessageMetaData_0_10 messageMetaData = new MessageMetaData_0_10(xfr);
final NamedAddressSpace virtualHost = getAddressSpace(ssn);
try {
ssn.getAMQPConnection().checkAuthorizedMessagePrincipal(getMessageUserId(xfr));
ssn.authorisePublish(destination, messageMetaData.getRoutingKey(), messageMetaData.isImmediate(), ssn.getAMQPConnection().getLastReadTime());
} catch (AccessControlException e) {
ExecutionErrorCode errorCode = ExecutionErrorCode.UNAUTHORIZED_ACCESS;
exception(ssn, xfr, errorCode, e.getMessage());
return;
}
final MessageStore store = virtualHost.getMessageStore();
final StoredMessage<MessageMetaData_0_10> storeMessage = createStoreMessage(xfr, messageMetaData, store);
final MessageTransferMessage message = new MessageTransferMessage(storeMessage, ssn.getReference());
MessageReference<MessageTransferMessage> reference = message.newReference();
try {
final InstanceProperties instanceProperties = new InstanceProperties() {
@Override
public Object getProperty(final Property prop) {
switch(prop) {
case EXPIRATION:
return message.getExpiration();
case IMMEDIATE:
return message.isImmediate();
case MANDATORY:
return (delvProps == null || !delvProps.getDiscardUnroutable()) && xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT;
case PERSISTENT:
return message.isPersistent();
case REDELIVERED:
return delvProps.getRedelivered();
}
return null;
}
};
RoutingResult<MessageTransferMessage> routingResult = ssn.enqueue(message, instanceProperties, destination);
boolean explictlyRejected = routingResult.containsReject(RejectType.LIMIT_EXCEEDED);
if (!routingResult.hasRoutes() || explictlyRejected) {
boolean closeWhenNoRoute = ssn.getAMQPConnection().getPort().getCloseWhenNoRoute();
boolean discardUnroutable = delvProps != null && delvProps.getDiscardUnroutable();
if (!discardUnroutable && xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT) {
RangeSet rejects = RangeSetFactory.createRangeSet();
rejects.add(xfr.getId());
MessageReject reject = new MessageReject(rejects, MessageRejectCode.UNROUTABLE, "Unroutable");
ssn.invoke(reject);
} else if (!discardUnroutable && closeWhenNoRoute && explictlyRejected) {
ExecutionErrorCode code = ExecutionErrorCode.RESOURCE_LIMIT_EXCEEDED;
String errorMessage = String.format("No route for message with destination '%s' and routing key '%s' : %s", xfr.getDestination(), message.getInitialRoutingAddress(), routingResult.getRejectReason());
ExecutionException ex = new ExecutionException();
ex.setErrorCode(code);
ex.setDescription(errorMessage);
ssn.invoke(ex);
ssn.close(ErrorCodes.RESOURCE_ERROR, errorMessage);
return;
} else {
getEventLogger(ssn).message(ExchangeMessages.DISCARDMSG(destination.getName(), messageMetaData.getRoutingKey()));
}
}
// TODO: we currently do not send MessageAccept when AcceptMode is EXPLICIT
if (ssn.isTransactional()) {
ssn.processed(xfr);
} else {
ssn.recordFuture(Futures.immediateFuture(null), new CommandProcessedAction(ssn, xfr));
}
} catch (VirtualHostUnavailableException e) {
getServerConnection(ssn).sendConnectionCloseAsync(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage());
} finally {
reference.release();
}
}
} finally {
xfr.dispose();
}
}
use of org.apache.qpid.server.message.MessageReference in project qpid-broker-j by apache.
the class AbstractQueue method checkMessageStatus.
@Override
public void checkMessageStatus() {
QueueEntryIterator queueListIterator = getEntries().iterator();
final Set<NotificationCheck> perMessageChecks = new HashSet<>();
final Set<NotificationCheck> queueLevelChecks = new HashSet<>();
for (NotificationCheck check : getNotificationChecks()) {
if (check.isMessageSpecific()) {
perMessageChecks.add(check);
} else {
queueLevelChecks.add(check);
}
}
QueueNotificationListener listener = _notificationListener;
final long currentTime = System.currentTimeMillis();
final long thresholdTime = currentTime - getAlertRepeatGap();
while (!_stopped.get() && queueListIterator.advance()) {
final QueueEntry node = queueListIterator.getNode();
// Only process nodes that are not currently deleted and not dequeued
if (!node.isDeleted()) {
// If the node has expired then acquire it
if (node.expired()) {
deleteEntry(node, () -> _queueStatistics.addToExpired(node.getSizeWithHeader()));
} else {
node.checkHeld(currentTime);
// There is a chance that the node could be deleted by
// the time the check actually occurs. So verify we
// can actually get the message to perform the check.
ServerMessage msg = node.getMessage();
if (msg != null) {
try (MessageReference messageReference = msg.newReference()) {
for (NotificationCheck check : perMessageChecks) {
checkForNotification(msg, listener, currentTime, thresholdTime, check);
}
} catch (MessageDeletedException e) {
// Ignore
}
}
}
}
}
for (NotificationCheck check : queueLevelChecks) {
checkForNotification(null, listener, currentTime, thresholdTime, check);
}
}
use of org.apache.qpid.server.message.MessageReference in project qpid-broker-j by apache.
the class AbstractQueue method visit.
@Override
public void visit(final QueueEntryVisitor visitor) {
QueueEntryIterator queueListIterator = getEntries().iterator();
while (queueListIterator.advance()) {
QueueEntry node = queueListIterator.getNode();
MessageReference reference = node.newMessageReference();
if (reference != null) {
try {
final boolean done = !node.isDeleted() && visitor.visit(node);
if (done) {
break;
}
} finally {
reference.release();
}
}
}
}
use of org.apache.qpid.server.message.MessageReference in project qpid-broker-j by apache.
the class AbstractQueue method attemptDelivery.
/**
* Attempt delivery for the given consumer.
*
* Looks up the next node for the consumer and attempts to deliver it.
*
* @param sub the consumer
* @return true if we have completed all possible deliveries for this sub.
*/
private MessageContainer attemptDelivery(QueueConsumer<?, ?> sub) {
// avoid referring old deleted queue entry in sub._queueContext._lastSeen
QueueEntry node = getNextAvailableEntry(sub);
boolean subActive = sub.isActive() && !sub.isSuspended();
if (node != null && subActive && (sub.getPriority() == Integer.MAX_VALUE || noHigherPriorityWithCredit(sub, node))) {
if (_virtualHost.getState() != State.ACTIVE) {
throw new ConnectionScopedRuntimeException("Delivery halted owing to " + "virtualhost state " + _virtualHost.getState());
}
if (node.isAvailable() && mightAssign(sub, node)) {
if (sub.allocateCredit(node)) {
MessageReference messageReference = null;
if ((sub.acquires() && !assign(sub, node)) || (!sub.acquires() && (messageReference = node.newMessageReference()) == null)) {
// restore credit here that would have been taken away by allocateCredit since we didn't manage
// to acquire the entry for this consumer
sub.restoreCredit(node);
} else {
setLastSeenEntry(sub, node);
return new MessageContainer(node, messageReference);
}
} else {
sub.awaitCredit(node);
}
}
}
return NO_MESSAGES;
}
use of org.apache.qpid.server.message.MessageReference in project qpid-broker-j by apache.
the class AbstractQueue method reallocateMessages.
@Override
public void reallocateMessages() {
QueueEntryIterator queueListIterator = getEntries().iterator();
while (!_stopped.get() && queueListIterator.advance()) {
final QueueEntry node = queueListIterator.getNode();
if (!node.isDeleted() && !node.expired()) {
try {
final ServerMessage message = node.getMessage();
final MessageReference messageReference = message.newReference();
try {
message.getStoredMessage().reallocate();
} finally {
messageReference.release();
}
} catch (MessageDeletedException mde) {
// Ignore
}
}
}
}
Aggregations