@@ -565,15 +565,16 @@ public static Entry<Map<TopicPartition, List<Integer>>, Map<TopicPartition, List
565565 List <Integer > brokersToReassign = t0 .getKey ();
566566 List <String > topicsToReassign = t0 .getValue ();
567567
568- Map <TopicPartition , List <Integer >> currentAssignments = getReplicaAssignmentForTopics (adminClient , topicsToReassign );
568+ Map <TopicPartition , List <Node >> currentAssignments = getReplicaAssignmentForTopics (adminClient , topicsToReassign );
569569 Map <TopicPartitionReplica , String > currentReplicaLogDirs = getReplicaToLogDir (adminClient , currentAssignments );
570570 List <UsableBroker > usableBrokers = getBrokerMetadata (adminClient , brokersToReassign , enableRackAwareness );
571- Map <TopicPartition , List <Integer >> proposedAssignments = calculateAssignment (currentAssignments , usableBrokers );
571+ Map <TopicPartition , List <Integer >> currentParts = toReplicaIds (currentAssignments );
572+ Map <TopicPartition , List <Integer >> proposedAssignments = calculateAssignment (currentParts , usableBrokers );
572573 System .out .printf ("Current partition replica assignment%n%s%n%n" ,
573- formatAsReassignmentJson (currentAssignments , currentReplicaLogDirs ));
574+ formatAsReassignmentJson (currentParts , currentReplicaLogDirs ));
574575 System .out .printf ("Proposed partition reassignment configuration%n%s%n" ,
575576 formatAsReassignmentJson (proposedAssignments , Map .of ()));
576- return Map .entry (proposedAssignments , currentAssignments );
577+ return Map .entry (proposedAssignments , currentParts );
577578 }
578579
579580 /**
@@ -642,14 +643,14 @@ private static Map<String, TopicDescription> describeTopics(Admin adminClient,
642643 * @return A map from partitions to broker assignments.
643644 * If any topic can't be found, an exception will be thrown.
644645 */
645- static Map <TopicPartition , List <Integer >> getReplicaAssignmentForTopics (Admin adminClient ,
646- List <String > topics
646+ static Map <TopicPartition , List <Node >> getReplicaAssignmentForTopics (Admin adminClient ,
647+ List <String > topics
647648 ) throws ExecutionException , InterruptedException {
648- Map <TopicPartition , List <Integer >> res = new HashMap <>();
649+ Map <TopicPartition , List <Node >> res = new HashMap <>();
649650 describeTopics (adminClient , new HashSet <>(topics )).forEach ((topicName , topicDescription ) ->
650651 topicDescription .partitions ().forEach (info -> res .put (
651652 new TopicPartition (topicName , info .partition ()),
652- info .replicas (). stream (). map ( Node :: id ). collect ( Collectors . toList ())
653+ info .replicas ()
653654 )
654655 ));
655656 return res ;
@@ -663,15 +664,15 @@ static Map<TopicPartition, List<Integer>> getReplicaAssignmentForTopics(Admin ad
663664 * @return A map from partitions to broker assignments.
664665 * If any topic or partition can't be found, an exception will be thrown.
665666 */
666- static Map <TopicPartition , List <Integer >> getReplicaAssignmentForPartitions (Admin adminClient ,
667- Set <TopicPartition > partitions
667+ static Map <TopicPartition , List <Node >> getReplicasForPartitions (Admin adminClient ,
668+ Set <TopicPartition > partitions
668669 ) throws ExecutionException , InterruptedException {
669- Map <TopicPartition , List <Integer >> res = new HashMap <>();
670+ Map <TopicPartition , List <Node >> res = new HashMap <>();
670671 describeTopics (adminClient , partitions .stream ().map (TopicPartition ::topic ).collect (Collectors .toSet ())).forEach ((topicName , topicDescription ) ->
671672 topicDescription .partitions ().forEach (info -> {
672673 TopicPartition tp = new TopicPartition (topicName , info .partition ());
673674 if (partitions .contains (tp ))
674- res .put (tp , info .replicas (). stream (). map ( Node :: id ). collect ( Collectors . toList ()) );
675+ res .put (tp , info .replicas ());
675676 })
676677 );
677678
@@ -684,6 +685,17 @@ static Map<TopicPartition, List<Integer>> getReplicaAssignmentForPartitions(Admi
684685 return res ;
685686 }
686687
688+ static Map <TopicPartition , List <Integer >> toReplicaIds (
689+ Map <TopicPartition , List <Node >> replicaAssignmentForPartitions
690+ ) {
691+ return replicaAssignmentForPartitions .entrySet ()
692+ .stream ()
693+ .collect (Collectors .toMap (
694+ Entry ::getKey ,
695+ e -> e .getValue ().stream ().map (Node ::id ).collect (Collectors .toList ())
696+ ));
697+ }
698+
687699 /**
688700 * Find the rack information for some brokers.
689701 *
@@ -775,8 +787,10 @@ public static void executeAssignment(Admin adminClient,
775787 proposedParts .values ().forEach (brokers ::addAll );
776788
777789 verifyBrokerIds (adminClient , brokers );
778- Map <TopicPartition , List <Integer >> currentParts = getReplicaAssignmentForPartitions (adminClient , proposedParts .keySet ());
779- System .out .println (currentPartitionReplicaAssignmentToString (adminClient , proposedParts , currentParts ));
790+ Map <TopicPartition , List <Node >> currentPartsToNode = getReplicasForPartitions (adminClient , proposedParts .keySet ());
791+ Map <TopicPartition , List <Integer >> currentParts = toReplicaIds (currentPartsToNode );
792+
793+ System .out .println (currentPartitionReplicaAssignmentToString (adminClient , proposedParts , currentPartsToNode ));
780794
781795 if (interBrokerThrottle >= 0 || logDirThrottle >= 0 ) {
782796 System .out .println (YOU_MUST_RUN_VERIFY_PERIODICALLY_MESSAGE );
@@ -919,21 +933,31 @@ private static void verifyBrokerIds(Admin adminClient, Set<Integer> brokers) thr
919933 *
920934 * @param adminClient The admin client object to use.
921935 * @param proposedParts The proposed partition assignment.
922- * @param currentParts The current partition assignment.
936+ * @param currentAssignments The current partition assignment with Node information .
923937 *
924938 * @return The string to print. We will only print information about
925939 * partitions that appear in the proposed partition assignment.
926940 */
927- static String currentPartitionReplicaAssignmentToString (Admin adminClient ,
928- Map <TopicPartition , List <Integer >> proposedParts ,
929- Map <TopicPartition , List <Integer >> currentParts ) throws JsonProcessingException , ExecutionException , InterruptedException {
930- Map <TopicPartition , List <Integer >> partitionsToBeReassigned = currentParts .entrySet ().stream ()
941+ static String currentPartitionReplicaAssignmentToString (
942+ Admin adminClient ,
943+ Map <TopicPartition , List <Integer >> proposedParts ,
944+ Map <TopicPartition , List <Node >> currentAssignments
945+ ) throws JsonProcessingException , ExecutionException , InterruptedException {
946+
947+ Map <TopicPartition , List <Node >> partitionsToBeReassigned = currentAssignments .entrySet ()
948+ .stream ()
931949 .filter (e -> proposedParts .containsKey (e .getKey ()))
932950 .collect (Collectors .toMap (Entry ::getKey , Entry ::getValue ));
933- Map <TopicPartitionReplica , String > currentReplicaLogDirs = getReplicaToLogDir (adminClient , partitionsToBeReassigned );
951+
952+ Map <TopicPartitionReplica , String > currentReplicaLogDirs = getReplicaToLogDir (
953+ adminClient ,
954+ partitionsToBeReassigned
955+ );
956+
957+ Map <TopicPartition , List <Integer >> currentParts = toReplicaIds (partitionsToBeReassigned );
934958
935959 return String .format ("Current partition replica assignment%n%n%s%n%nSave this to use as the %s" ,
936- formatAsReassignmentJson (partitionsToBeReassigned , currentReplicaLogDirs ),
960+ formatAsReassignmentJson (currentParts , currentReplicaLogDirs ),
937961 "--reassignment-json-file option during rollback" );
938962 }
939963
@@ -1519,25 +1543,48 @@ static Set<TopicPartitionReplica> alterReplicaLogDirs(Admin adminClient,
15191543 return results ;
15201544 }
15211545
1546+ /**
1547+ * Get the log directory for each replica.
1548+ *
1549+ * @param adminClient The admin client object to use.
1550+ * @param current The current partition assignment with Node information.
1551+ * @return Map of TopicPartitionReplica to log directory path.
1552+ */
15221553 static Map <TopicPartitionReplica , String > getReplicaToLogDir (
15231554 Admin adminClient ,
1524- Map <TopicPartition , List <Integer >> topicPartitionToReplicas
1525- ) throws InterruptedException , ExecutionException {
1526- var replicaLogDirs = topicPartitionToReplicas
1527- .entrySet ()
1528- .stream ()
1529- .flatMap (entry -> entry .getValue ()
1530- .stream ()
1531- .map (id -> new TopicPartitionReplica (entry .getKey ().topic (), entry .getKey ().partition (), id )))
1532- .collect (Collectors .toUnmodifiableSet ());
1555+ Map <TopicPartition , List <Node >> current
1556+ ) throws ExecutionException , InterruptedException {
1557+ List <TopicPartitionReplica > availableReplicas = available (current );
1558+
1559+ if (availableReplicas .isEmpty ()) {
1560+ return Map .of ();
1561+ }
15331562
1534- return adminClient .describeReplicaLogDirs (replicaLogDirs ).all ().get ()
1563+ return adminClient .describeReplicaLogDirs (availableReplicas ).all ().get ()
15351564 .entrySet ()
15361565 .stream ()
1537- .filter (entry -> entry .getValue ().getCurrentReplicaLogDir () != null )
1566+ .filter (e -> e .getValue ().getCurrentReplicaLogDir () != null )
15381567 .collect (Collectors .toMap (
15391568 Entry ::getKey ,
1540- entry -> entry .getValue ().getCurrentReplicaLogDir ()
1541- ));
1569+ e -> e .getValue ().getCurrentReplicaLogDir ())
1570+ );
1571+ }
1572+
1573+ /**
1574+ * Extract available (non-empty) replicas from the assignment.
1575+ */
1576+ private static List <TopicPartitionReplica > available (Map <TopicPartition , List <Node >> current ) {
1577+ return current .entrySet ()
1578+ .stream ()
1579+ .flatMap (entry -> entry .getValue ()
1580+ .stream ()
1581+ .filter (node -> !node .isEmpty ())
1582+ .map (node -> new TopicPartitionReplica (
1583+ entry .getKey ().topic (),
1584+ entry .getKey ().partition (),
1585+ node .id ()
1586+ ))
1587+ )
1588+ .toList ();
15421589 }
15431590}
0 commit comments