Search in sources :

Example 6 with AddPartitionsToTxnResponse

use of org.apache.kafka.common.requests.AddPartitionsToTxnResponse in project kafka by apache.

the class SenderTest method testTransactionAbortedExceptionOnAbortWithoutError.

@Test
public void testTransactionAbortedExceptionOnAbortWithoutError() throws InterruptedException, ExecutionException {
    ProducerIdAndEpoch producerIdAndEpoch = new ProducerIdAndEpoch(123456L, (short) 0);
    TransactionManager txnManager = new TransactionManager(logContext, "testTransactionAbortedExceptionOnAbortWithoutError", 60000, 100, apiVersions);
    setupWithTransactionState(txnManager, false, null);
    doInitTransactions(txnManager, producerIdAndEpoch);
    // Begin the transaction
    txnManager.beginTransaction();
    txnManager.maybeAddPartition(tp0);
    client.prepareResponse(new AddPartitionsToTxnResponse(0, Collections.singletonMap(tp0, Errors.NONE)));
    // Run it once so that the partition is added to the transaction.
    sender.runOnce();
    // Append a record to the accumulator.
    FutureRecordMetadata metadata = appendToAccumulator(tp0, time.milliseconds(), "key", "value");
    // Now abort the transaction manually.
    txnManager.beginAbort();
    // Try to send.
    // This should abort the existing transaction and
    // drain all the unsent batches with a TransactionAbortedException.
    sender.runOnce();
    // Now attempt to fetch the result for the record.
    TestUtils.assertFutureThrows(metadata, TransactionAbortedException.class);
}
Also used : AddPartitionsToTxnResponse(org.apache.kafka.common.requests.AddPartitionsToTxnResponse) ProducerIdAndEpoch(org.apache.kafka.common.utils.ProducerIdAndEpoch) Test(org.junit.jupiter.api.Test)

Example 7 with AddPartitionsToTxnResponse

use of org.apache.kafka.common.requests.AddPartitionsToTxnResponse in project kafka by apache.

the class SenderTest method testTransactionalSplitBatchAndSend.

@Test
public void testTransactionalSplitBatchAndSend() throws Exception {
    ProducerIdAndEpoch producerIdAndEpoch = new ProducerIdAndEpoch(123456L, (short) 0);
    TopicPartition tp = new TopicPartition("testSplitBatchAndSend", 1);
    TransactionManager txnManager = new TransactionManager(logContext, "testSplitBatchAndSend", 60000, 100, apiVersions);
    setupWithTransactionState(txnManager);
    doInitTransactions(txnManager, producerIdAndEpoch);
    txnManager.beginTransaction();
    txnManager.maybeAddPartition(tp);
    client.prepareResponse(new AddPartitionsToTxnResponse(0, Collections.singletonMap(tp, Errors.NONE)));
    sender.runOnce();
    testSplitBatchAndSend(txnManager, producerIdAndEpoch, tp);
}
Also used : TopicPartition(org.apache.kafka.common.TopicPartition) AddPartitionsToTxnResponse(org.apache.kafka.common.requests.AddPartitionsToTxnResponse) ProducerIdAndEpoch(org.apache.kafka.common.utils.ProducerIdAndEpoch) Test(org.junit.jupiter.api.Test)

Example 8 with AddPartitionsToTxnResponse

use of org.apache.kafka.common.requests.AddPartitionsToTxnResponse in project kafka by apache.

the class SenderTest method addPartitionToTxn.

private void addPartitionToTxn(Sender sender, TransactionManager txnManager, TopicPartition tp) {
    txnManager.maybeAddPartition(tp);
    client.prepareResponse(new AddPartitionsToTxnResponse(0, Collections.singletonMap(tp, Errors.NONE)));
    runUntil(sender, () -> txnManager.isPartitionAdded(tp));
    assertFalse(txnManager.hasInFlightRequest());
}
Also used : AddPartitionsToTxnResponse(org.apache.kafka.common.requests.AddPartitionsToTxnResponse)

Example 9 with AddPartitionsToTxnResponse

