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());
}
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);
}
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();
}
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);
}
}
Aggregations