Search in sources :

Example 11 with MessageReference

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();
    }
}
Also used : MessageStore(org.apache.qpid.server.store.MessageStore) MessageDestination(org.apache.qpid.server.message.MessageDestination) InstanceProperties(org.apache.qpid.server.message.InstanceProperties) NamedAddressSpace(org.apache.qpid.server.model.NamedAddressSpace) AccessControlException(java.security.AccessControlException) MessageReference(org.apache.qpid.server.message.MessageReference) RoutingResult(org.apache.qpid.server.message.RoutingResult) VirtualHostUnavailableException(org.apache.qpid.server.virtualhost.VirtualHostUnavailableException) StoredMessage(org.apache.qpid.server.store.StoredMessage) AbstractConfiguredObject(org.apache.qpid.server.model.AbstractConfiguredObject)

Example 12 with MessageReference

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);
    }
}
Also used : MessageDeletedException(org.apache.qpid.server.message.MessageDeletedException) ServerMessage(org.apache.qpid.server.message.ServerMessage) MessageReference(org.apache.qpid.server.message.MessageReference) HashSet(java.util.HashSet)

Example 13 with MessageReference

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();
            }
        }
    }
}
Also used : MessageReference(org.apache.qpid.server.message.MessageReference)

Example 14 with MessageReference

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;
}
Also used : MessageContainer(org.apache.qpid.server.message.MessageContainer) ConnectionScopedRuntimeException(org.apache.qpid.server.util.ConnectionScopedRuntimeException) MessageReference(org.apache.qpid.server.message.MessageReference)

Example 15 with MessageReference

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
            }
        }
    }
}
Also used : MessageDeletedException(org.apache.qpid.server.message.MessageDeletedException) ServerMessage(org.apache.qpid.server.message.ServerMessage) MessageReference(org.apache.qpid.server.message.MessageReference)

Aggregations

MessageReference (org.apache.qpid.server.message.MessageReference)20 ServerMessage (org.apache.qpid.server.message.ServerMessage)13 TransactionLogResource (org.apache.qpid.server.store.TransactionLogResource)10 StoredMessage (org.apache.qpid.server.store.StoredMessage)6 AMQMessageHeader (org.apache.qpid.server.message.AMQMessageHeader)5 MessageDeletedException (org.apache.qpid.server.message.MessageDeletedException)3 AccessControlException (java.security.AccessControlException)2 InstanceProperties (org.apache.qpid.server.message.InstanceProperties)2 MessageDestination (org.apache.qpid.server.message.MessageDestination)2 ContentHeaderBody (org.apache.qpid.server.protocol.v0_8.transport.ContentHeaderBody)2 MessagePublishInfo (org.apache.qpid.server.protocol.v0_8.transport.MessagePublishInfo)2 Transaction (org.apache.qpid.server.store.Transaction)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 MessageContainer (org.apache.qpid.server.message.MessageContainer)1 RoutingResult (org.apache.qpid.server.message.RoutingResult)1 AbstractConfiguredObject (org.apache.qpid.server.model.AbstractConfiguredObject)1 NamedAddressSpace (org.apache.qpid.server.model.NamedAddressSpace)1