Search in sources :

Example 16 with OperationContext

use of org.apache.activemq.artemis.core.persistence.OperationContext in project activemq-artemis by apache.

the class AMQPSessionCallback method serverSend.

public void serverSend(final ProtonServerReceiverContext context, final Transaction transaction, final Receiver receiver, final Delivery delivery, SimpleString address, int messageFormat, byte[] data) throws Exception {
    AMQPMessage message = new AMQPMessage(messageFormat, data, coreMessageObjectPools);
    if (address != null) {
        message.setAddress(address);
    } else {
        // Anonymous relay must set a To value
        address = message.getAddressSimpleString();
        if (address == null) {
            rejectMessage(delivery, Symbol.valueOf("failed"), "Missing 'to' field for message sent to an anonymous producer");
            return;
        }
    }
    // here check queue-autocreation
    RoutingType routingType = context.getRoutingType(receiver, address);
    if (!bindingQuery(address, routingType)) {
        throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.addressDoesntExist();
    }
    OperationContext oldcontext = recoverContext();
    try {
        PagingStore store = manager.getServer().getPagingManager().getPageStore(message.getAddressSimpleString());
        if (store.isRejectingMessages()) {
            // We drop pre-settled messages (and abort any associated Tx)
            if (delivery.remotelySettled()) {
                if (transaction != null) {
                    String amqpAddress = delivery.getLink().getTarget().getAddress();
                    ActiveMQException e = new ActiveMQAMQPResourceLimitExceededException("Address is full: " + amqpAddress);
                    transaction.markAsRollbackOnly(e);
                }
            } else {
                rejectMessage(delivery, AmqpError.RESOURCE_LIMIT_EXCEEDED, "Address is full: " + address);
            }
        } else {
            serverSend(transaction, message, delivery, receiver);
        }
    } finally {
        resetContext(oldcontext);
    }
}
Also used : OperationContext(org.apache.activemq.artemis.core.persistence.OperationContext) ActiveMQException(org.apache.activemq.artemis.api.core.ActiveMQException) ActiveMQAMQPResourceLimitExceededException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPResourceLimitExceededException) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) PagingStore(org.apache.activemq.artemis.core.paging.PagingStore) RoutingType(org.apache.activemq.artemis.api.core.RoutingType)

Example 17 with OperationContext

use of org.apache.activemq.artemis.core.persistence.OperationContext in project activemq-artemis by apache.

the class AMQPSessionCallback method recoverContext.

public OperationContext recoverContext() {
    OperationContext oldContext = storageManager.getContext();
    manager.getServer().getStorageManager().setContext(serverSession.getSessionContext());
    return oldContext;
}
Also used : OperationContext(org.apache.activemq.artemis.core.persistence.OperationContext)

Example 18 with OperationContext

use of org.apache.activemq.artemis.core.persistence.OperationContext in project activemq-artemis by apache.

the class ProtonServerSenderContext method onMessage.

