/** * Unsubscribe from the specific topic partitions. Messages for these partitions will not be * returned from the next {@link #poll(long) poll()} onwards * * @param partitions Partitions to unsubscribe from 移除订阅的TopicPartition */ public void unsubscribe(TopicPartition... partitions) { // throw an exception if the partition was never subscribed to for (TopicPartition partition : partitions) { if (!subscribedPartitions.contains(partition)) throw new IllegalStateException( "Partition " + partition + " was never subscribed to. subscribe(new TopicPartition(" + partition.topic() + "," + partition.partition() + ") should be called prior" + " to unsubscribe(new TopicPartition(" + partition.topic() + "," + partition.partition() + ")"); subscribedPartitions.remove(partition); } // trigger a rebalance operation }
public ControlledShutdownResponse(short errorCode, Set<TopicPartition> partitionsRemaining) { super(new Struct(CURRENT_SCHEMA)); struct.set(ERROR_CODE_KEY_NAME, errorCode); List<Struct> partitionsRemainingList = new ArrayList<>(partitionsRemaining.size()); for (TopicPartition topicPartition : partitionsRemaining) { Struct topicPartitionStruct = struct.instance(PARTITIONS_REMAINING_KEY_NAME); topicPartitionStruct.set(TOPIC_KEY_NAME, topicPartition.topic()); topicPartitionStruct.set(PARTITION_KEY_NAME, topicPartition.partition()); partitionsRemainingList.add(topicPartitionStruct); } struct.set(PARTITIONS_REMAINING_KEY_NAME, partitionsRemainingList.toArray()); this.errorCode = errorCode; this.partitionsRemaining = partitionsRemaining; }
@Test public void testOnConsumeChain() { List<ConsumerInterceptor<Integer, Integer>> interceptorList = new ArrayList<>(); // we are testing two different interceptors by configuring the same interceptor differently, // which is not // how it would be done in KafkaConsumer, but ok for testing interceptor callbacks FilterConsumerInterceptor<Integer, Integer> interceptor1 = new FilterConsumerInterceptor<>(filterPartition1); FilterConsumerInterceptor<Integer, Integer> interceptor2 = new FilterConsumerInterceptor<>(filterPartition2); interceptorList.add(interceptor1); interceptorList.add(interceptor2); ConsumerInterceptors<Integer, Integer> interceptors = new ConsumerInterceptors<>(interceptorList); // verify that onConsumer modifies ConsumerRecords Map<TopicPartition, List<ConsumerRecord<Integer, Integer>>> records = new HashMap<>(); List<ConsumerRecord<Integer, Integer>> list1 = new ArrayList<>(); list1.add(consumerRecord); List<ConsumerRecord<Integer, Integer>> list2 = new ArrayList<>(); list2.add( new ConsumerRecord<>( filterTopicPart1.topic(), filterTopicPart1.partition(), 0, 0L, TimestampType.CREATE_TIME, 0L, 0, 0, 1, 1)); List<ConsumerRecord<Integer, Integer>> list3 = new ArrayList<>(); list3.add( new ConsumerRecord<>( filterTopicPart2.topic(), filterTopicPart2.partition(), 0, 0L, TimestampType.CREATE_TIME, 0L, 0, 0, 1, 1)); records.put(tp, list1); records.put(filterTopicPart1, list2); records.put(filterTopicPart2, list3); ConsumerRecords<Integer, Integer> consumerRecords = new ConsumerRecords<>(records); ConsumerRecords<Integer, Integer> interceptedRecords = interceptors.onConsume(consumerRecords); assertEquals(1, interceptedRecords.count()); assertTrue(interceptedRecords.partitions().contains(tp)); assertFalse(interceptedRecords.partitions().contains(filterTopicPart1)); assertFalse(interceptedRecords.partitions().contains(filterTopicPart2)); assertEquals(2, onConsumeCount); // verify that even if one of the intermediate interceptors throws an exception, all // interceptors' onConsume are called interceptor1.injectOnConsumeError(true); ConsumerRecords<Integer, Integer> partInterceptedRecs = interceptors.onConsume(consumerRecords); assertEquals(2, partInterceptedRecs.count()); assertTrue( partInterceptedRecs .partitions() .contains(filterTopicPart1)); // since interceptor1 threw exception assertFalse( partInterceptedRecs .partitions() .contains(filterTopicPart2)); // interceptor2 should still be called assertEquals(4, onConsumeCount); // if all interceptors throw an exception, records should be unmodified interceptor2.injectOnConsumeError(true); ConsumerRecords<Integer, Integer> noneInterceptedRecs = interceptors.onConsume(consumerRecords); assertEquals(noneInterceptedRecs, consumerRecords); assertEquals(3, noneInterceptedRecs.count()); assertEquals(6, onConsumeCount); interceptors.close(); }
@Override public String getId() { return topicPartition.topic() + "/" + topicPartition.partition(); }