Search in sources :

Example 31 with ProducerMetadata

use of org.apache.kafka.clients.producer.internals.ProducerMetadata in project kafka by apache.

the class KafkaProducerTest method testMetadataWithPartitionOutOfRange.

@ParameterizedTest
@ValueSource(booleans = { true, false })
public void testMetadataWithPartitionOutOfRange(boolean isIdempotenceEnabled) throws Exception {
    Map<String, Object> configs = new HashMap<>();
    configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9999");
    configs.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, 60000);
    configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, isIdempotenceEnabled);
    // Create a record with a partition higher than the initial (outdated) partition range
    ProducerRecord<String, String> record = new ProducerRecord<>(topic, 2, null, "value");
    ProducerMetadata metadata = mock(ProducerMetadata.class);
    MockTime mockTime = new MockTime();
    when(metadata.fetch()).thenReturn(onePartitionCluster, onePartitionCluster, threePartitionCluster);
    KafkaProducer<String, String> producer = producerWithOverrideNewSender(configs, metadata, mockTime);
    // One request update if metadata is available but outdated for the given record
    producer.send(record);
    verify(metadata, times(2)).requestUpdateForTopic(topic);
    verify(metadata, times(2)).awaitUpdate(anyInt(), anyLong());
    verify(metadata, times(3)).fetch();
    producer.close(Duration.ofMillis(0));
}
Also used : ProducerMetadata(org.apache.kafka.clients.producer.internals.ProducerMetadata) HashMap(java.util.HashMap) MockTime(org.apache.kafka.common.utils.MockTime) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 32 with ProducerMetadata

use of org.apache.kafka.clients.producer.internals.ProducerMetadata in project kafka by apache.

the class KafkaProducerTest method testSendToInvalidTopic.

@Test
public void testSendToInvalidTopic() throws Exception {
    Map<String, Object> configs = new HashMap<>();
    configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9000");
    configs.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, "15000");
    Time time = new MockTime();
    MetadataResponse initialUpdateResponse = RequestTestUtils.metadataUpdateWith(1, emptyMap());
    ProducerMetadata metadata = newMetadata(0, Long.MAX_VALUE);
    metadata.updateWithCurrentRequestVersion(initialUpdateResponse, false, time.milliseconds());
    MockClient client = new MockClient(time, metadata);
    Producer<String, String> producer = kafkaProducer(configs, new StringSerializer(), new StringSerializer(), metadata, client, null, time);
    // Invalid topic name due to space
    String invalidTopicName = "topic abc";
    ProducerRecord<String, String> record = new ProducerRecord<>(invalidTopicName, "HelloKafka");
    List<MetadataResponse.TopicMetadata> topicMetadata = new ArrayList<>();
    topicMetadata.add(new MetadataResponse.TopicMetadata(Errors.INVALID_TOPIC_EXCEPTION, invalidTopicName, false, Collections.emptyList()));
    MetadataResponse updateResponse = RequestTestUtils.metadataResponse(new ArrayList<>(initialUpdateResponse.brokers()), initialUpdateResponse.clusterId(), initialUpdateResponse.controller().id(), topicMetadata);
    client.prepareMetadataUpdate(updateResponse);
    Future<RecordMetadata> future = producer.send(record);
    assertEquals(Collections.singleton(invalidTopicName), metadata.fetch().invalidTopics(), "Cluster has incorrect invalid topic list.");
    TestUtils.assertFutureError(future, InvalidTopicException.class);
    producer.close(Duration.ofMillis(0));
}
Also used : ProducerMetadata(org.apache.kafka.clients.producer.internals.ProducerMetadata) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) MockTime(org.apache.kafka.common.utils.MockTime) Time(org.apache.kafka.common.utils.Time) MetadataResponse(org.apache.kafka.common.requests.MetadataResponse) StringSerializer(org.apache.kafka.common.serialization.StringSerializer) MockTime(org.apache.kafka.common.utils.MockTime) MockClient(org.apache.kafka.clients.MockClient) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Test(org.junit.jupiter.api.Test)

Example 33 with ProducerMetadata

use of org.apache.kafka.clients.producer.internals.ProducerMetadata in project kafka by apache.

the class KafkaProducerTest method testCloseWhenWaitingForMetadataUpdate.