use of org.apache.kafka.common.requests.AddPartitionsToTxnResponse in project kafka by apache.

the class SenderTest method testTransactionalUnknownProducerHandlingWhenRetentionLimitReached.

@Test
public void testTransactionalUnknownProducerHandlingWhenRetentionLimitReached() throws Exception {
    final long producerId = 343434L;
    TransactionManager transactionManager = new TransactionManager(logContext, "testUnresolvedSeq", 60000, 100, apiVersions);
    setupWithTransactionState(transactionManager);
    doInitTransactions(transactionManager, new ProducerIdAndEpoch(producerId, (short) 0));
    assertTrue(transactionManager.hasProducerId());
    transactionManager.beginTransaction();
    transactionManager.maybeAddPartition(tp0);
    client.prepareResponse(new AddPartitionsToTxnResponse(0, Collections.singletonMap(tp0, Errors.NONE)));
    // Receive AddPartitions response
    sender.runOnce();
    assertEquals(0, transactionManager.sequenceNumber(tp0).longValue());
    // Send first ProduceRequest
    Future<RecordMetadata> request1 = appendToAccumulator(tp0);
    sender.runOnce();
    assertEquals(1, client.inFlightRequestCount());
    assertEquals(1, transactionManager.sequenceNumber(tp0).longValue());
    assertEquals(OptionalInt.empty(), transactionManager.lastAckedSequence(tp0));
    sendIdempotentProducerResponse(0, tp0, Errors.NONE, 1000L, 10L);
    // receive the response.
    sender.runOnce();
    assertTrue(request1.isDone());
    assertEquals(1000L, request1.get().offset());
    assertEquals(OptionalInt.of(0), transactionManager.lastAckedSequence(tp0));
    assertEquals(OptionalLong.of(1000L), transactionManager.lastAckedOffset(tp0));
    // Send second ProduceRequest, a single batch with 2 records.
    appendToAccumulator(tp0);
    Future<RecordMetadata> request2 = appendToAccumulator(tp0);
    sender.runOnce();
    assertEquals(3, transactionManager.sequenceNumber(tp0).longValue());
    assertEquals(OptionalInt.of(0), transactionManager.lastAckedSequence(tp0));
    assertFalse(request2.isDone());
    sendIdempotentProducerResponse(1, tp0, Errors.UNKNOWN_PRODUCER_ID, -1L, 1010L);
    // receive response 0, should be retried since the logStartOffset > lastAckedOffset.
    sender.runOnce();
    // We should have reset the sequence number state of the partition because the state was lost on the broker.
    assertEquals(OptionalInt.empty(), transactionManager.lastAckedSequence(tp0));
    assertEquals(2, transactionManager.sequenceNumber(tp0).longValue());
    assertFalse(request2.isDone());
    assertFalse(client.hasInFlightRequests());
    // should retry request 1
    sender.runOnce();
    // resend the request. Note that the expected sequence is 0, since we have lost producer state on the broker.
    sendIdempotentProducerResponse(0, tp0, Errors.NONE, 1011L, 1010L);
    // receive response 1
    sender.runOnce();
    assertEquals(OptionalInt.of(1), transactionManager.lastAckedSequence(tp0));
    assertEquals(2, transactionManager.sequenceNumber(tp0).longValue());
    assertFalse(client.hasInFlightRequests());
    assertTrue(request2.isDone());
    assertEquals(1012L, request2.get().offset());
    assertEquals(OptionalLong.of(1012L), transactionManager.lastAckedOffset(tp0));
}
Also used : RecordMetadata(org.apache.kafka.clients.producer.RecordMetadata) AddPartitionsToTxnResponse(org.apache.kafka.common.requests.AddPartitionsToTxnResponse) ProducerIdAndEpoch(org.apache.kafka.common.utils.ProducerIdAndEpoch) Test(org.junit.jupiter.api.Test)

Example 10 with AddPartitionsToTxnResponse

use of org.apache.kafka.common.requests.AddPartitionsToTxnResponse in project kafka by apache.

