void abortableError(RuntimeException e) { result.setError(e); transitionToAbortableError(e); result.done(); }
@Test(expected = KafkaException.class) public void testMaybeAddPartitionToTransactionAfterAbortableError() { long pid = 13131L; short epoch = 1; doInitTransactions(pid, epoch); transactionManager.beginTransaction(); transactionManager.transitionToAbortableError(new KafkaException()); transactionManager.maybeAddPartitionToTransaction(new TopicPartition("foo", 0)); }
@Test(expected = KafkaException.class) public void testFailIfNotReadyForSendAfterAbortableError() { long pid = 13131L; short epoch = 1; doInitTransactions(pid, epoch); transactionManager.beginTransaction(); transactionManager.transitionToAbortableError(new KafkaException()); transactionManager.failIfNotReadyForSend(); }
transactionManager.transitionToFatalError(exception); } else if (transactionManager.isTransactional()) { transactionManager.transitionToAbortableError(exception);
@Test public void resendFailedProduceRequestAfterAbortableError() throws Exception { final long pid = 13131L; final short epoch = 1; doInitTransactions(pid, epoch); transactionManager.beginTransaction(); transactionManager.maybeAddPartitionToTransaction(tp0); Future<RecordMetadata> responseFuture = accumulator.append(tp0, time.milliseconds(), "key".getBytes(), "value".getBytes(), Record.EMPTY_HEADERS, null, MAX_BLOCK_TIMEOUT).future; prepareAddPartitionsToTxnResponse(Errors.NONE, tp0, epoch, pid); prepareProduceResponse(Errors.NOT_LEADER_FOR_PARTITION, pid, epoch); sender.run(time.milliseconds()); // Add partitions sender.run(time.milliseconds()); // Produce assertFalse(responseFuture.isDone()); transactionManager.transitionToAbortableError(new KafkaException()); prepareProduceResponse(Errors.NONE, pid, epoch); sender.run(time.milliseconds()); assertTrue(responseFuture.isDone()); assertNotNull(responseFuture.get()); // should throw the exception which caused the transaction to be aborted. }
@Test public void testIsSendToPartitionAllowedWithPendingPartitionAfterAbortableError() { final long pid = 13131L; final short epoch = 1; doInitTransactions(pid, epoch); transactionManager.beginTransaction(); transactionManager.maybeAddPartitionToTransaction(tp0); transactionManager.transitionToAbortableError(new KafkaException()); assertFalse(transactionManager.isSendToPartitionAllowed(tp0)); assertTrue(transactionManager.hasAbortableError()); }
@Test public void testIsSendToPartitionAllowedWithInFlightPartitionAddAfterAbortableError() { final long pid = 13131L; final short epoch = 1; doInitTransactions(pid, epoch); transactionManager.beginTransaction(); transactionManager.maybeAddPartitionToTransaction(tp0); // Send the AddPartitionsToTxn request and leave it in-flight sender.run(time.milliseconds()); transactionManager.transitionToAbortableError(new KafkaException()); assertFalse(transactionManager.isSendToPartitionAllowed(tp0)); assertTrue(transactionManager.hasAbortableError()); }
@Test public void testFindCoordinatorAllowedInAbortableErrorState() throws InterruptedException { final long pid = 13131L; final short epoch = 1; doInitTransactions(pid, epoch); transactionManager.beginTransaction(); transactionManager.maybeAddPartitionToTransaction(tp0); Future<RecordMetadata> responseFuture = accumulator.append(tp0, time.milliseconds(), "key".getBytes(), "value".getBytes(), Record.EMPTY_HEADERS, null, MAX_BLOCK_TIMEOUT).future; assertFalse(responseFuture.isDone()); sender.run(time.milliseconds()); // Send AddPartitionsRequest transactionManager.transitionToAbortableError(new KafkaException()); sendAddPartitionsToTxnResponse(Errors.NOT_COORDINATOR, tp0, epoch, pid); sender.run(time.milliseconds()); // AddPartitions returns assertTrue(transactionManager.hasAbortableError()); assertNull(transactionManager.coordinator(CoordinatorType.TRANSACTION)); prepareFindCoordinatorResponse(Errors.NONE, false, CoordinatorType.TRANSACTION, transactionalId); sender.run(time.milliseconds()); // FindCoordinator handled assertEquals(brokerNode, transactionManager.coordinator(CoordinatorType.TRANSACTION)); assertTrue(transactionManager.hasAbortableError()); }
@Test public void testIsSendToPartitionAllowedWithAddedPartitionAfterAbortableError() { final long pid = 13131L; final short epoch = 1; doInitTransactions(pid, epoch); transactionManager.beginTransaction(); transactionManager.maybeAddPartitionToTransaction(tp0); prepareAddPartitionsToTxnResponse(Errors.NONE, tp0, epoch, pid); sender.run(time.milliseconds()); assertFalse(transactionManager.hasPartitionsToAdd()); transactionManager.transitionToAbortableError(new KafkaException()); assertTrue(transactionManager.isSendToPartitionAllowed(tp0)); assertTrue(transactionManager.hasAbortableError()); }
@Test public void testHasOngoingTransactionAbortableError() { long pid = 13131L; short epoch = 1; TopicPartition partition = new TopicPartition("foo", 0); assertFalse(transactionManager.hasOngoingTransaction()); doInitTransactions(pid, epoch); assertFalse(transactionManager.hasOngoingTransaction()); transactionManager.beginTransaction(); assertTrue(transactionManager.hasOngoingTransaction()); transactionManager.maybeAddPartitionToTransaction(partition); assertTrue(transactionManager.hasOngoingTransaction()); prepareAddPartitionsToTxn(partition, Errors.NONE); sender.run(time.milliseconds()); transactionManager.transitionToAbortableError(new KafkaException()); assertTrue(transactionManager.hasOngoingTransaction()); transactionManager.beginAbort(); assertTrue(transactionManager.hasOngoingTransaction()); prepareEndTxnResponse(Errors.NONE, TransactionResult.ABORT, pid, epoch); sender.run(time.milliseconds()); assertFalse(transactionManager.hasOngoingTransaction()); }