Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
1144c98
Change the elect leader RPC
jsancio Apr 10, 2019
d6728de
Election type support in the controller
jsancio May 6, 2019
6a5a58b
Implement kafka-elect-leaders command
jsancio May 7, 2019
3261276
Add PartitionLeaderNotAvailable exception
jsancio May 9, 2019
cf9e4c8
Add tests for partition state machine
jsancio May 9, 2019
23f6eeb
Merge the preferred election command test suites
jsancio May 10, 2019
33ec321
Add framework for testing LeaderElectionCommand
jsancio May 13, 2019
fcebc1e
Close AdminClient after elect leader command
jsancio May 14, 2019
5bcf3cf
Propagate leader information during election
jsancio May 14, 2019
35af0cc
Refactor controller to return leader election result
jsancio May 15, 2019
0f945b3
Add a top level error to the leader election RPC
jsancio May 16, 2019
144d8c2
Query all partitions after authorization
jsancio May 16, 2019
41b16c9
Only fetch topic config if allowUnclean is not set
jsancio May 16, 2019
9ddba69
Implement electPreferredLeaders using electLeaders
jsancio May 16, 2019
8674e72
Do not assume cluster authorization error
jsancio May 17, 2019
282d900
Change old command error semantic to mathc the new electLeaders RPC
jsancio May 20, 2019
e61f7ab
Merge remote-tracking branch 'upstream/trunk' into election-rpc
jsancio May 20, 2019
524e8b9
Update documentation
jsancio May 20, 2019
a0b588c
Merge remote-tracking branch 'upstream/trunk' into election-rpc
jsancio May 20, 2019
bf0820e
Fix checkstyle
jsancio May 20, 2019
4f60fa8
Either right bias is only supported in Scala 2.12
jsancio May 20, 2019
7efac6a
Add deprecation notice to the upgrade document
jsancio May 21, 2019
242b413
Change the admin test to now use deprecated APIs
jsancio May 21, 2019
6ebb040
Don't return partitions that didn't need election
jsancio May 22, 2019
edbe381
Move the byte to ElectionType conversion function
jsancio May 22, 2019
48cfdfa
Implement all() for ElectLeadersResult
jsancio May 22, 2019
9f3466d
Avoid unnecessary copy when generating response
jsancio May 23, 2019
fdc5dfb
Merge remote-tracking branch 'upstream/trunk' into election-rpc
jsancio May 23, 2019
b806b26
For unclean filter partitions with a live leader
jsancio May 24, 2019
4fd6420
Use Set for collection of topics
jsancio May 24, 2019
092b3e4
Merge remote-tracking branch 'upstream/trunk' into election-rpc
jsancio May 24, 2019
7dd3e01
It compiles in scala 2.11.x
jsancio May 24, 2019
0709771
Merge remote-tracking branch 'upstream/trunk' into election-rpc
jsancio May 28, 2019
95432ce
Remove extra match case introduced during merge
jsancio May 28, 2019
6d53f26
Make a mutable copy of the topic Set
jsancio May 29, 2019
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
17 changes: 17 additions & 0 deletions bin/kafka-leader-election.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

exec $(dirname $0)/kafka-run-class.sh kafka.admin.LeaderElectionCommand "$@"
17 changes: 17 additions & 0 deletions bin/windows/kafka-leader-election.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@echo off
rem Licensed to the Apache Software Foundation (ASF) under one or more
rem contributor license agreements. See the NOTICE file distributed with
rem this work for additional information regarding copyright ownership.
rem The ASF licenses this file to You under the Apache License, Version 2.0
rem (the "License"); you may not use this file except in compliance with
rem the License. You may obtain a copy of the License at
rem
rem http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rem See the License for the specific language governing permissions and
rem limitations under the License.

"%~dp0kafka-run-class.bat" kafka.admin.LeaderElectionCommand %*
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@

package org.apache.kafka.clients.admin;

import java.time.Duration;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.kafka.common.ElectionType;
import org.apache.kafka.common.Metric;
import org.apache.kafka.common.MetricName;
import org.apache.kafka.common.TopicPartition;
Expand All @@ -26,12 +34,6 @@
import org.apache.kafka.common.annotation.InterfaceStability;
import org.apache.kafka.common.config.ConfigResource;

