|
72 | 72 | import org.apache.kafka.common.errors.TopicAuthorizationException;
|
73 | 73 | import org.apache.kafka.common.errors.TopicDeletionDisabledException;
|
74 | 74 | import org.apache.kafka.common.errors.TopicExistsException;
|
| 75 | +import org.apache.kafka.common.errors.TransactionalIdAuthorizationException; |
75 | 76 | import org.apache.kafka.common.errors.UnknownMemberIdException;
|
76 | 77 | import org.apache.kafka.common.errors.UnknownServerException;
|
77 | 78 | import org.apache.kafka.common.errors.UnknownTopicIdException;
|
@@ -9746,6 +9747,92 @@ public void testAbortTransactionFindLeaderAfterDisconnect() throws Exception {
|
9746 | 9747 | }
|
9747 | 9748 | }
|
9748 | 9749 |
|
| 9750 | + @Test |
| 9751 | + public void testForceTerminateTransaction() throws Exception { |
| 9752 | + try (AdminClientUnitTestEnv env = mockClientEnv()) { |
| 9753 | + String transactionalId = "testForceTerminate"; |
| 9754 | + Node transactionCoordinator = env.cluster().nodes().iterator().next(); |
| 9755 | + |
| 9756 | + env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse( |
| 9757 | + Errors.NONE, |
| 9758 | + transactionalId, |
| 9759 | + transactionCoordinator |
| 9760 | + )); |
| 9761 | + |
| 9762 | + // Complete the init PID request successfully |
| 9763 | + InitProducerIdResponseData initProducerIdResponseData = new InitProducerIdResponseData() |
| 9764 | + .setProducerId(5678) |
| 9765 | + .setProducerEpoch((short) 123); |
| 9766 | + |
| 9767 | + env.kafkaClient().prepareResponseFrom(request -> |
| 9768 | + request instanceof InitProducerIdRequest, |
| 9769 | + new InitProducerIdResponse(initProducerIdResponseData), |
| 9770 | + transactionCoordinator |
| 9771 | + ); |
| 9772 | + |
| 9773 | + // Call force terminate and verify results |
| 9774 | + TerminateTransactionResult result = env.adminClient().forceTerminateTransaction(transactionalId); |
| 9775 | + assertNull(result.result().get()); |
| 9776 | + } |
| 9777 | + } |
| 9778 | + |
| 9779 | + @Test |
| 9780 | + public void testForceTerminateTransactionWithError() throws Exception { |
| 9781 | + try (AdminClientUnitTestEnv env = mockClientEnv()) { |
| 9782 | + String transactionalId = "testForceTerminateError"; |
| 9783 | + Node transactionCoordinator = env.cluster().nodes().iterator().next(); |
| 9784 | + |
| 9785 | + env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse( |
| 9786 | + Errors.NONE, |
| 9787 | + transactionalId, |
| 9788 | + transactionCoordinator |
| 9789 | + )); |
| 9790 | + |
| 9791 | + // Return an error from the InitProducerId request |
| 9792 | + env.kafkaClient().prepareResponseFrom(request -> |
| 9793 | + request instanceof InitProducerIdRequest, |
| 9794 | + new InitProducerIdResponse(new InitProducerIdResponseData() |
| 9795 | + .setErrorCode(Errors.TRANSACTIONAL_ID_AUTHORIZATION_FAILED.code())), |
| 9796 | + transactionCoordinator |
| 9797 | + ); |
| 9798 | + |
| 9799 | + // Call force terminate and verify error is propagated |
| 9800 | + TerminateTransactionResult result = env.adminClient().forceTerminateTransaction(transactionalId); |
| 9801 | + ExecutionException exception = assertThrows(ExecutionException.class, () -> result.result().get()); |
| 9802 | + assertTrue(exception.getCause() instanceof TransactionalIdAuthorizationException); |
| 9803 | + } |
| 9804 | + } |
| 9805 | + |
| 9806 | + @Test |
| 9807 | + public void testForceTerminateTransactionWithCustomTimeout() throws Exception { |
| 9808 | + try (AdminClientUnitTestEnv env = mockClientEnv()) { |
| 9809 | + String transactionalId = "testForceTerminateTimeout"; |
| 9810 | + Node transactionCoordinator = env.cluster().nodes().iterator().next(); |
| 9811 | + |
| 9812 | + env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse( |
| 9813 | + Errors.NONE, |
| 9814 | + transactionalId, |
| 9815 | + transactionCoordinator |
| 9816 | + )); |
| 9817 | + |
| 9818 | + // Complete the init PID request |
| 9819 | + InitProducerIdResponseData initProducerIdResponseData = new InitProducerIdResponseData() |
| 9820 | + .setProducerId(9012) |
| 9821 | + .setProducerEpoch((short) 456); |
| 9822 | + |
| 9823 | + env.kafkaClient().prepareResponseFrom(request -> |
| 9824 | + request instanceof InitProducerIdRequest, |
| 9825 | + new InitProducerIdResponse(initProducerIdResponseData), |
| 9826 | + transactionCoordinator |
| 9827 | + ); |
| 9828 | + |
| 9829 | + // Use custom timeout |
| 9830 | + TerminateTransactionOptions options = new TerminateTransactionOptions().timeoutMs(10000); |
| 9831 | + TerminateTransactionResult result = env.adminClient().forceTerminateTransaction(transactionalId, options); |
| 9832 | + assertNull(result.result().get()); |
| 9833 | + } |
| 9834 | + } |
| 9835 | + |
9749 | 9836 | @Test
|
9750 | 9837 | public void testListTransactions() throws Exception {
|
9751 | 9838 | try (AdminClientUnitTestEnv env = mockClientEnv()) {
|
|
0 commit comments