Search in sources :

Example 6 with TopicAssigner

use of org.apache.storm.kafka.spout.subscription.TopicAssigner in project storm by apache.

the class SpoutWithMockedConsumerSetupHelper method setupSpout.

/**
 * Creates, opens and activates a KafkaSpout using a mocked consumer. The TopicFilter and ManualPartitioner should be mock objects,
 * since this method shortcircuits the TopicPartition assignment process and just calls onPartitionsAssigned on the rebalance listener.
 *
 * @param <K> The Kafka key type
 * @param <V> The Kafka value type
 * @param spoutConfig The spout config to use
 * @param topoConf The topo conf to pass to the spout
 * @param contextMock The topo context to pass to the spout
 * @param collectorMock The mocked collector to pass to the spout
 * @param consumerMock The mocked consumer
 * @param assignedPartitions The partitions to assign to this spout. The consumer will act like these partitions are assigned to it.
 * @return The spout
 */
public static <K, V> KafkaSpout<K, V> setupSpout(KafkaSpoutConfig<K, V> spoutConfig, Map<String, Object> topoConf, TopologyContext contextMock, SpoutOutputCollector collectorMock, KafkaConsumer<K, V> consumerMock, TopicPartition... assignedPartitions) {
    TopicFilter topicFilter = spoutConfig.getTopicFilter();
    ManualPartitioner topicPartitioner = spoutConfig.getTopicPartitioner();
    if (!mockingDetails(topicFilter).isMock() || !mockingDetails(topicPartitioner).isMock()) {
        throw new IllegalStateException("Use a mocked TopicFilter and a mocked ManualPartitioner when using this method, it helps avoid complex stubbing");
    }
    Set<TopicPartition> assignedPartitionsSet = new HashSet<>(Arrays.asList(assignedPartitions));
    TopicAssigner assigner = mock(TopicAssigner.class);
    doAnswer(invocation -> {
        ConsumerRebalanceListener listener = invocation.getArgument(2);
        listener.onPartitionsAssigned(assignedPartitionsSet);
        return null;
    }).when(assigner).assignPartitions(any(), any(), any());
    when(consumerMock.assignment()).thenReturn(assignedPartitionsSet);
    ConsumerFactory<K, V> consumerFactory = (kafkaSpoutConfig) -> consumerMock;
    KafkaSpout<K, V> spout = new KafkaSpout<>(spoutConfig, consumerFactory, assigner);
    spout.open(topoConf, contextMock, collectorMock);
    spout.activate();
    return spout;
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) Arrays(java.util.Arrays) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) Mockito.mockingDetails(org.mockito.Mockito.mockingDetails) ManualPartitioner(org.apache.storm.kafka.spout.subscription.ManualPartitioner) TopologyContext(org.apache.storm.task.TopologyContext) HashMap(java.util.HashMap) ConsumerRecords(org.apache.kafka.clients.consumer.ConsumerRecords) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ArgumentCaptor(org.mockito.ArgumentCaptor) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Map(java.util.Map) TopicPartition(org.apache.kafka.common.TopicPartition) Set(java.util.Set) Mockito.times(org.mockito.Mockito.times) Mockito.when(org.mockito.Mockito.when) ArgumentMatchers.anyList(org.mockito.ArgumentMatchers.anyList) Mockito.verify(org.mockito.Mockito.verify) ConsumerRebalanceListener(org.apache.kafka.clients.consumer.ConsumerRebalanceListener) List(java.util.List) TopicFilter(org.apache.storm.kafka.spout.subscription.TopicFilter) ConsumerRecord(org.apache.kafka.clients.consumer.ConsumerRecord) Entry(java.util.Map.Entry) ConsumerFactory(org.apache.storm.kafka.spout.internal.ConsumerFactory) SpoutOutputCollector(org.apache.storm.spout.SpoutOutputCollector) Collections(java.util.Collections) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Mockito.mock(org.mockito.Mockito.mock) KafkaConsumer(org.apache.kafka.clients.consumer.KafkaConsumer) TopicAssigner(org.apache.storm.kafka.spout.subscription.TopicAssigner) TopicFilter(org.apache.storm.kafka.spout.subscription.TopicFilter) ConsumerRebalanceListener(org.apache.kafka.clients.consumer.ConsumerRebalanceListener) ManualPartitioner(org.apache.storm.kafka.spout.subscription.ManualPartitioner) TopicPartition(org.apache.kafka.common.TopicPartition) TopicAssigner(org.apache.storm.kafka.spout.subscription.TopicAssigner) HashSet(java.util.HashSet)

