Search in sources :

Example 16 with ProducerIdAndEpoch

use of org.apache.kafka.common.utils.ProducerIdAndEpoch in project kafka by apache.

the class SenderTest method testIdempotentInitProducerIdWithMaxInFlightOne.

/**
 * Verifies that InitProducerId of idempotent producer succeeds even if metadata requests
 * are pending with only one bootstrap node available and maxInFlight=1, where multiple
 * polls are necessary to send requests.
 */
@Test
public void testIdempotentInitProducerIdWithMaxInFlightOne() throws Exception {
    final long producerId = 123456L;
    createMockClientWithMaxFlightOneMetadataPending();
    // Initialize transaction manager. InitProducerId will be queued up until metadata response
    // is processed.
    TransactionManager transactionManager = createTransactionManager();
    setupWithTransactionState(transactionManager, false, null, false);
    ProducerIdAndEpoch producerIdAndEpoch = new ProducerIdAndEpoch(producerId, (short) 0);
    // Process metadata and InitProducerId responses.
    // Verify producerId after the sender is run to process responses.
    MetadataResponse metadataUpdate = RequestTestUtils.metadataUpdateWith(1, Collections.emptyMap());
    client.respond(metadataUpdate);
    sender.runOnce();
    sender.runOnce();
    client.respond(initProducerIdResponse(producerIdAndEpoch.producerId, producerIdAndEpoch.epoch, Errors.NONE));
    waitForProducerId(transactionManager, producerIdAndEpoch);
}
Also used : MetadataResponse(org.apache.kafka.common.requests.MetadataResponse) ProducerIdAndEpoch(org.apache.kafka.common.utils.ProducerIdAndEpoch) Test(org.junit.jupiter.api.Test)

Example 17 with ProducerIdAndEpoch

use of org.apache.kafka.common.utils.ProducerIdAndEpoch in project kafka by apache.

the class TransactionManagerTest method testEpochBumpAfterLastInflightBatchFails.

@Test
public void testEpochBumpAfterLastInflightBatchFails() {
    initializeTransactionManager(Optional.empty());
    ProducerIdAndEpoch producerIdAndEpoch = new ProducerIdAndEpoch(producerId, epoch);
    initializeIdempotentProducerId(producerId, epoch);
    TopicPartition tp0 = new TopicPartition("foo", 0);
    ProducerBatch b1 = writeIdempotentBatchWithValue(transactionManager, tp0, "1");
    ProducerBatch b2 = writeIdempotentBatchWithValue(transactionManager, tp0, "2");
    ProducerBatch b3 = writeIdempotentBatchWithValue(transactionManager, tp0, "3");
    assertEquals(Integer.valueOf(3), transactionManager.sequenceNumber(tp0));
    // The first batch fails with a timeout
    transactionManager.markSequenceUnresolved(b1);
    transactionManager.handleFailedBatch(b1, new TimeoutException(), false);
    assertTrue(transactionManager.hasUnresolvedSequences());
    // The second batch succeeds, but sequence numbers are still not resolved
    transactionManager.handleCompletedBatch(b2, new ProduceResponse.PartitionResponse(Errors.NONE, 500L, time.milliseconds(), 0L));
    transactionManager.bumpIdempotentEpochAndResetIdIfNeeded();
    assertEquals(producerIdAndEpoch, transactionManager.producerIdAndEpoch());
    assertTrue(transactionManager.hasUnresolvedSequences());
    // When the last inflight batch fails, we have to bump the epoch
    transactionManager.handleFailedBatch(b3, new TimeoutException(), false);
    // Run sender loop to trigger epoch bump
    runUntil(() -> transactionManager.producerIdAndEpoch().epoch == 2);
    assertFalse(transactionManager.hasUnresolvedSequences());
    assertEquals(0, transactionManager.sequenceNumber(tp0).intValue());
}
Also used : TopicPartition(org.apache.kafka.common.TopicPartition) ProduceResponse(org.apache.kafka.common.requests.ProduceResponse) ProducerIdAndEpoch(org.apache.kafka.common.utils.ProducerIdAndEpoch) TimeoutException(org.apache.kafka.common.errors.TimeoutException) Test(org.junit.jupiter.api.Test)

Example 18 with ProducerIdAndEpoch

use of org.apache.kafka.common.utils.ProducerIdAndEpoch in project kafka by apache.

the class RecordAccumulatorTest method testRecordsDrainedWhenTransactionCompleting.