the class TransactionManagerTest method testCommitWithTopicAuthorizationFailureInAddPartitionsInFlight.

@Test
public void testCommitWithTopicAuthorizationFailureInAddPartitionsInFlight() throws InterruptedException {
    final TopicPartition tp0 = new TopicPartition("foo", 0);
    final TopicPartition tp1 = new TopicPartition("bar", 0);
    doInitTransactions();
    // Begin a transaction, send two records, and begin commit
    transactionManager.beginTransaction();
    transactionManager.maybeAddPartition(tp0);
    transactionManager.maybeAddPartition(tp1);
    FutureRecordMetadata firstPartitionAppend = appendToAccumulator(tp0);
    FutureRecordMetadata secondPartitionAppend = appendToAccumulator(tp1);
    TransactionalRequestResult commitResult = transactionManager.beginCommit();
    // We send the AddPartitionsToTxn request in the first sender call
    sender.runOnce();
    assertFalse(transactionManager.hasError());
    assertFalse(commitResult.isCompleted());
    assertFalse(firstPartitionAppend.isDone());
    // The AddPartitionsToTxn response returns in the next call with the error
    Map<TopicPartition, Errors> errors = new HashMap<>();
    errors.put(tp0, Errors.TOPIC_AUTHORIZATION_FAILED);
    errors.put(tp1, Errors.OPERATION_NOT_ATTEMPTED);
    client.respond(body -> {
        AddPartitionsToTxnRequest request = (AddPartitionsToTxnRequest) body;
        assertEquals(new HashSet<>(request.partitions()), new HashSet<>(errors.keySet()));
        return true;
    }, new AddPartitionsToTxnResponse(0, errors));
    sender.runOnce();
    assertTrue(transactionManager.hasError());
    assertFalse(commitResult.isCompleted());
    assertFalse(firstPartitionAppend.isDone());
    assertFalse(secondPartitionAppend.isDone());
    // The next call aborts the records, which have not yet been sent. It should
    // not block because there are no requests pending and we still need to cancel
    // the pending transaction commit.
    sender.runOnce();
    assertTrue(commitResult.isCompleted());
    TestUtils.assertFutureThrows(firstPartitionAppend, KafkaException.class);
    TestUtils.assertFutureThrows(secondPartitionAppend, KafkaException.class);
    assertTrue(commitResult.error() instanceof TopicAuthorizationException);
}
Also used : Errors(org.apache.kafka.common.protocol.Errors) HashMap(java.util.HashMap) TopicPartition(org.apache.kafka.common.TopicPartition) AddPartitionsToTxnRequest(org.apache.kafka.common.requests.AddPartitionsToTxnRequest) AddPartitionsToTxnResponse(org.apache.kafka.common.requests.AddPartitionsToTxnResponse) TopicAuthorizationException(org.apache.kafka.common.errors.TopicAuthorizationException) Test(org.junit.jupiter.api.Test)

Aggregations

AddPartitionsToTxnResponse (org.apache.kafka.common.requests.AddPartitionsToTxnResponse)12 Test (org.junit.jupiter.api.Test)9 ProducerIdAndEpoch (org.apache.kafka.common.utils.ProducerIdAndEpoch)8 TopicPartition (org.apache.kafka.common.TopicPartition)6 Metrics (org.apache.kafka.common.metrics.Metrics)3 RecordMetadata (org.apache.kafka.clients.producer.RecordMetadata)2 EndTxnResponseData (org.apache.kafka.common.message.EndTxnResponseData)2 AddPartitionsToTxnRequest (org.apache.kafka.common.requests.AddPartitionsToTxnRequest)2 EndTxnResponse (org.apache.kafka.common.requests.EndTxnResponse)2 HashMap (java.util.HashMap)1 Node (org.apache.kafka.common.Node)1 TopicAuthorizationException (org.apache.kafka.common.errors.TopicAuthorizationException)1 Errors (org.apache.kafka.common.protocol.Errors)1 Test (org.junit.Test)1 Timeout (org.junit.jupiter.api.Timeout)1