use of org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult in project cruise-control by linkedin.
the class ExecutorTest method testSubmitReplicaReassignmentTasksWithDeadTaskAndNoReassignmentInProgress.
@Test
public void testSubmitReplicaReassignmentTasksWithDeadTaskAndNoReassignmentInProgress() throws InterruptedException {
AdminClient adminClient = KafkaCruiseControlUtils.createAdminClient(Collections.singletonMap(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, broker(0).plaintextAddr()));
TopicPartition tp = new TopicPartition(TOPIC0, 0);
ExecutionProposal proposal = new ExecutionProposal(tp, 100, new ReplicaPlacementInfo(0), Arrays.asList(new ReplicaPlacementInfo(0), new ReplicaPlacementInfo(1)), Arrays.asList(new ReplicaPlacementInfo(0), new ReplicaPlacementInfo(2)));
ExecutionTask task = new ExecutionTask(0, proposal, ExecutionTask.TaskType.INTER_BROKER_REPLICA_ACTION, EXECUTION_ALERTING_THRESHOLD_MS);
task.inProgress(MOCK_CURRENT_TIME);
task.kill(MOCK_CURRENT_TIME);
AlterPartitionReassignmentsResult result = ExecutionUtils.submitReplicaReassignmentTasks(adminClient, Collections.singletonList(task));
assertEquals(1, result.values().size());
assertTrue(verifyFutureError(result.values().get(tp), Errors.NO_REASSIGNMENT_IN_PROGRESS.exception().getClass()));
}
use of org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult in project cruise-control by linkedin.
the class ExecutorTest method testSubmitPreferredLeaderElection.
@Test
public void testSubmitPreferredLeaderElection() throws InterruptedException, ExecutionException {
Map<String, TopicDescription> topicDescriptions = createTopics(0);
AdminClient adminClient = KafkaCruiseControlUtils.createAdminClient(Collections.singletonMap(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, broker(0).plaintextAddr()));
// Case 1: Handle the successful case.
ReplicaPlacementInfo oldLeader = new ReplicaPlacementInfo(topicDescriptions.get(TP1.topic()).partitions().get(PARTITION).leader().id());
List<ReplicaPlacementInfo> replicas = new ArrayList<>();
for (Node node : topicDescriptions.get(TP1.topic()).partitions().get(PARTITION).replicas()) {
replicas.add(new ReplicaPlacementInfo(node.id()));
}
List<ReplicaPlacementInfo> newReplicas = new ArrayList<>(replicas.size());
for (int i = replicas.size() - 1; i >= 0; i--) {
newReplicas.add(new ReplicaPlacementInfo(replicas.get(i).brokerId()));
}
// Reorder replicas before leadership election to change the preferred replica.
ExecutionTask swapTask = new ExecutionTask(0, new ExecutionProposal(TP1, 0, oldLeader, replicas, newReplicas), ExecutionTask.TaskType.INTER_BROKER_REPLICA_ACTION, EXECUTION_ALERTING_THRESHOLD_MS);
swapTask.inProgress(MOCK_CURRENT_TIME);
AlterPartitionReassignmentsResult swapResult = ExecutionUtils.submitReplicaReassignmentTasks(adminClient, Collections.singletonList(swapTask));
assertEquals(1, swapResult.values().size());
// Can retrieve the future if it is successful.
swapResult.values().get(TP1).get();
// Leadership task to transfer the leadership to the preferred replica.
ExecutionTask task = new ExecutionTask(0, new ExecutionProposal(TP1, 0, oldLeader, newReplicas, newReplicas), ExecutionTask.TaskType.LEADER_ACTION, EXECUTION_ALERTING_THRESHOLD_MS);
task.inProgress(MOCK_CURRENT_TIME);
ElectLeadersResult result = ExecutionUtils.submitPreferredLeaderElection(adminClient, Collections.singletonList(task));
assertTrue(result.partitions().get().get(TP1).isEmpty());
// Case 2: Handle "election not needed" -- i.e. the leader is already the preferred replica for TP0.
oldLeader = new ReplicaPlacementInfo(topicDescriptions.get(TP0.topic()).partitions().get(PARTITION).leader().id());
replicas.clear();
for (Node node : topicDescriptions.get(TP0.topic()).partitions().get(PARTITION).replicas()) {
replicas.add(new ReplicaPlacementInfo(node.id()));
}
task = new ExecutionTask(0, new ExecutionProposal(TP0, 0, oldLeader, replicas, replicas), ExecutionTask.TaskType.LEADER_ACTION, EXECUTION_ALERTING_THRESHOLD_MS);
task.inProgress(MOCK_CURRENT_TIME);
result = ExecutionUtils.submitPreferredLeaderElection(adminClient, Collections.singletonList(task));
assertTrue(result.partitions().get().get(TP0).isPresent());
assertEquals(Errors.ELECTION_NOT_NEEDED.exception().getClass(), result.partitions().get().get(TP0).get().getClass());
// Case 3: Handle "unknown topic or partition" -- i.e. the partition TP2 does not exist, maybe it existed at some point and then deleted
task = new ExecutionTask(0, new ExecutionProposal(TP2, 0, oldLeader, replicas, replicas), ExecutionTask.TaskType.LEADER_ACTION, EXECUTION_ALERTING_THRESHOLD_MS);
task.inProgress(MOCK_CURRENT_TIME);
result = ExecutionUtils.submitPreferredLeaderElection(adminClient, Collections.singletonList(task));
assertTrue(result.partitions().get().get(TP2).isPresent());
assertEquals(Errors.UNKNOWN_TOPIC_OR_PARTITION.exception().getClass(), result.partitions().get().get(TP2).get().getClass());
// Case 4: Handle the scenario, where we tried to elect the preferred leader but it is offline.
_brokers.get(0).shutdown();
task = new ExecutionTask(0, new ExecutionProposal(TP0, 0, oldLeader, replicas, replicas), ExecutionTask.TaskType.LEADER_ACTION, EXECUTION_ALERTING_THRESHOLD_MS);
task.inProgress(MOCK_CURRENT_TIME);
result = ExecutionUtils.submitPreferredLeaderElection(adminClient, Collections.singletonList(task));
assertTrue(result.partitions().get().get(TP0).isPresent());
assertEquals(Errors.PREFERRED_LEADER_NOT_AVAILABLE.exception().getClass(), result.partitions().get().get(TP0).get().getClass());
}
use of org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult in project cruise-control by linkedin.
the class ExecutorTest method testSubmitReplicaReassignmentTasksWithInProgressTaskAndExistingTopic.
@Test
public void testSubmitReplicaReassignmentTasksWithInProgressTaskAndExistingTopic() throws InterruptedException, ExecutionException {
Map<String, TopicDescription> topicDescriptions = createTopics(0);
int initialLeader0 = topicDescriptions.get(TOPIC0).partitions().get(0).leader().id();
ExecutionProposal proposal0 = new ExecutionProposal(TP0, 0, new ReplicaPlacementInfo(initialLeader0), Collections.singletonList(new ReplicaPlacementInfo(initialLeader0)), Collections.singletonList(new ReplicaPlacementInfo(initialLeader0 == 0 ? 1 : 0)));
AdminClient adminClient = KafkaCruiseControlUtils.createAdminClient(Collections.singletonMap(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, broker(0).plaintextAddr()));
ExecutionTask task = new ExecutionTask(0, proposal0, ExecutionTask.TaskType.INTER_BROKER_REPLICA_ACTION, EXECUTION_ALERTING_THRESHOLD_MS);
task.inProgress(MOCK_CURRENT_TIME);
AlterPartitionReassignmentsResult result = ExecutionUtils.submitReplicaReassignmentTasks(adminClient, Collections.singletonList(task));
assertEquals(1, result.values().size());
// Can retrieve the future if it is successful.
result.values().get(TP0).get();
}
use of org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult in project cruise-control by linkedin.
the class ExecutorTest method testSubmitReplicaReassignmentTasksWithInProgressTaskAndNonExistingTopic.
@Test
public void testSubmitReplicaReassignmentTasksWithInProgressTaskAndNonExistingTopic() throws InterruptedException {
AdminClient adminClient = KafkaCruiseControlUtils.createAdminClient(Collections.singletonMap(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, broker(0).plaintextAddr()));
ExecutionProposal proposal = new ExecutionProposal(TP0, 100, new ReplicaPlacementInfo(0), Collections.singletonList(new ReplicaPlacementInfo(0)), Collections.singletonList(new ReplicaPlacementInfo(1)));
ExecutionTask task = new ExecutionTask(0, proposal, ExecutionTask.TaskType.INTER_BROKER_REPLICA_ACTION, EXECUTION_ALERTING_THRESHOLD_MS);
task.inProgress(MOCK_CURRENT_TIME);
AlterPartitionReassignmentsResult result = ExecutionUtils.submitReplicaReassignmentTasks(adminClient, Collections.singletonList(task));
assertEquals(1, result.values().size());
// Expect topic deletion -- i.e. or it has never been created.
assertTrue(verifyFutureError(result.values().get(TP0), Errors.UNKNOWN_TOPIC_OR_PARTITION.exception().getClass()));
}
use of org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult in project cruise-control by linkedin.
the class ExecutionUtilsTest method testProcessAlterPartitionReassignmentResult.
@Test
public void testProcessAlterPartitionReassignmentResult() throws Exception {
// Case 1: Handle null result input. Expect no side effect.
ExecutionUtils.processAlterPartitionReassignmentsResult(null, Collections.emptySet(), Collections.emptySet(), Collections.emptySet());
// Case 2: Handle successful execution results
AlterPartitionReassignmentsResult result = EasyMock.mock(AlterPartitionReassignmentsResult.class);
EasyMock.expect(result.values()).andReturn(getKafkaFutureByTopicPartition(null)).once();
EasyMock.replay(result);
ExecutionUtils.processAlterPartitionReassignmentsResult(result, Collections.emptySet(), Collections.emptySet(), Collections.emptySet());
EasyMock.verify(result);
EasyMock.reset(result);
// Case 3: Handle invalid replica assignment exception
EasyMock.expect(result.values()).andReturn(getKafkaFutureByTopicPartition(new ExecutionException(Errors.INVALID_REPLICA_ASSIGNMENT.exception()))).once();
EasyMock.replay(result);
Set<TopicPartition> deadTopicPartitions = new HashSet<>();
ExecutionUtils.processAlterPartitionReassignmentsResult(result, Collections.emptySet(), deadTopicPartitions, Collections.emptySet());
assertEquals(Collections.singleton(new TopicPartition(TOPIC_NAME, P0.partition())), deadTopicPartitions);
EasyMock.verify(result);
EasyMock.reset(result);
// Case 4: Handle unknown topic or partition exception
EasyMock.expect(result.values()).andReturn(getKafkaFutureByTopicPartition(new ExecutionException(Errors.UNKNOWN_TOPIC_OR_PARTITION.exception()))).once();
EasyMock.replay(result);
Set<TopicPartition> deletedTopicPartitions = new HashSet<>();
ExecutionUtils.processAlterPartitionReassignmentsResult(result, deletedTopicPartitions, Collections.emptySet(), Collections.emptySet());
assertEquals(Collections.singleton(new TopicPartition(TOPIC_NAME, P0.partition())), deletedTopicPartitions);
EasyMock.verify(result);
EasyMock.reset(result);
// Case 5: Handle no reassign in progress exception
EasyMock.expect(result.values()).andReturn(getKafkaFutureByTopicPartition(new ExecutionException(Errors.NO_REASSIGNMENT_IN_PROGRESS.exception()))).once();
EasyMock.replay(result);
Set<TopicPartition> noReassignmentToCancelTopicPartitions = new HashSet<>();
ExecutionUtils.processAlterPartitionReassignmentsResult(result, Collections.emptySet(), Collections.emptySet(), noReassignmentToCancelTopicPartitions);
assertEquals(Collections.singleton(new TopicPartition(TOPIC_NAME, P0.partition())), noReassignmentToCancelTopicPartitions);
EasyMock.verify(result);
EasyMock.reset(result);
// Case 6: Handle execution timeout exception. Expect no side effect.
org.apache.kafka.common.errors.TimeoutException kafkaTimeoutException = new org.apache.kafka.common.errors.TimeoutException();
EasyMock.expect(result.values()).andReturn(getKafkaFutureByTopicPartition(new ExecutionException(kafkaTimeoutException))).times(2);
EasyMock.replay(result);
Exception thrownException = assertThrows(IllegalStateException.class, () -> {
ExecutionUtils.processAlterPartitionReassignmentsResult(result, Collections.emptySet(), Collections.emptySet(), Collections.emptySet());
});
Assert.assertEquals(kafkaTimeoutException, thrownException.getCause());
EasyMock.verify(result);
EasyMock.reset(result);
// Case 7: Handle future wait interrupted exception
EasyMock.expect(result.values()).andReturn(getKafkaFutureByTopicPartition(new InterruptedException())).times(2);
EasyMock.replay(result);
ExecutionUtils.processAlterPartitionReassignmentsResult(result, Collections.emptySet(), Collections.emptySet(), Collections.emptySet());
EasyMock.verify(result);
EasyMock.reset(result);
}
Aggregations