import java.time.Duration;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

/**
* The administrative client for Kafka, which supports managing and inspecting topics, brokers, configurations and ACLs.
*
Expand Down Expand Up @@ -839,35 +841,75 @@ public DeleteConsumerGroupsResult deleteConsumerGroups(Collection<String> groupI
}

/**
* Elect the preferred broker of the given {@code partitions} as leader, or
* elect the preferred broker for all partitions as leader if the argument to {@code partitions} is null.
* Elect the preferred replica as leader for topic partitions.
*
* This is a convenience method for {@link #electPreferredLeaders(Collection, ElectPreferredLeadersOptions)}
* with default options.
* See the overload for more details.
* This is a convenience method for {@link #electLeaders(ElectionType, Set, ElectLeadersOptions)}
* with preferred election type and default options.
*
* This operation is supported by brokers with version 2.2.0 or higher.
*
* @param partitions The partitions for which the preferred leader should be elected.
* @return The ElectPreferredLeadersResult.
* @deprecated Since 2.4.0. Use {@link #electLeaders(ElectionType, Set)}.
*/
@Deprecated
public ElectPreferredLeadersResult electPreferredLeaders(Collection<TopicPartition> partitions) {
return electPreferredLeaders(partitions, new ElectPreferredLeadersOptions());
}

/**
* Elect the preferred broker of the given {@code partitions} as leader, or
* elect the preferred broker for all partitions as leader if the argument to {@code partitions} is null.
* Elect the preferred replica as leader for topic partitions.
*
* This is a convenience method for {@link #electLeaders(ElectionType, Set, ElectLeadersOptions)}
* with preferred election type.
*
* This operation is supported by brokers with version 2.2.0 or higher.
*
* @param partitions The partitions for which the preferred leader should be elected.
* @param options The options to use when electing the preferred leaders.
* @return The ElectPreferredLeadersResult.
* @deprecated Since 2.4.0. Use {@link #electLeaders(ElectionType, Set, ElectLeadersOptions)}.
*/
@Deprecated
public ElectPreferredLeadersResult electPreferredLeaders(Collection<TopicPartition> partitions,
ElectPreferredLeadersOptions options) {
final ElectLeadersOptions newOptions = new ElectLeadersOptions();
newOptions.timeoutMs(options.timeoutMs());
final Set<TopicPartition> topicPartitions = partitions == null ? null : new HashSet<>(partitions);

return new ElectPreferredLeadersResult(electLeaders(ElectionType.PREFERRED, topicPartitions, newOptions));
}

/**
* Elect a replica as leader for topic partitions.
*
* This is a convenience method for {@link #electLeaders(ElectionType, Set, ElectLeadersOptions)}
* with default options.
*
* @param electionType The type of election to conduct.
* @param partitions The topics and partitions for which to conduct elections.
* @return The ElectLeadersResult.
*/
public ElectLeadersResult electLeaders(ElectionType electionType, Set<TopicPartition> partitions) {
return electLeaders(electionType, partitions, new ElectLeadersOptions());
}

