Search in sources :

Example 1 with AlterPartitionReassignmentsResult

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()));
}
Also used : TopicPartition(org.apache.kafka.common.TopicPartition) AlterPartitionReassignmentsResult(org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult) ReplicaPlacementInfo(com.linkedin.kafka.cruisecontrol.model.ReplicaPlacementInfo) AdminClient(org.apache.kafka.clients.admin.AdminClient) Test(org.junit.Test)

Example 2 with AlterPartitionReassignmentsResult

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());
}
Also used : ElectLeadersResult(org.apache.kafka.clients.admin.ElectLeadersResult) AlterPartitionReassignmentsResult(org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult) Node(org.apache.kafka.common.Node) ArrayList(java.util.ArrayList) TopicDescription(org.apache.kafka.clients.admin.TopicDescription) ReplicaPlacementInfo(com.linkedin.kafka.cruisecontrol.model.ReplicaPlacementInfo) AdminClient(org.apache.kafka.clients.admin.AdminClient) Test(org.junit.Test)

Example 3 with AlterPartitionReassignmentsResult

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();
}
Also used : AlterPartitionReassignmentsResult(org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult) TopicDescription(org.apache.kafka.clients.admin.TopicDescription) ReplicaPlacementInfo(com.linkedin.kafka.cruisecontrol.model.ReplicaPlacementInfo) AdminClient(org.apache.kafka.clients.admin.AdminClient) Test(org.junit.Test)

Example 4 with AlterPartitionReassignmentsResult

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()));
}
Also used : AlterPartitionReassignmentsResult(org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult) ReplicaPlacementInfo(com.linkedin.kafka.cruisecontrol.model.ReplicaPlacementInfo) AdminClient(org.apache.kafka.clients.admin.AdminClient) Test(org.junit.Test)

Example 5 with AlterPartitionReassignmentsResult

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);
}
Also used : AlterPartitionReassignmentsResult(org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult) ElectionNotNeededException(org.apache.kafka.common.errors.ElectionNotNeededException) NotControllerException(org.apache.kafka.common.errors.NotControllerException) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) ExecutionException(java.util.concurrent.ExecutionException) UnknownTopicOrPartitionException(org.apache.kafka.common.errors.UnknownTopicOrPartitionException) PreferredLeaderNotAvailableException(org.apache.kafka.common.errors.PreferredLeaderNotAvailableException) TopicPartition(org.apache.kafka.common.TopicPartition) ExecutionException(java.util.concurrent.ExecutionException) HashSet(java.util.HashSet) Test(org.junit.Test)

Aggregations

AlterPartitionReassignmentsResult (org.apache.kafka.clients.admin.AlterPartitionReassignmentsResult)5 Test (org.junit.Test)5 ReplicaPlacementInfo (com.linkedin.kafka.cruisecontrol.model.ReplicaPlacementInfo)4 AdminClient (org.apache.kafka.clients.admin.AdminClient)4 TopicDescription (org.apache.kafka.clients.admin.TopicDescription)2 TopicPartition (org.apache.kafka.common.TopicPartition)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 ExecutionException (java.util.concurrent.ExecutionException)1 ElectLeadersResult (org.apache.kafka.clients.admin.ElectLeadersResult)1 Node (org.apache.kafka.common.Node)1 ElectionNotNeededException (org.apache.kafka.common.errors.ElectionNotNeededException)1 InvalidTopicException (org.apache.kafka.common.errors.InvalidTopicException)1 NotControllerException (org.apache.kafka.common.errors.NotControllerException)1 PreferredLeaderNotAvailableException (org.apache.kafka.common.errors.PreferredLeaderNotAvailableException)1 UnknownTopicOrPartitionException (org.apache.kafka.common.errors.UnknownTopicOrPartitionException)1