use of org.apache.qpid.proton.amqp.transaction.Declared in project activemq-artemis by apache.
the class ProtonTransactionHandler method onMessage.
@Override
public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
final Receiver receiver;
try {
receiver = ((Receiver) delivery.getLink());
if (!delivery.isReadable()) {
return;
}
ByteBuffer buffer;
MessageImpl msg;
connection.lock();
try {
// transaction declare and discahrge operations.
if (receiver.getCredit() < amqpLowMark) {
receiver.flow(amqpCredit);
}
// the incoming request is to big just use a scratch buffer.
if (delivery.available() > DECODE_BUFFER.capacity()) {
buffer = ByteBuffer.allocate(delivery.available());
} else {
buffer = (ByteBuffer) DECODE_BUFFER.clear();
}
// Update Buffer for the next incoming command.
buffer.limit(receiver.recv(buffer.array(), buffer.arrayOffset(), buffer.capacity()));
receiver.advance();
msg = decodeMessage(buffer);
} finally {
connection.unlock();
}
Object action = ((AmqpValue) msg.getBody()).getValue();
if (action instanceof Declare) {
Binary txID = sessionSPI.newTransaction();
Declared declared = new Declared();
declared.setTxnId(txID);
IOCallback ioAction = new IOCallback() {
@Override
public void done() {
connection.lock();
try {
delivery.settle();
delivery.disposition(declared);
} finally {
connection.unlock();
connection.flush();
}
}
@Override
public void onError(int errorCode, String errorMessage) {
}
};
sessionSPI.afterIO(ioAction);
} else if (action instanceof Discharge) {
Discharge discharge = (Discharge) action;
Binary txID = discharge.getTxnId();
ProtonTransactionImpl tx = (ProtonTransactionImpl) sessionSPI.getTransaction(txID, true);
tx.discharge();
IOCallback ioAction = new IOCallback() {
@Override
public void done() {
connection.lock();
try {
delivery.settle();
delivery.disposition(new Accepted());
} finally {
connection.unlock();
connection.flush();
}
}
@Override
public void onError(int errorCode, String errorMessage) {
}
};
if (discharge.getFail()) {
sessionSPI.withinContext(() -> tx.rollback());
sessionSPI.afterIO(ioAction);
} else {
sessionSPI.withinContext(() -> tx.commit());
sessionSPI.afterIO(ioAction);
}
}
} catch (ActiveMQAMQPException amqpE) {
log.warn(amqpE.getMessage(), amqpE);
connection.lock();
try {
delivery.settle();
delivery.disposition(createRejected(amqpE.getAmqpError(), amqpE.getMessage()));
} finally {
connection.unlock();
}
connection.flush();
} catch (Throwable e) {
log.warn(e.getMessage(), e);
connection.lock();
try {
delivery.settle();
delivery.disposition(createRejected(Symbol.getSymbol("failed"), e.getMessage()));
} finally {
connection.unlock();
}
connection.flush();
}
}
use of org.apache.qpid.proton.amqp.transaction.Declared 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