Source:
public void run() { producer.initTransactions(); final AtomicLong messageRemaining = new AtomicLong(Long.MAX_VALUE); if (this.mode.equals("groupMode")) { consumer.subscribe(Collections.singleton(inputTopic), new ConsumerRebalanceListener() { @Override public void onPartitionsRevoked(Collection<TopicPartition> partitions) { printWithTxnId("Revoked partition assignment to kick-off rebalancing: " + partitions); } @Override public void onPartitionsAssigned(Collection<TopicPartition> partitions) { printWithTxnId("Received partition assignment after rebalancing: " + partitions); messageRemaining.set(messagesRemaining(consumer)); } }); } else { List<TopicPartition> topicPartitions = new ArrayList<>(); int rangeSize = numPartitions / numInstances; int startPartition = rangeSize * instanceIdx; int endPartition = Math.min(numPartitions - 1, startPartition + rangeSize - 1); for (int partition = startPartition; partition <= endPartition; partition++) { topicPartitions.add(new TopicPartition(inputTopic, partition)); } consumer.assign(topicPartitions); printWithTxnId("Manually assign partitions: " + topicPartitions); } int messageProcessed = 0; while (messageRemaining.get() > 0) { try { messageProcessed += processMessages(); } catch (ProducerFencedException | FencedInstanceIdException | AuthorizationException | AuthenticationException | UnsupportedVersionException | UnsupportedForMessageFormatException | InvalidTopicException | InvalidOffsetException e) { throw new KafkaException("Encountered fatal error during processing: " + e.getMessage()); } messageRemaining.set(messagesRemaining(consumer)); printWithTxnId("Message remaining: " + messageRemaining); } printWithTxnId("Finished processing " + messageProcessed + " records"); latch.countDown(); }

Target:
public void run() { producer.initTransactions(); final AtomicLong messageRemaining = new AtomicLong(Long.MAX_VALUE); consumer.subscribe(Collections.singleton(inputTopic), new ConsumerRebalanceListener() { @Override public void onPartitionsRevoked(Collection<TopicPartition> partitions) { printWithTxnId("Revoked partition assignment to kick-off rebalancing: " + partitions); } @Override public void onPartitionsAssigned(Collection<TopicPartition> partitions) { printWithTxnId("Received partition assignment after rebalancing: " + partitions); messageRemaining.set(messagesRemaining(consumer)); } }); int messageProcessed = 0; while (messageRemaining.get() > 0) { try { ConsumerRecords<Integer, String> records = consumer.poll(Duration.ofMillis(200)); if (records.count() > 0) { producer.beginTransaction(); for (ConsumerRecord<Integer, String> record : records) { ProducerRecord<Integer, String> customizedRecord = transform(record); producer.send(customizedRecord); } Map<TopicPartition, OffsetAndMetadata> offsets = consumerOffsets(); producer.sendOffsetsToTransaction(offsets, consumer.groupMetadata()); producer.commitTransaction(); messageProcessed += records.count(); } } catch (ProducerFencedException e) { throw new KafkaException(String.format("The transactional.id %s has been claimed by another process", transactionalId)); } catch (FencedInstanceIdException e) { throw new KafkaException(String.format("The group.instance.id %s has been claimed by another process", groupInstanceId)); } catch (KafkaException e) { producer.abortTransaction(); resetToLastCommittedPositions(consumer); } messageRemaining.set(messagesRemaining(consumer)); printWithTxnId("Message remaining: " + messageRemaining); } printWithTxnId("Finished processing " + messageProcessed + " records"); latch.countDown(); }