LeadershipStore updates:
- Now tracking leader and candidates for a topic using a single map.
- Using term numbers that are incremented by one every time a new leader is elected.
- Introduced a separate LeadershipStore to conform to the manager-store pattern
Change-Id: I1d03a6c5e8ff0e68ef0c1e3a6c2d425c4856e470
diff --git a/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java b/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java
index 7d1f607..b0f7a8d 100644
--- a/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java
+++ b/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java
@@ -17,87 +17,73 @@
import org.onosproject.event.ListenerService;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.CompletableFuture;
/**
* Service for leader election.
+ * <p>
* Leadership contests are organized around topics. A instance can join the
* leadership race for a topic or withdraw from a race it has previously joined.
+ * <p>
* Listeners can be added to receive notifications asynchronously for various
* leadership contests.
+ * <p>
+ * When a node gets elected as a leader for a topic, all nodes receive notifications
+ * indicating a change in leadership.
*/
public interface LeadershipService
extends ListenerService<LeadershipEvent, LeadershipEventListener> {
/**
- * Returns the current leader for the topic.
+ * Returns the {@link NodeId node identifier} that is the current leader for a topic.
*
- * @param path topic
- * @return nodeId of the leader, null if so such topic exists.
+ * @param topic leadership topic
+ * @return node identifier of the current leader; {@code null} if there is no leader for the topic
*/
- NodeId getLeader(String path);
+ default NodeId getLeader(String topic) {
+ Leadership leadership = getLeadership(topic);
+ return leadership == null ? null : leadership.leaderNodeId();
+ }
/**
- * Returns the current leadership info for the topic.
+ * Returns the current {@link Leadership leadership} for a topic.
*
- * @param path topic
- * @return leadership info or null if so such topic exists.
+ * @param topic leadership topic
+ * @return leadership or {@code null} if no such topic exists
*/
- Leadership getLeadership(String path);
+ Leadership getLeadership(String topic);
/**
- * Returns the set of topics owned by the specified node.
+ * Returns the set of topics owned by the specified {@link NodeId node}.
*
- * @param nodeId node Id.
+ * @param nodeId node identifier.
* @return set of topics for which this node is the current leader.
*/
- Set<String> ownedTopics(NodeId nodeId);
+ default Set<String> ownedTopics(NodeId nodeId) {
+ return Maps.filterValues(getLeaderBoard(), v -> Objects.equal(nodeId, v.leaderNodeId())).keySet();
+ }
/**
- * Joins the leadership contest.
+ * Enters a leadership contest.
*
- * @param path topic for which this controller node wishes to be a leader
+ * @param topic leadership topic
* @return {@code Leadership} future
*/
- CompletableFuture<Leadership> runForLeadership(String path);
+ Leadership runForLeadership(String topic);
/**
* Withdraws from a leadership contest.
*
- * @param path topic for which this controller node no longer wishes to be a leader
- * @return future that is successfully completed when withdraw is done
+ * @param topic leadership topic
*/
- CompletableFuture<Void> withdraw(String path);
-
- /**
- * If the local nodeId is the leader for specified topic, this method causes it to
- * step down temporarily from leadership.
- * <p>
- * The node will continue to be in contention for leadership and can
- * potentially become the leader again if and when it becomes the highest
- * priority candidate
- * <p>
- * If the local nodeId is not the leader, this method will make no changes and
- * simply return false.
- *
- * @param path topic for which this controller node should give up leadership
- * @return true if this node stepped down from leadership, false otherwise
- */
- boolean stepdown(String path);
-
- /**
- * Moves the specified nodeId to the top of the candidates list for the topic.
- * <p>
- * If the node is not a candidate for this topic, this method will be a noop.
- *
- * @param path leadership topic
- * @param nodeId nodeId to make the top candidate
- * @return true if nodeId is now the top candidate, false otherwise
- */
- boolean makeTopCandidate(String path, NodeId nodeId);
+ void withdraw(String topic);
/**
* Returns the current leader board.
@@ -107,18 +93,22 @@
Map<String, Leadership> getLeaderBoard();
/**
- * Returns the candidates for all known topics.
+ * Returns the candidate nodes for each topic.
*
* @return A mapping from topics to corresponding list of candidates.
*/
- Map<String, List<NodeId>> getCandidates();
+ default Map<String, List<NodeId>> getCandidates() {
+ return ImmutableMap.copyOf(Maps.transformValues(getLeaderBoard(), v -> ImmutableList.copyOf(v.candidates())));
+ }
/**
- * Returns the candidates for a given topic.
+ * Returns the candidate nodes for a given topic.
*
- * @param path topic
- * @return A lists of NodeIds, which may be empty.
+ * @param topic leadership topic
+ * @return A lists of {@link NodeId nodeIds}, which may be empty.
*/
- List<NodeId> getCandidates(String path);
-
-}
+ default List<NodeId> getCandidates(String topic) {
+ Leadership leadership = getLeadership(topic);
+ return leadership == null ? ImmutableList.of() : ImmutableList.copyOf(leadership.candidates());
+ }
+}
\ No newline at end of file