use of org.apache.qpid.protonj2.engine.TransactionController in project qpid-protonj2 by apache.
the class ClientLocalTransactionContext method handleTransactionDischargeFailed.
private void handleTransactionDischargeFailed(Transaction<TransactionController> transaction) {
ClientFuture<Session> future = transaction.getAttachments().get(DISCHARGE_FUTURE_NAME);
LOG.trace("Discharge of transaction:{} failed", transaction);
ClientException cause = ClientExceptionSupport.convertToNonFatalException(transaction.getCondition());
future.failed(new ClientTransactionRolledBackException(cause.getMessage(), cause));
}
use of org.apache.qpid.protonj2.engine.TransactionController in project qpid-protonj2 by apache.
the class ProtonTransactionController method declare.
@Override
public TransactionController declare(Transaction<TransactionController> transaction) {
if (!senderLink.isSendable()) {
throw new IllegalStateException("Cannot Declare due to current capacity restrictions.");
}
if (transaction.getState() != TransactionState.IDLE) {
throw new IllegalStateException("Cannot declare a transaction that has already been used previously");
}
if (transaction.parent() != this) {
throw new IllegalArgumentException("Cannot declare a transaction that was created by another controller.");
}
ProtonControllerTransaction protonTransaction = (ProtonControllerTransaction) transaction;
protonTransaction.setState(TransactionState.DECLARING);
OutgoingDelivery command = senderLink.next();
command.setLinkedResource(protonTransaction);
try {
command.writeBytes(ENCODED_DECLARE);
} finally {
ENCODED_DECLARE.setReadIndex(0);
}
return this;
}
use of org.apache.qpid.protonj2.engine.TransactionController in project qpid-protonj2 by apache.
the class ProtonTransactionControllerTest method dischargeTransactionAfterConnectionDropsFollowingTxnDeclared.
public void dischargeTransactionAfterConnectionDropsFollowingTxnDeclared(boolean commit) throws Exception {
final byte[] txnId = new byte[] { 0, 1, 2, 3 };
Coordinator coordinator = new Coordinator();
coordinator.setCapabilities(TxnCapability.LOCAL_TXN);
Source source = new Source();
source.setOutcomes(DEFAULT_OUTCOMES);
Engine engine = EngineFactory.PROTON.createNonSaslEngine();
engine.errorHandler(result -> failure = result.failureCause());
ProtonTestConnector peer = createTestPeer(engine);
peer.expectAMQPHeader().respondWithAMQPHeader();
peer.expectOpen().respond();
peer.expectBegin().respond();
peer.expectCoordinatorAttach().respond();
peer.remoteFlow().withLinkCredit(2).queue();
peer.expectDeclare().accept(txnId);
peer.dropAfterLastHandler();
Connection connection = engine.start().open();
Session session = connection.session().open();
TransactionController txnController = session.coordinator("test-coordinator");
txnController.setSource(source);
txnController.setCoordinator(coordinator);
txnController.open();
Transaction<TransactionController> txn = txnController.newTransaction();
txnController.addCapacityAvailableHandler(controller -> {
controller.declare(txn);
});
peer.waitForScriptToComplete();
try {
if (commit) {
txnController.discharge(txn, false);
} else {
txnController.discharge(txn, true);
}
fail("Should have failed to discharge transaction");
} catch (EngineFailedException ex) {
// Expected error as a simulated IO disconnect was requested
LOG.info("Caught expected EngineFailedException on write of discharge", ex);
}
peer.waitForScriptToComplete(5, TimeUnit.SECONDS);
}
use of org.apache.qpid.protonj2.engine.TransactionController in project qpid-protonj2 by apache.
the class ProtonTransactionControllerTest method testTransactionControllerSignalsWhenEngineShutdown.
@Test
public void testTransactionControllerSignalsWhenEngineShutdown() {
final byte[] TXN_ID = new byte[] { 1, 2, 3, 4 };
Engine engine = EngineFactory.PROTON.createNonSaslEngine();
engine.errorHandler(result -> failure = result.failureCause());
ProtonTestConnector peer = createTestPeer(engine);
Coordinator coordinator = new Coordinator();
coordinator.setCapabilities(TxnCapability.LOCAL_TXN);
Source source = new Source();
source.setOutcomes(DEFAULT_OUTCOMES);
peer.expectAMQPHeader().respondWithAMQPHeader();
peer.expectOpen().respond();
peer.expectBegin().respond();
peer.expectAttach().withSource().withOutcomes(DEFAULT_OUTCOMES_STRINGS).and().withCoordinator().withCapabilities(TxnCapability.LOCAL_TXN.toString()).and().respond();
peer.remoteFlow().withLinkCredit(1).queue();
peer.expectDeclare().accept(TXN_ID);
Connection connection = engine.start().open();
Session session = connection.session().open();
TransactionController txnController = session.coordinator("test-coordinator");
txnController.setSource(source);
txnController.setCoordinator(coordinator);
final AtomicBoolean openedWithCoordinatorTarget = new AtomicBoolean();
txnController.openHandler(result -> {
if (result.getRemoteCoordinator() instanceof Coordinator) {
openedWithCoordinatorTarget.set(true);
}
});
final AtomicReference<byte[]> declaredTxnId = new AtomicReference<>();
txnController.declaredHandler(result -> {
declaredTxnId.set(result.getTxnId().arrayCopy());
});
final AtomicBoolean engineShutdown = new AtomicBoolean();
txnController.engineShutdownHandler((theEngine) -> {
engineShutdown.set(true);
});
txnController.open();
txnController.declare();
assertTrue(openedWithCoordinatorTarget.get());
engine.shutdown();
peer.waitForScriptToComplete();
assertTrue(engineShutdown.get());
assertNull(failure);
}
use of org.apache.qpid.protonj2.engine.TransactionController in project qpid-protonj2 by apache.
the class ProtonTransactionControllerTest method testTransactionControllerDeclaresTransaction.
@Test
public void testTransactionControllerDeclaresTransaction() {
Engine engine = EngineFactory.PROTON.createNonSaslEngine();
engine.errorHandler(result -> failure = result.failureCause());
ProtonTestConnector peer = createTestPeer(engine);
Coordinator coordinator = new Coordinator();
coordinator.setCapabilities(TxnCapability.LOCAL_TXN);
Source source = new Source();
source.setOutcomes(DEFAULT_OUTCOMES);
peer.expectAMQPHeader().respondWithAMQPHeader();
peer.expectOpen().respond();
peer.expectBegin().respond();
peer.expectAttach().withSource().withOutcomes(DEFAULT_OUTCOMES_STRINGS).and().withCoordinator().withCapabilities(TxnCapability.LOCAL_TXN.toString()).and().respond();
peer.remoteFlow().withLinkCredit(1).queue();
Connection connection = engine.start().open();
Session session = connection.session().open();
TransactionController txnController = session.coordinator("test-coordinator");
assertSame(session, txnController.getParent());
txnController.setSource(source);
txnController.setCoordinator(coordinator);
final AtomicBoolean openedWithCoordinatorTarget = new AtomicBoolean();
txnController.openHandler(result -> {
if (result.getRemoteCoordinator() instanceof Coordinator) {
openedWithCoordinatorTarget.set(true);
}
});
final byte[] TXN_ID = new byte[] { 1, 2, 3, 4 };
final AtomicReference<byte[]> declaredTxnId = new AtomicReference<>();
txnController.declaredHandler(result -> {
declaredTxnId.set(result.getTxnId().arrayCopy());
});
txnController.open();
peer.waitForScriptToComplete();
peer.expectDeclare().accept(TXN_ID);
assertTrue(openedWithCoordinatorTarget.get());
assertNotNull(txnController.declare());
peer.waitForScriptToComplete();
peer.expectDetach().withClosed(true).respond();
peer.expectEnd().respond();
peer.expectClose().respond();
assertArrayEquals(TXN_ID, declaredTxnId.get());
txnController.close();
session.close();
connection.close();
peer.waitForScriptToComplete();
assertNull(failure);
}
Aggregations