@Test
public void testCloseWhenWaitingForMetadataUpdate() throws InterruptedException {
    Map<String, Object> configs = new HashMap<>();
    configs.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, Long.MAX_VALUE);
    configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9000");
    // Simulate a case where metadata for a particular topic is not available. This will cause KafkaProducer#send to
    // block in Metadata#awaitUpdate for the configured max.block.ms. When close() is invoked, KafkaProducer#send should
    // return with a KafkaException.
    String topicName = "test";
    Time time = Time.SYSTEM;
    MetadataResponse initialUpdateResponse = RequestTestUtils.metadataUpdateWith(1, emptyMap());
    ProducerMetadata metadata = new ProducerMetadata(0, Long.MAX_VALUE, Long.MAX_VALUE, new LogContext(), new ClusterResourceListeners(), time);
    metadata.updateWithCurrentRequestVersion(initialUpdateResponse, false, time.milliseconds());
    MockClient client = new MockClient(time, metadata);
    Producer<String, String> producer = kafkaProducer(configs, new StringSerializer(), new StringSerializer(), metadata, client, null, time);
    ExecutorService executor = Executors.newSingleThreadExecutor();
    final AtomicReference<Exception> sendException = new AtomicReference<>();
    try {
        executor.submit(() -> {
            try {
                // Metadata for topic "test" will not be available which will cause us to block indefinitely until
                // KafkaProducer#close is invoked.
                producer.send(new ProducerRecord<>(topicName, "key", "value"));
                fail();
            } catch (Exception e) {
                sendException.set(e);
            }
        });
        // Wait until metadata update for the topic has been requested
        TestUtils.waitForCondition(() -> metadata.containsTopic(topicName), "Timeout when waiting for topic to be added to metadata");
        producer.close(Duration.ofMillis(0));
        TestUtils.waitForCondition(() -> sendException.get() != null, "No producer exception within timeout");
        assertEquals(KafkaException.class, sendException.get().getClass());
    } finally {
        executor.shutdownNow();
    }
}
Also used : ProducerMetadata(org.apache.kafka.clients.producer.internals.ProducerMetadata) ClusterResourceListeners(org.apache.kafka.common.internals.ClusterResourceListeners) HashMap(java.util.HashMap) LogContext(org.apache.kafka.common.utils.LogContext) MockTime(org.apache.kafka.common.utils.MockTime) Time(org.apache.kafka.common.utils.Time) AtomicReference(java.util.concurrent.atomic.AtomicReference) KafkaException(org.apache.kafka.common.KafkaException) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) InterruptException(org.apache.kafka.common.errors.InterruptException) ExecutionException(java.util.concurrent.ExecutionException) RecordTooLargeException(org.apache.kafka.common.errors.RecordTooLargeException) TimeoutException(org.apache.kafka.common.errors.TimeoutException) ConfigException(org.apache.kafka.common.config.ConfigException) MetadataResponse(org.apache.kafka.common.requests.MetadataResponse) ExecutorService(java.util.concurrent.ExecutorService) StringSerializer(org.apache.kafka.common.serialization.StringSerializer) MockClient(org.apache.kafka.clients.MockClient) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Test(org.junit.jupiter.api.Test)

Example 34 with ProducerMetadata

use of org.apache.kafka.clients.producer.internals.ProducerMetadata in project kafka by apache.

the class KafkaProducerTest method testMetadataTimeoutWithMissingTopic.

@ParameterizedTest
@ValueSource(booleans = { true, false })
public void testMetadataTimeoutWithMissingTopic(boolean isIdempotenceEnabled) throws Exception {
    Map<String, Object> configs = new HashMap<>();
    configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9999");
    configs.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, 60000);
    configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, isIdempotenceEnabled);
    // Create a record for a not-yet-created topic
    ProducerRecord<String, String> record = new ProducerRecord<>(topic, 2, null, "value");
    ProducerMetadata metadata = mock(ProducerMetadata.class);
    MockTime mockTime = new MockTime();
    AtomicInteger invocationCount = new AtomicInteger(0);
    when(metadata.fetch()).then(invocation -> {
        invocationCount.incrementAndGet();
        if (invocationCount.get() == 5) {
            mockTime.setCurrentTimeMs(mockTime.milliseconds() + 70000);
        }
        return emptyCluster;
    });
    KafkaProducer<String, String> producer = producerWithOverrideNewSender(configs, metadata, mockTime);
    // Four request updates where the topic isn't present, at which point the timeout expires and a
    // TimeoutException is thrown
    // For idempotence enabled case, the first metadata.fetch will be called in Sender#maybeSendAndPollTransactionalRequest
    Future<RecordMetadata> future = producer.send(record);
    verify(metadata, times(4)).requestUpdateForTopic(topic);
    verify(metadata, times(4)).awaitUpdate(anyInt(), anyLong());
    verify(metadata, times(5)).fetch();
    try {
        future.get();
    } catch (ExecutionException e) {
        assertTrue(e.getCause() instanceof TimeoutException);
    } finally {
        producer.close(Duration.ofMillis(0));
    }
}
Also used : ProducerMetadata(org.apache.kafka.clients.producer.internals.ProducerMetadata) HashMap(java.util.HashMap) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutionException(java.util.concurrent.ExecutionException) MockTime(org.apache.kafka.common.utils.MockTime) TimeoutException(org.apache.kafka.common.errors.TimeoutException) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

HashMap (java.util.HashMap)34 ProducerMetadata (org.apache.kafka.clients.producer.internals.ProducerMetadata)34 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)32 MockTime (org.apache.kafka.common.utils.MockTime)30 StringSerializer (org.apache.kafka.common.serialization.StringSerializer)28 MockClient (org.apache.kafka.clients.MockClient)27 MetadataResponse (org.apache.kafka.common.requests.MetadataResponse)27 Test (org.junit.jupiter.api.Test)27 Time (org.apache.kafka.common.utils.Time)25 ExecutorService (java.util.concurrent.ExecutorService)8 ExecutionException (java.util.concurrent.ExecutionException)7 TimeoutException (org.apache.kafka.common.errors.TimeoutException)7 ValueSource (org.junit.jupiter.params.provider.ValueSource)7 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 Node (org.apache.kafka.common.Node)6 ArrayList (java.util.ArrayList)5 CountDownLatch (java.util.concurrent.CountDownLatch)5 ConsumerGroupMetadata (org.apache.kafka.clients.consumer.ConsumerGroupMetadata)5 KafkaException (org.apache.kafka.common.KafkaException)5 TopicPartition (org.apache.kafka.common.TopicPartition)5