Search in sources :

Example 1 with AsyncResult

use of org.apache.activemq.transport.amqp.client.util.AsyncResult in project activemq-artemis by apache.

the class AmqpTransactionCoordinator method remotelyClosed.

// ----- Base class overrides ---------------------------------------------//
@Override
public void remotelyClosed(AmqpConnection connection) {
    Exception txnError = AmqpSupport.convertToException(getEndpoint().getRemoteCondition());
    // begin / commit / rollback operation.
    for (AsyncResult pendingRequest : pendingRequests.values()) {
        pendingRequest.onFailure(txnError);
    }
    // Purge linkages to pending operations.
    pendingDeliveries.clear();
    pendingRequests.clear();
    if (getEndpoint() != null) {
        getEndpoint().close();
        getEndpoint().free();
    }
    LOG.debug("Transaction Coordinator link {} was remotely closed", getEndpoint());
}
Also used : AsyncResult(org.apache.activemq.transport.amqp.client.util.AsyncResult) BufferOverflowException(java.nio.BufferOverflowException) IOException(java.io.IOException) IllegalStateException(javax.jms.IllegalStateException) JMSException(javax.jms.JMSException) TransactionRolledBackException(javax.jms.TransactionRolledBackException)

Example 2 with AsyncResult

use of org.apache.activemq.transport.amqp.client.util.AsyncResult in project activemq-artemis by apache.

the class AmqpSender method processDeliveryUpdates.

@Override
public void processDeliveryUpdates(AmqpConnection connection, Delivery updated) throws IOException {
    List<Delivery> toRemove = new ArrayList<>();
    for (Delivery delivery : pending) {
        DeliveryState state = delivery.getRemoteState();
        if (state == null) {
            continue;
        }
        doDeliveryUpdateInspection(delivery);
        Outcome outcome = null;
        if (state instanceof TransactionalState) {
            LOG.trace("State of delivery is Transactional, retrieving outcome: {}", state);
            outcome = ((TransactionalState) state).getOutcome();
        } else if (state instanceof Outcome) {
            outcome = (Outcome) state;
        } else {
            LOG.warn("Message send updated with unsupported state: {}", state);
            outcome = null;
        }
        AsyncResult request = (AsyncResult) delivery.getContext();
        Exception deliveryError = null;
        if (outcome instanceof Accepted) {
            LOG.trace("Outcome of delivery was accepted: {}", delivery);
            if (request != null && !request.isComplete()) {
                request.onSuccess();
            }
        } else if (outcome instanceof Rejected) {
            LOG.trace("Outcome of delivery was rejected: {}", delivery);
            ErrorCondition remoteError = ((Rejected) outcome).getError();
            if (remoteError == null) {
                remoteError = getEndpoint().getRemoteCondition();
            }
            deliveryError = AmqpSupport.convertToException(remoteError);
        } else if (outcome instanceof Released) {
            LOG.trace("Outcome of delivery was released: {}", delivery);
            deliveryError = new IOException("Delivery failed: released by receiver");
        } else if (outcome instanceof Modified) {
            LOG.trace("Outcome of delivery was modified: {}", delivery);
            deliveryError = new IOException("Delivery failed: failure at remote");
        }
        if (deliveryError != null) {
            if (request != null && !request.isComplete()) {
                request.onFailure(deliveryError);
            } else {
                connection.fireClientException(deliveryError);
            }
        }
        tagGenerator.returnTag(delivery.getTag());
        delivery.settle();
        toRemove.add(delivery);
    }
    pending.removeAll(toRemove);
}
Also used : Released(org.apache.qpid.proton.amqp.messaging.Released) Modified(org.apache.qpid.proton.amqp.messaging.Modified) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ArrayList(java.util.ArrayList) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) IOException(java.io.IOException) InvalidDestinationException(javax.jms.InvalidDestinationException) IOException(java.io.IOException) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) TransactionalState(org.apache.qpid.proton.amqp.transaction.TransactionalState) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) Outcome(org.apache.qpid.proton.amqp.messaging.Outcome) Delivery(org.apache.qpid.proton.engine.Delivery) AsyncResult(org.apache.activemq.transport.amqp.client.util.AsyncResult)

Example 3 with AsyncResult

use of org.apache.activemq.transport.amqp.client.util.AsyncResult in project activemq-artemis by apache.

the class AmqpTransactionContext method begin.

/**
 * Begins a new transaction scoped to the target session.
 *
 * @throws Exception if an error occurs while starting the transaction.
 */