@Test
public void testRecordsDrainedWhenTransactionCompleting() throws Exception {
    int batchSize = 1025;
    int deliveryTimeoutMs = 3200;
    int lingerMs = 10;
    long totalSize = 10 * batchSize;
    TransactionManager transactionManager = Mockito.mock(TransactionManager.class);
    RecordAccumulator accumulator = createTestRecordAccumulator(transactionManager, deliveryTimeoutMs, batchSize, totalSize, CompressionType.NONE, lingerMs);
    ProducerIdAndEpoch producerIdAndEpoch = new ProducerIdAndEpoch(12345L, (short) 5);
    Mockito.when(transactionManager.producerIdAndEpoch()).thenReturn(producerIdAndEpoch);
    Mockito.when(transactionManager.isSendToPartitionAllowed(tp1)).thenReturn(true);
    Mockito.when(transactionManager.isPartitionAdded(tp1)).thenReturn(true);
    Mockito.when(transactionManager.firstInFlightSequence(tp1)).thenReturn(0);
    // Initially, the transaction is still in progress, so we should respect the linger.
    Mockito.when(transactionManager.isCompleting()).thenReturn(false);
    accumulator.append(tp1, 0L, key, value, Record.EMPTY_HEADERS, null, maxBlockTimeMs, false, time.milliseconds());
    accumulator.append(tp1, 0L, key, value, Record.EMPTY_HEADERS, null, maxBlockTimeMs, false, time.milliseconds());
    assertTrue(accumulator.hasUndrained());
    RecordAccumulator.ReadyCheckResult firstResult = accumulator.ready(cluster, time.milliseconds());
    assertEquals(0, firstResult.readyNodes.size());
    Map<Integer, List<ProducerBatch>> firstDrained = accumulator.drain(cluster, firstResult.readyNodes, Integer.MAX_VALUE, time.milliseconds());
    assertEquals(0, firstDrained.size());
    // Once the transaction begins completion, then the batch should be drained immediately.
    Mockito.when(transactionManager.isCompleting()).thenReturn(true);
    RecordAccumulator.ReadyCheckResult secondResult = accumulator.ready(cluster, time.milliseconds());
    assertEquals(1, secondResult.readyNodes.size());
    Node readyNode = secondResult.readyNodes.iterator().next();
    Map<Integer, List<ProducerBatch>> secondDrained = accumulator.drain(cluster, secondResult.readyNodes, Integer.MAX_VALUE, time.milliseconds());
    assertEquals(Collections.singleton(readyNode.id()), secondDrained.keySet());
    List<ProducerBatch> batches = secondDrained.get(readyNode.id());
    assertEquals(1, batches.size());
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Node(org.apache.kafka.common.Node) Arrays.asList(java.util.Arrays.asList) List(java.util.List) ArrayList(java.util.ArrayList) ProducerIdAndEpoch(org.apache.kafka.common.utils.ProducerIdAndEpoch) Test(org.junit.jupiter.api.Test)

Example 19 with ProducerIdAndEpoch

use of org.apache.kafka.common.utils.ProducerIdAndEpoch in project kafka by apache.

the class TransactionManagerTest method testBumpEpochAfterTimeoutWithoutPendingInflightRequests.

@Test
public void testBumpEpochAfterTimeoutWithoutPendingInflightRequests() {
    initializeTransactionManager(Optional.empty());
    long producerId = 15L;
    short epoch = 5;
    ProducerIdAndEpoch producerIdAndEpoch = new ProducerIdAndEpoch(producerId, epoch);
    initializeIdempotentProducerId(producerId, epoch);
    // Nothing to resolve, so no reset is needed
    transactionManager.bumpIdempotentEpochAndResetIdIfNeeded();
    assertEquals(producerIdAndEpoch, transactionManager.producerIdAndEpoch());
    TopicPartition tp0 = new TopicPartition("foo", 0);
    assertEquals(Integer.valueOf(0), transactionManager.sequenceNumber(tp0));
    ProducerBatch b1 = writeIdempotentBatchWithValue(transactionManager, tp0, "1");
    assertEquals(Integer.valueOf(1), transactionManager.sequenceNumber(tp0));
    transactionManager.handleCompletedBatch(b1, new ProduceResponse.PartitionResponse(Errors.NONE, 500L, time.milliseconds(), 0L));
    assertEquals(OptionalInt.of(0), transactionManager.lastAckedSequence(tp0));
    // Marking sequence numbers unresolved without inflight requests is basically a no-op.
    transactionManager.markSequenceUnresolved(b1);
    transactionManager.maybeResolveSequences();
    assertEquals(producerIdAndEpoch, transactionManager.producerIdAndEpoch());
    assertFalse(transactionManager.hasUnresolvedSequences());
    // We have a new batch which fails with a timeout
    ProducerBatch b2 = writeIdempotentBatchWithValue(transactionManager, tp0, "2");
    assertEquals(Integer.valueOf(2), transactionManager.sequenceNumber(tp0));
    transactionManager.markSequenceUnresolved(b2);
    transactionManager.handleFailedBatch(b2, new TimeoutException(), false);
    assertTrue(transactionManager.hasUnresolvedSequences());
    // We only had one inflight batch, so we should be able to clear the unresolved status
    // and bump the epoch
    transactionManager.maybeResolveSequences();
    assertFalse(transactionManager.hasUnresolvedSequences());
    // Run sender loop to trigger epoch bump
    runUntil(() -> transactionManager.producerIdAndEpoch().epoch == 6);
}
Also used : TopicPartition(org.apache.kafka.common.TopicPartition) ProduceResponse(org.apache.kafka.common.requests.ProduceResponse) ProducerIdAndEpoch(org.apache.kafka.common.utils.ProducerIdAndEpoch) TimeoutException(org.apache.kafka.common.errors.TimeoutException) Test(org.junit.jupiter.api.Test)

Example 20 with ProducerIdAndEpoch

use of org.apache.kafka.common.utils.ProducerIdAndEpoch in project kafka by apache.

the class TransactionManagerTest method testNoProducerIdResetAfterLastInFlightBatchSucceeds.

@Test
public void testNoProducerIdResetAfterLastInFlightBatchSucceeds() {
    initializeTransactionManager(Optional.empty());
    long producerId = 15L;
    short epoch = 5;
    ProducerIdAndEpoch producerIdAndEpoch = new ProducerIdAndEpoch(producerId, epoch);
    initializeIdempotentProducerId(producerId, epoch);
    TopicPartition tp0 = new TopicPartition("foo", 0);
    ProducerBatch b1 = writeIdempotentBatchWithValue(transactionManager, tp0, "1");
    ProducerBatch b2 = writeIdempotentBatchWithValue(transactionManager, tp0, "2");
    ProducerBatch b3 = writeIdempotentBatchWithValue(transactionManager, tp0, "3");
    assertEquals(3, transactionManager.sequenceNumber(tp0).intValue());
    // The first batch fails with a timeout
    transactionManager.markSequenceUnresolved(b1);
    transactionManager.handleFailedBatch(b1, new TimeoutException(), false);
    assertTrue(transactionManager.hasUnresolvedSequences());
    // The reset should not occur until sequence numbers have been resolved
    transactionManager.bumpIdempotentEpochAndResetIdIfNeeded();
    assertEquals(producerIdAndEpoch, transactionManager.producerIdAndEpoch());
    assertTrue(transactionManager.hasUnresolvedSequences());
    // The second batch fails as well with a timeout
    transactionManager.handleFailedBatch(b2, new TimeoutException(), false);
    transactionManager.bumpIdempotentEpochAndResetIdIfNeeded();
    assertEquals(producerIdAndEpoch, transactionManager.producerIdAndEpoch());
    assertTrue(transactionManager.hasUnresolvedSequences());
    // The third batch succeeds, which should resolve the sequence number without
    // requiring a producerId reset.
    transactionManager.handleCompletedBatch(b3, new ProduceResponse.PartitionResponse(Errors.NONE, 500L, time.milliseconds(), 0L));
    transactionManager.maybeResolveSequences();
    assertEquals(producerIdAndEpoch, transactionManager.producerIdAndEpoch());
    assertFalse(transactionManager.hasUnresolvedSequences());
    assertEquals(3, transactionManager.sequenceNumber(tp0).intValue());
}
Also used : TopicPartition(org.apache.kafka.common.TopicPartition) ProduceResponse(org.apache.kafka.common.requests.ProduceResponse) ProducerIdAndEpoch(org.apache.kafka.common.utils.ProducerIdAndEpoch) TimeoutException(org.apache.kafka.common.errors.TimeoutException) Test(org.junit.jupiter.api.Test)

Aggregations

ProducerIdAndEpoch (org.apache.kafka.common.utils.ProducerIdAndEpoch)25 Test (org.junit.jupiter.api.Test)20 TopicPartition (org.apache.kafka.common.TopicPartition)11 AddPartitionsToTxnResponse (org.apache.kafka.common.requests.AddPartitionsToTxnResponse)8 Metrics (org.apache.kafka.common.metrics.Metrics)5 TimeoutException (org.apache.kafka.common.errors.TimeoutException)4 Node (org.apache.kafka.common.Node)3 ProduceResponse (org.apache.kafka.common.requests.ProduceResponse)3 ArrayList (java.util.ArrayList)2 ApiVersions (org.apache.kafka.clients.ApiVersions)2 MockClient (org.apache.kafka.clients.MockClient)2 NodeApiVersions (org.apache.kafka.clients.NodeApiVersions)2 RecordMetadata (org.apache.kafka.clients.producer.RecordMetadata)2 EndTxnResponseData (org.apache.kafka.common.message.EndTxnResponseData)2 EndTxnResponse (org.apache.kafka.common.requests.EndTxnResponse)2 MetadataResponse (org.apache.kafka.common.requests.MetadataResponse)2 LogContext (org.apache.kafka.common.utils.LogContext)2 ArrayDeque (java.util.ArrayDeque)1 Arrays.asList (java.util.Arrays.asList)1 List (java.util.List)1