Example 7 with TopicAssigner

use of org.apache.storm.kafka.spout.subscription.TopicAssigner in project storm by apache.

the class KafkaSpoutRebalanceTest method spoutMustIgnoreAcksForTuplesItIsNotAssignedAfterRebalance.

@Test
public void spoutMustIgnoreAcksForTuplesItIsNotAssignedAfterRebalance() throws Exception {
    // Acking tuples for partitions that are no longer assigned is useless since the spout will not be allowed to commit them
    try (SimulatedTime simulatedTime = new SimulatedTime()) {
        TopicAssigner assignerMock = mock(TopicAssigner.class);
        KafkaSpout<String, String> spout = new KafkaSpout<>(createKafkaSpoutConfigBuilder(topicFilterMock, partitionerMock, -1).setOffsetCommitPeriodMs(offsetCommitPeriodMs).build(), consumerFactory, assignerMock);
        String topic = SingleTopicKafkaSpoutConfiguration.TOPIC;
        TopicPartition partitionThatWillBeRevoked = new TopicPartition(topic, 1);
        TopicPartition assignedPartition = new TopicPartition(topic, 2);
        // Emit a message on each partition and revoke the first partition
        List<KafkaSpoutMessageId> emittedMessageIds = emitOneMessagePerPartitionThenRevokeOnePartition(spout, partitionThatWillBeRevoked, assignedPartition, assignerMock);
        // Ack both emitted tuples
        spout.ack(emittedMessageIds.get(0));
        spout.ack(emittedMessageIds.get(1));
        // Ensure the commit timer has expired
        Time.advanceTime(offsetCommitPeriodMs + KafkaSpout.TIMER_DELAY_MS);
        // Make the spout commit any acked tuples
        spout.nextTuple();
        // Verify that it only committed the message on the assigned partition
        verify(consumerMock, times(1)).commitSync(commitCapture.capture());
        Map<TopicPartition, OffsetAndMetadata> commitCaptureMap = commitCapture.getValue();
        assertThat(commitCaptureMap, hasKey(assignedPartition));
        assertThat(commitCaptureMap, not(hasKey(partitionThatWillBeRevoked)));
    }
}
Also used : SimulatedTime(org.apache.storm.utils.Time.SimulatedTime) TopicPartition(org.apache.kafka.common.TopicPartition) OffsetAndMetadata(org.apache.kafka.clients.consumer.OffsetAndMetadata) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) TopicAssigner(org.apache.storm.kafka.spout.subscription.TopicAssigner) Test(org.junit.Test)

Aggregations

TopicPartition (org.apache.kafka.common.TopicPartition)7 TopicAssigner (org.apache.storm.kafka.spout.subscription.TopicAssigner)7 HashSet (java.util.HashSet)5 ConsumerRebalanceListener (org.apache.kafka.clients.consumer.ConsumerRebalanceListener)5 ArrayList (java.util.ArrayList)4 Collections (java.util.Collections)4 List (java.util.List)4 Map (java.util.Map)4 Set (java.util.Set)4 ManualPartitioner (org.apache.storm.kafka.spout.subscription.ManualPartitioner)4 TopicFilter (org.apache.storm.kafka.spout.subscription.TopicFilter)4 TopologyContext (org.apache.storm.task.TopologyContext)4 ArgumentMatchers.any (org.mockito.ArgumentMatchers.any)4 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)4 Mockito.mock (org.mockito.Mockito.mock)4 Mockito.verify (org.mockito.Mockito.verify)4 Mockito.when (org.mockito.Mockito.when)4 Collectors (java.util.stream.Collectors)3 MockConsumer (org.apache.kafka.clients.consumer.MockConsumer)3 OffsetResetStrategy (org.apache.kafka.clients.consumer.OffsetResetStrategy)3