public void begin() throws Exception {
    if (transactionId != null) {
        throw new IOException("Begin called while a TX is still Active.");
    }
    final AmqpTransactionId txId = session.getConnection().getNextTransactionId();
    final ClientFuture request = new ClientFuture(new ClientFutureSynchronization() {

        @Override
        public void onPendingSuccess() {
            transactionId = txId;
        }

        @Override
        public void onPendingFailure(Throwable cause) {
            transactionId = null;
        }
    });
    LOG.info("Attempting to Begin TX:[{}]", txId);
    session.getScheduler().execute(new Runnable() {

        @Override
        public void run() {
            if (coordinator == null || coordinator.isClosed()) {
                LOG.info("Creating new Coordinator for TX:[{}]", txId);
                coordinator = new AmqpTransactionCoordinator(session);
                coordinator.open(new AsyncResult() {

                    @Override
                    public void onSuccess() {
                        try {
                            LOG.info("Attempting to declare TX:[{}]", txId);
                            coordinator.declare(txId, request);
                        } catch (Exception e) {
                            request.onFailure(e);
                        }
                    }

                    @Override
                    public void onFailure(Throwable result) {
                        request.onFailure(result);
                    }

                    @Override
                    public boolean isComplete() {
                        return request.isComplete();
                    }
                });
            } else {
                try {
                    LOG.info("Attempting to declare TX:[{}]", txId);
                    coordinator.declare(txId, request);
                } catch (Exception e) {
                    request.onFailure(e);
                }
            }
            session.pumpToProtonTransport(request);
        }
    });
    request.sync();
}
Also used : ClientFutureSynchronization(org.apache.activemq.transport.amqp.client.util.ClientFutureSynchronization) ClientFuture(org.apache.activemq.transport.amqp.client.util.ClientFuture) IOException(java.io.IOException) AsyncResult(org.apache.activemq.transport.amqp.client.util.AsyncResult) IOException(java.io.IOException)

Example 4 with AsyncResult

use of org.apache.activemq.transport.amqp.client.util.AsyncResult in project activemq-artemis by apache.

the class AmqpTransactionCoordinator method processDeliveryUpdates.

@Override
public void processDeliveryUpdates(AmqpConnection connection, Delivery delivery) throws IOException {
    try {
        Iterator<Delivery> deliveries = pendingDeliveries.iterator();
        while (deliveries.hasNext()) {
            Delivery pendingDelivery = deliveries.next();
            if (!pendingDelivery.remotelySettled()) {
                continue;
            }
            DeliveryState state = pendingDelivery.getRemoteState();
            AmqpTransactionId txId = (AmqpTransactionId) pendingDelivery.getContext();
            AsyncResult pendingRequest = pendingRequests.get(txId);
            if (pendingRequest == null) {
                throw new IllegalStateException("Pending tx operation with no pending request");
            }
            if (state instanceof Declared) {
                LOG.debug("New TX started: {}", txId.getTxId());
                Declared declared = (Declared) state;
                txId.setRemoteTxId(declared.getTxnId());
                pendingRequest.onSuccess();
            } else if (state instanceof Rejected) {
                LOG.debug("Last TX request failed: {}", txId.getTxId());
                Rejected rejected = (Rejected) state;
                Exception cause = AmqpSupport.convertToException(rejected.getError());
                JMSException failureCause = null;
                if (txId.isCommit()) {
                    failureCause = new TransactionRolledBackException(cause.getMessage());
                } else {
                    failureCause = new JMSException(cause.getMessage());
                }
                pendingRequest.onFailure(failureCause);
            } else {
                LOG.debug("Last TX request succeeded: {}", txId.getTxId());
                pendingRequest.onSuccess();
            }
            // Clear state data
            pendingDelivery.settle();
            pendingRequests.remove(txId);
            deliveries.remove();
        }
        super.processDeliveryUpdates(connection, delivery);
    } catch (Exception e) {
        throw IOExceptionSupport.create(e);
    }
}
Also used : IllegalStateException(javax.jms.IllegalStateException) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) JMSException(javax.jms.JMSException) TransactionRolledBackException(javax.jms.TransactionRolledBackException) Delivery(org.apache.qpid.proton.engine.Delivery) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) AsyncResult(org.apache.activemq.transport.amqp.client.util.AsyncResult) Declared(org.apache.qpid.proton.amqp.transaction.Declared) BufferOverflowException(java.nio.BufferOverflowException) IOException(java.io.IOException) IllegalStateException(javax.jms.IllegalStateException) JMSException(javax.jms.JMSException) TransactionRolledBackException(javax.jms.TransactionRolledBackException)

Aggregations

IOException (java.io.IOException)4 AsyncResult (org.apache.activemq.transport.amqp.client.util.AsyncResult)4 BufferOverflowException (java.nio.BufferOverflowException)2 IllegalStateException (javax.jms.IllegalStateException)2 JMSException (javax.jms.JMSException)2 TransactionRolledBackException (javax.jms.TransactionRolledBackException)2 Rejected (org.apache.qpid.proton.amqp.messaging.Rejected)2 DeliveryState (org.apache.qpid.proton.amqp.transport.DeliveryState)2 Delivery (org.apache.qpid.proton.engine.Delivery)2 ArrayList (java.util.ArrayList)1 InvalidDestinationException (javax.jms.InvalidDestinationException)1 ClientFuture (org.apache.activemq.transport.amqp.client.util.ClientFuture)1 ClientFutureSynchronization (org.apache.activemq.transport.amqp.client.util.ClientFutureSynchronization)1 Accepted (org.apache.qpid.proton.amqp.messaging.Accepted)1 Modified (org.apache.qpid.proton.amqp.messaging.Modified)1 Outcome (org.apache.qpid.proton.amqp.messaging.Outcome)1 Released (org.apache.qpid.proton.amqp.messaging.Released)1 Declared (org.apache.qpid.proton.amqp.transaction.Declared)1 TransactionalState (org.apache.qpid.proton.amqp.transaction.TransactionalState)1 ErrorCondition (org.apache.qpid.proton.amqp.transport.ErrorCondition)1