/**
* Elect a replica as leader for the given {@code partitions}, or for all partitions if the argumentl
* to {@code partitions} is null.
*
* This operation is not transactional so it may succeed for some partitions while fail for others.
*
* It may take several seconds after this method returns
* success for all the brokers in the cluster to become aware that the partitions have new leaders.
* During this time, {@link AdminClient#describeTopics(Collection)}
* may not return information about the partitions' new leaders.
* It may take several seconds after this method returns success for all the brokers in the cluster
* to become aware that the partitions have new leaders. During this time,
* {@link AdminClient#describeTopics(Collection)} may not return information about the partitions'
* new leaders.
*
* This operation is supported by brokers with version 2.2.0 or higher.
* This operation is supported by brokers with version 2.2.0 or later if preferred eleciton is use;
* otherwise the brokers most be 2.4.0 or higher.
*
* <p>The following exceptions can be anticipated when calling {@code get()} on the futures obtained from
* the returned {@code ElectPreferredLeadersResult}:</p>
* <p>The following exceptions can be anticipated when calling {@code get()} on the future obtained
* from the returned {@code ElectLeadersResult}:</p>
* <ul>
* <li>{@link org.apache.kafka.common.errors.ClusterAuthorizationException}
* if the authenticated user didn't have alter access to the cluster.</li>
Expand All @@ -883,12 +925,15 @@ public ElectPreferredLeadersResult electPreferredLeaders(Collection<TopicPartiti
* if the preferred leader was not alive or not in the ISR.</li>
* </ul>
*
* @param partitions The partitions for which the preferred leader should be elected.
* @param options The options to use when electing the preferred leaders.
* @return The ElectPreferredLeadersResult.
* @param electionType The type of election to conduct.
* @param partitions The topics and partitions for which to conduct elections.
* @param options The options to use when electing the leaders.
* @return The ElectLeadersResult.
*/
public abstract ElectPreferredLeadersResult electPreferredLeaders(Collection<TopicPartition> partitions,
ElectPreferredLeadersOptions options);
public abstract ElectLeadersResult electLeaders(
ElectionType electionType,
Set<TopicPartition> partitions,
ElectLeadersOptions options);

/**
* Get the metrics kept by the adminClient
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.kafka.clients.admin;

import org.apache.kafka.common.annotation.InterfaceStability;

/**
* Options for {@link AdminClient#electLeaders(ElectionType, Set, ElectLeadersOptions)}.
*
* The API of this class is evolving, see {@link AdminClient} for details.
*/
@InterfaceStability.Evolving
final public class ElectLeadersOptions extends AbstractOptions<ElectLeadersOptions> {
Comment thread
jsancio marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.kafka.clients.admin;


import java.util.Map;
import java.util.Optional;
import org.apache.kafka.common.KafkaFuture;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.annotation.InterfaceStability;
import org.apache.kafka.common.internals.KafkaFutureImpl;

/**
* The result of {@link AdminClient#electLeaders(ElectionType, Set, ElectLeadersOptions)}
*
* The API of this class is evolving, see {@link AdminClient} for details.
*/
@InterfaceStability.Evolving
final public class ElectLeadersResult {
Comment thread
jsancio marked this conversation as resolved.
private final KafkaFutureImpl<Map<TopicPartition, Optional<Throwable>>> electionFuture;

ElectLeadersResult(KafkaFutureImpl<Map<TopicPartition, Optional<Throwable>>> electionFuture) {
this.electionFuture = electionFuture;
}

/**
* <p>Get a future for the topic partitions for which a leader election was attempted.
* If the election succeeded then the value for a topic partition will be the empty Optional.
* Otherwise the election failed and the Optional will be set with the error.</p>
*/
public KafkaFuture<Map<TopicPartition, Optional<Throwable>>> partitions() {
return electionFuture;
}

/**
* Return a future which succeeds if all the topic elections succeed.
*/
public KafkaFuture<Void> all() {
final KafkaFutureImpl<Void> result = new KafkaFutureImpl<>();

partitions().whenComplete(
new KafkaFuture.BiConsumer<Map<TopicPartition, Optional<Throwable>>, Throwable>() {
@Override
public void accept(Map<TopicPartition, Optional<Throwable>> topicPartitions, Throwable throwable) {
if (throwable != null) {
result.completeExceptionally(throwable);
} else {
for (Optional<Throwable> exception : topicPartitions.values()) {
if (exception.isPresent()) {
result.completeExceptionally(exception.get());
return;
}
}
result.complete(null);
}
}
});

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@
package org.apache.kafka.clients.admin;

import org.apache.kafka.common.annotation.InterfaceStability;

import java.util.Collection;

/**
* Options for {@link AdminClient#electPreferredLeaders(Collection, ElectPreferredLeadersOptions)}.
*
* The API of this class is evolving, see {@link AdminClient} for details.
*
* @deprecated Since 2.4.0. Use {@link AdminClient#electLeaders(ElectionType, Set, ElectLeadersOptions)}.
*/
@InterfaceStability.Evolving
@Deprecated
public class ElectPreferredLeadersOptions extends AbstractOptions<ElectPreferredLeadersOptions> {
}
Loading