Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,13 @@
package org.apache.kafka.tools.reassign;

import java.util.List;
import java.util.Objects;

/**
* The state of a partition reassignment. The current replicas and target replicas
* may overlap.
*/
final class PartitionReassignmentState {
public final List<Integer> currentReplicas;

public final List<Integer> targetReplicas;

public final boolean done;

/**
* @param currentReplicas The current replicas.
* @param targetReplicas The target replicas.
* @param done True if the reassignment is done.
*/
Comment thread
TaiJuWu marked this conversation as resolved.
public PartitionReassignmentState(List<Integer> currentReplicas, List<Integer> targetReplicas, boolean done) {
this.currentReplicas = currentReplicas;
this.targetReplicas = targetReplicas;
this.done = done;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PartitionReassignmentState state = (PartitionReassignmentState) o;
return done == state.done && Objects.equals(currentReplicas, state.currentReplicas) && Objects.equals(targetReplicas, state.targetReplicas);
}

@Override
public int hashCode() {
return Objects.hash(currentReplicas, targetReplicas, done);
}
}
record PartitionReassignmentState(
List<Integer> currentReplicas,
List<Integer> targetReplicas,
boolean done
) { }
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,12 @@ static String partitionReassignmentStatesToString(Map<TopicPartition, PartitionR
bld.add("Status of partition reassignment:");
states.keySet().stream().sorted(ReassignPartitionsCommand::compareTopicPartitions).forEach(topicPartition -> {
PartitionReassignmentState state = states.get(topicPartition);
if (state.done) {
if (state.currentReplicas.equals(state.targetReplicas)) {
if (state.done()) {
if (state.currentReplicas().equals(state.targetReplicas())) {
bld.add(String.format("Reassignment of partition %s is completed.", topicPartition));
} else {
String currentReplicaStr = state.currentReplicas.stream().map(String::valueOf).collect(Collectors.joining(","));
String targetReplicaStr = state.targetReplicas.stream().map(String::valueOf).collect(Collectors.joining(","));
String currentReplicaStr = state.currentReplicas().stream().map(String::valueOf).collect(Collectors.joining(","));
String targetReplicaStr = state.targetReplicas().stream().map(String::valueOf).collect(Collectors.joining(","));

bld.add("There is no active reassignment of partition " + topicPartition + ", " +
"but replica set is " + currentReplicaStr + " rather than " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,49 +21,21 @@
import org.apache.kafka.common.TopicPartitionReplica;

import java.util.Map;
import java.util.Objects;

/**
* A result returned from verifyAssignment.
* @param partStates A map from partitions to reassignment states.
* @param partsOngoing True if there are any ongoing partition reassignments.
* @param moveStates A map from log directories to movement states.
* @param movesOngoing True if there are any ongoing moves that we know about.
*/
public final class VerifyAssignmentResult {
public final Map<TopicPartition, PartitionReassignmentState> partStates;
public final boolean partsOngoing;
public final Map<TopicPartitionReplica, LogDirMoveState> moveStates;
public final boolean movesOngoing;

public record VerifyAssignmentResult(
Map<TopicPartition, PartitionReassignmentState> partStates,
boolean partsOngoing,
Map<TopicPartitionReplica, LogDirMoveState> moveStates,
boolean movesOngoing
) {
public VerifyAssignmentResult(Map<TopicPartition, PartitionReassignmentState> partStates) {
this(partStates, false, Map.of(), false);
}

/**
* @param partStates A map from partitions to reassignment states.
* @param partsOngoing True if there are any ongoing partition reassignments.
* @param moveStates A map from log directories to movement states.
* @param movesOngoing True if there are any ongoing moves that we know about.
*/
public VerifyAssignmentResult(
Map<TopicPartition, PartitionReassignmentState> partStates,
boolean partsOngoing,
Map<TopicPartitionReplica, LogDirMoveState> moveStates,
boolean movesOngoing
) {
this.partStates = partStates;
this.partsOngoing = partsOngoing;
this.moveStates = moveStates;
this.movesOngoing = movesOngoing;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
VerifyAssignmentResult that = (VerifyAssignmentResult) o;
return partsOngoing == that.partsOngoing && movesOngoing == that.movesOngoing && Objects.equals(partStates, that.partStates) && Objects.equals(moveStates, that.moveStates);
}

@Override
public int hashCode() {
return Objects.hash(partStates, partsOngoing, moveStates, movesOngoing);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,18 @@ public void testGenerateAssignmentWithBootstrapServer() throws Exception {
produceMessages(foo0.topic(), foo0.partition(), 100);

try (Admin admin = Admin.create(Map.of(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, clusterInstance.bootstrapServers()))) {
String assignment = "{\"version\":1,\"partitions\":" +
"[{\"topic\":\"foo\",\"partition\":0,\"replicas\":[3,1,2],\"log_dirs\":[\"any\",\"any\",\"any\"]}" +
"]}";
generateAssignment(admin, assignment, "1,2,3", false);
String topicsToMoveJson = "{\"topics\":\n\t[{\"topic\": \"foo\"}],\n\"version\":1\n}";
var assignment = generateAssignment(admin, topicsToMoveJson, "1,2,3", false);
Map<TopicPartition, List<Integer>> proposedAssignments = assignment.getKey();
String assignmentJson = String.format("{\"version\":1,\"partitions\":" +
"[{\"topic\":\"foo\",\"partition\":0,\"replicas\":%s,\"log_dirs\":[\"any\",\"any\",\"any\"]}" +
"]}", proposedAssignments.get(foo0));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not easy to read. Can we use the text block feature from Java 17?

For example:

            String assignmentJson = String.format("""
                {"version":1,"partitions":\
                [{"topic":"foo","partition":0,"replicas":%s,"log_dirs":["any","any","any"]}\
                ]}""", proposedAssignments.get(foo0));


runExecuteAssignment(false, assignmentJson, -1L, -1L);

Map<TopicPartition, PartitionReassignmentState> finalAssignment = Map.of(foo0,
new PartitionReassignmentState(List.of(0, 1, 2), List.of(3, 1, 2), true));
waitForVerifyAssignment(admin, assignment, false,
new PartitionReassignmentState(proposedAssignments.get(foo0), proposedAssignments.get(foo0), true));
waitForVerifyAssignment(admin, assignmentJson, false,
new VerifyAssignmentResult(finalAssignment));
}
}
Expand Down Expand Up @@ -237,15 +242,15 @@ public void testThrottledReassignment() throws Exception {
// Check the reassignment status.
VerifyAssignmentResult result = runVerifyAssignment(admin, assignment, true);

if (!result.partsOngoing) {
if (!result.partsOngoing()) {
return true;
} else {
assertFalse(
result.partStates.values().stream().allMatch(state -> state.done),
result.partStates().values().stream().allMatch(PartitionReassignmentState::done),
"Expected at least one partition reassignment to be ongoing when result = " + result
);
assertEquals(List.of(0, 3, 2), result.partStates.get(new TopicPartition("foo", 0)).targetReplicas);
assertEquals(List.of(3, 2, 1), result.partStates.get(new TopicPartition("baz", 2)).targetReplicas);
assertEquals(List.of(0, 3, 2), result.partStates().get(new TopicPartition("foo", 0)).targetReplicas());
assertEquals(List.of(3, 2, 1), result.partStates().get(new TopicPartition("baz", 2)).targetReplicas());
waitForInterBrokerThrottle(admin, List.of(0, 1, 2, 3), interBrokerThrottle);
return false;
}
Expand Down Expand Up @@ -540,7 +545,7 @@ private void executeAndVerifyReassignment() throws InterruptedException {
finalAssignment.put(bar0, new PartitionReassignmentState(List.of(3, 2, 0), List.of(3, 2, 0), true));

VerifyAssignmentResult verifyAssignmentResult = runVerifyAssignment(admin, assignment, false);
assertFalse(verifyAssignmentResult.movesOngoing);
assertFalse(verifyAssignmentResult.movesOngoing());

// Wait for the assignment to complete
waitForVerifyAssignment(admin, assignment, false,
Expand Down Expand Up @@ -786,7 +791,7 @@ private void testCancellationAction(boolean useBootstrapServer) throws Interrupt
// This time, the broker throttles were removed.
waitForBrokerLevelThrottles(admin, unthrottledBrokerConfigs);
// Verify that there are no ongoing reassignments.
assertFalse(runVerifyAssignment(admin, assignment, false).partsOngoing);
assertFalse(runVerifyAssignment(admin, assignment, false).partsOngoing());
}
// Verify that the partition is removed from cancelled replicas
verifyReplicaDeleted(new TopicPartitionReplica(foo0.topic(), foo0.partition(), 3));
Expand Down
Loading