@Override
public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
    if (closed) {
        return;
    }
    OperationContext oldContext = sessionSPI.recoverContext();
    try {
        Message message = ((MessageReference) delivery.getContext()).getMessage();
        boolean preSettle = sender.getRemoteSenderSettleMode() == SenderSettleMode.SETTLED;
        DeliveryState remoteState;
        connection.lock();
        try {
            remoteState = delivery.getRemoteState();
        } finally {
            connection.unlock();
        }
        boolean settleImmediate = true;
        if (remoteState instanceof Accepted) {
            // acking again would show an exception but would have no negative effect but best to handle anyway.
            if (delivery.isSettled()) {
                return;
            }
            // from dealer, a perf hit but a must
            try {
                sessionSPI.ack(null, brokerConsumer, message);
            } catch (Exception e) {
                log.warn(e.toString(), e);
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorAcknowledgingMessage(message.toString(), e.getMessage());
            }
        } else if (remoteState instanceof TransactionalState) {
            // When the message arrives with a TransactionState disposition the ack should
            // enlist the message into the transaction associated with the given txn ID.
            TransactionalState txState = (TransactionalState) remoteState;
            ProtonTransactionImpl tx = (ProtonTransactionImpl) this.sessionSPI.getTransaction(txState.getTxnId(), false);
            if (txState.getOutcome() != null) {
                settleImmediate = false;
                Outcome outcome = txState.getOutcome();
                if (outcome instanceof Accepted) {
                    if (!delivery.remotelySettled()) {
                        TransactionalState txAccepted = new TransactionalState();
                        txAccepted.setOutcome(Accepted.getInstance());
                        txAccepted.setTxnId(txState.getTxnId());
                        connection.lock();
                        try {
                            delivery.disposition(txAccepted);
                        } finally {
                            connection.unlock();
                        }
                    }
                    // from dealer, a perf hit but a must
                    try {
                        sessionSPI.ack(tx, brokerConsumer, message);
                        tx.addDelivery(delivery, this);
                    } catch (Exception e) {
                        throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorAcknowledgingMessage(message.toString(), e.getMessage());
                    }
                }
            }
        } else if (remoteState instanceof Released) {
            try {
                sessionSPI.cancel(brokerConsumer, message, false);
            } catch (Exception e) {
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
            }
        } else if (remoteState instanceof Rejected) {
            try {
                sessionSPI.reject(brokerConsumer, message);
            } catch (Exception e) {
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
            }
        } else if (remoteState instanceof Modified) {
            try {
                Modified modification = (Modified) remoteState;
                if (Boolean.TRUE.equals(modification.getUndeliverableHere())) {
                    message.rejectConsumer(brokerConsumer.sequentialID());
                }
                if (Boolean.TRUE.equals(modification.getDeliveryFailed())) {
                    sessionSPI.cancel(brokerConsumer, message, true);
                } else {
                    sessionSPI.cancel(brokerConsumer, message, false);
                }
            } catch (Exception e) {
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
            }
        } else {
            log.debug("Received null or unknown disposition for delivery update: " + remoteState);
            return;
        }
        if (!preSettle) {
            protonSession.replaceTag(delivery.getTag());
        }
        if (settleImmediate) {
            settle(delivery);
        }
    } finally {
        sessionSPI.afterIO(new IOCallback() {

            @Override
            public void done() {
                connection.flush();
            }

            @Override
            public void onError(int errorCode, String errorMessage) {
                connection.flush();
            }
        });
        sessionSPI.resetContext(oldContext);
    }
}
Also used : OperationContext(org.apache.activemq.artemis.core.persistence.OperationContext) Released(org.apache.qpid.proton.amqp.messaging.Released) Modified(org.apache.qpid.proton.amqp.messaging.Modified) AMQPMessage(org.apache.activemq.artemis.protocol.amqp.broker.AMQPMessage) Message(org.apache.activemq.artemis.api.core.Message) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) IOCallback(org.apache.activemq.artemis.core.io.IOCallback) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) ActiveMQAMQPNotFoundException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPNotFoundException) ActiveMQAMQPException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException) FilterException(org.apache.activemq.artemis.selector.filter.FilterException) ActiveMQAMQPInternalErrorException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInternalErrorException) ActiveMQQueueExistsException(org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException) ActiveMQAMQPResourceLimitExceededException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPResourceLimitExceededException) ActiveMQAMQPIllegalStateException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPIllegalStateException) ActiveMQSecurityException(org.apache.activemq.artemis.api.core.ActiveMQSecurityException) TransactionalState(org.apache.qpid.proton.amqp.transaction.TransactionalState) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) Outcome(org.apache.qpid.proton.amqp.messaging.Outcome) ProtonTransactionImpl(org.apache.activemq.artemis.protocol.amqp.proton.transaction.ProtonTransactionImpl)

Aggregations

OperationContext (org.apache.activemq.artemis.core.persistence.OperationContext)18 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)7 CountDownLatch (java.util.concurrent.CountDownLatch)5 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)5 ArrayList (java.util.ArrayList)4 RoutingType (org.apache.activemq.artemis.api.core.RoutingType)4 Test (org.junit.Test)4 Configuration (org.apache.activemq.artemis.core.config.Configuration)3 DivertConfiguration (org.apache.activemq.artemis.core.config.DivertConfiguration)3 StoreConfiguration (org.apache.activemq.artemis.core.config.StoreConfiguration)3 DatabaseStorageConfiguration (org.apache.activemq.artemis.core.config.storage.DatabaseStorageConfiguration)3 IOCallback (org.apache.activemq.artemis.core.io.IOCallback)3 PagingManager (org.apache.activemq.artemis.core.paging.PagingManager)3 PagingStore (org.apache.activemq.artemis.core.paging.PagingStore)3 ServerSession (org.apache.activemq.artemis.core.server.ServerSession)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 ActiveMQSecurityException (org.apache.activemq.artemis.api.core.ActiveMQSecurityException)2 ReplicationManager (org.apache.activemq.artemis.core.replication.ReplicationManager)2 ActiveMQServerPlugin (org.apache.activemq.artemis.core.server.plugin.ActiveMQServerPlugin)2 ActiveMQAMQPResourceLimitExceededException (org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPResourceLimitExceededException)2