Committed by
Gerrit Code Review
DistributedLeadershipManager tracks topic election candidates in addition to
leaders. Includes update to leaders CLI command to list candidates. part of: Device Mastership store on top of LeadershipService Reference: ONOS-76 Conflicts: core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DistributedLeadershipManager.java Change-Id: I587bb9e9ad16a9c8392969dde45001181053e5e6
Showing
7 changed files
with
88 additions
and
5 deletions
| ... | @@ -17,12 +17,15 @@ package org.onosproject.cli.net; | ... | @@ -17,12 +17,15 @@ package org.onosproject.cli.net; |
| 17 | 17 | ||
| 18 | import java.util.Comparator; | 18 | import java.util.Comparator; |
| 19 | import java.util.Map; | 19 | import java.util.Map; |
| 20 | +import java.util.List; | ||
| 20 | 21 | ||
| 21 | import org.apache.karaf.shell.commands.Command; | 22 | import org.apache.karaf.shell.commands.Command; |
| 23 | +import org.apache.karaf.shell.commands.Option; | ||
| 22 | import org.onlab.util.Tools; | 24 | import org.onlab.util.Tools; |
| 23 | import org.onosproject.cli.AbstractShellCommand; | 25 | import org.onosproject.cli.AbstractShellCommand; |
| 24 | import org.onosproject.cluster.Leadership; | 26 | import org.onosproject.cluster.Leadership; |
| 25 | import org.onosproject.cluster.LeadershipService; | 27 | import org.onosproject.cluster.LeadershipService; |
| 28 | +import org.onosproject.cluster.NodeId; | ||
| 26 | 29 | ||
| 27 | import com.fasterxml.jackson.databind.JsonNode; | 30 | import com.fasterxml.jackson.databind.JsonNode; |
| 28 | import com.fasterxml.jackson.databind.ObjectMapper; | 31 | import com.fasterxml.jackson.databind.ObjectMapper; |
| ... | @@ -36,6 +39,12 @@ import com.fasterxml.jackson.databind.node.ArrayNode; | ... | @@ -36,6 +39,12 @@ import com.fasterxml.jackson.databind.node.ArrayNode; |
| 36 | public class LeaderCommand extends AbstractShellCommand { | 39 | public class LeaderCommand extends AbstractShellCommand { |
| 37 | 40 | ||
| 38 | private static final String FMT = "%-20s | %-15s | %-6s | %-10s |"; | 41 | private static final String FMT = "%-20s | %-15s | %-6s | %-10s |"; |
| 42 | + private static final String FMT_C = "%-20s | %-15s | %-19s |"; | ||
| 43 | + | ||
| 44 | + @Option(name = "-c", aliases = "--candidates", | ||
| 45 | + description = "List candidate Nodes for each topic's leadership race", | ||
| 46 | + required = false, multiValued = false) | ||
| 47 | + private boolean showCandidates = false; | ||
| 39 | 48 | ||
| 40 | /** | 49 | /** |
| 41 | * Compares leaders, sorting by toString() output. | 50 | * Compares leaders, sorting by toString() output. |
| ... | @@ -75,6 +84,28 @@ public class LeaderCommand extends AbstractShellCommand { | ... | @@ -75,6 +84,28 @@ public class LeaderCommand extends AbstractShellCommand { |
| 75 | print("--------------------------------------------------------------"); | 84 | print("--------------------------------------------------------------"); |
| 76 | } | 85 | } |
| 77 | 86 | ||
| 87 | + private void displayCandidates(Map<String, Leadership> leaderBoard, | ||
| 88 | + Map<String, List<NodeId>> candidates) { | ||
| 89 | + print("--------------------------------------------------------------"); | ||
| 90 | + print(FMT_C, "Topic", "Leader", "Candidates"); | ||
| 91 | + print("--------------------------------------------------------------"); | ||
| 92 | + leaderBoard | ||
| 93 | + .values() | ||
| 94 | + .stream() | ||
| 95 | + .sorted(leadershipComparator) | ||
| 96 | + .forEach(l -> { | ||
| 97 | + List<NodeId> list = candidates.get(l.topic()); | ||
| 98 | + print(FMT_C, | ||
| 99 | + l.topic(), | ||
| 100 | + l.leader(), | ||
| 101 | + list.remove(0).toString()); | ||
| 102 | + // formatting hacks to get it into a table | ||
| 103 | + list.forEach(n -> print(FMT_C, " ", " ", n)); | ||
| 104 | + print(FMT_C, " ", " ", " "); | ||
| 105 | + }); | ||
| 106 | + print("--------------------------------------------------------------"); | ||
| 107 | + } | ||
| 108 | + | ||
| 78 | /** | 109 | /** |
| 79 | * Returns JSON node representing the leaders. | 110 | * Returns JSON node representing the leaders. |
| 80 | * | 111 | * |
| ... | @@ -91,6 +122,7 @@ public class LeaderCommand extends AbstractShellCommand { | ... | @@ -91,6 +122,7 @@ public class LeaderCommand extends AbstractShellCommand { |
| 91 | mapper.createObjectNode() | 122 | mapper.createObjectNode() |
| 92 | .put("topic", l.topic()) | 123 | .put("topic", l.topic()) |
| 93 | .put("leader", l.leader().toString()) | 124 | .put("leader", l.leader().toString()) |
| 125 | + .put("candidates", l.candidates().toString()) | ||
| 94 | .put("epoch", l.epoch()) | 126 | .put("epoch", l.epoch()) |
| 95 | .put("electedTime", Tools.timeAgo(l.electedTime())))); | 127 | .put("electedTime", Tools.timeAgo(l.electedTime())))); |
| 96 | 128 | ||
| ... | @@ -106,7 +138,12 @@ public class LeaderCommand extends AbstractShellCommand { | ... | @@ -106,7 +138,12 @@ public class LeaderCommand extends AbstractShellCommand { |
| 106 | if (outputJson()) { | 138 | if (outputJson()) { |
| 107 | print("%s", json(leaderBoard)); | 139 | print("%s", json(leaderBoard)); |
| 108 | } else { | 140 | } else { |
| 109 | - displayLeaders(leaderBoard); | 141 | + if (showCandidates) { |
| 142 | + Map<String, List<NodeId>> candidates = leaderService.getCandidates(); | ||
| 143 | + displayCandidates(leaderBoard, candidates); | ||
| 144 | + } else { | ||
| 145 | + displayLeaders(leaderBoard); | ||
| 146 | + } | ||
| 110 | } | 147 | } |
| 111 | } | 148 | } |
| 112 | } | 149 | } | ... | ... |
| ... | @@ -49,11 +49,10 @@ public class LeadershipEvent extends AbstractEvent<LeadershipEvent.Type, Leaders | ... | @@ -49,11 +49,10 @@ public class LeadershipEvent extends AbstractEvent<LeadershipEvent.Type, Leaders |
| 49 | LEADER_BOOTED, | 49 | LEADER_BOOTED, |
| 50 | 50 | ||
| 51 | /** | 51 | /** |
| 52 | - * Signifies that the list of candidates for leadership for a resource | 52 | + * Signifies that the list of candidates for leadership for a topic has |
| 53 | - * has changed. If the change in the backups list is accompanied by a | 53 | + * changed. |
| 54 | - * change in the leader, the event is subsumed by the leadership change. | ||
| 55 | */ | 54 | */ |
| 56 | - LEADER_CANDIDATES_CHANGED | 55 | + CANDIDATES_CHANGED |
| 57 | } | 56 | } |
| 58 | 57 | ||
| 59 | /** | 58 | /** | ... | ... |
| ... | @@ -17,6 +17,7 @@ package org.onosproject.cluster; | ... | @@ -17,6 +17,7 @@ package org.onosproject.cluster; |
| 17 | 17 | ||
| 18 | import java.util.Map; | 18 | import java.util.Map; |
| 19 | import java.util.Set; | 19 | import java.util.Set; |
| 20 | +import java.util.List; | ||
| 20 | 21 | ||
| 21 | /** | 22 | /** |
| 22 | * Service for leader election. | 23 | * Service for leader election. |
| ... | @@ -67,6 +68,19 @@ public interface LeadershipService { | ... | @@ -67,6 +68,19 @@ public interface LeadershipService { |
| 67 | Map<String, Leadership> getLeaderBoard(); | 68 | Map<String, Leadership> getLeaderBoard(); |
| 68 | 69 | ||
| 69 | /** | 70 | /** |
| 71 | + * Returns the candidates for all known topics. | ||
| 72 | + * @return A map of topics to lists of NodeIds. | ||
| 73 | + */ | ||
| 74 | + Map<String, List<NodeId>> getCandidates(); | ||
| 75 | + | ||
| 76 | + /** | ||
| 77 | + * Returns the candidates for a given topic. | ||
| 78 | + * @param path topic | ||
| 79 | + * @return A lists of NodeIds, which may be empty. | ||
| 80 | + */ | ||
| 81 | + List<NodeId> getCandidates(String path); | ||
| 82 | + | ||
| 83 | + /** | ||
| 70 | * Registers a event listener to be notified of leadership events. | 84 | * Registers a event listener to be notified of leadership events. |
| 71 | * @param listener listener that will asynchronously notified of leadership events. | 85 | * @param listener listener that will asynchronously notified of leadership events. |
| 72 | */ | 86 | */ | ... | ... |
| ... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.cluster; | 16 | package org.onosproject.cluster; |
| 17 | 17 | ||
| 18 | +import java.util.List; | ||
| 18 | import java.util.Map; | 19 | import java.util.Map; |
| 19 | import java.util.Set; | 20 | import java.util.Set; |
| 20 | 21 | ||
| ... | @@ -62,4 +63,14 @@ public class LeadershipServiceAdapter implements LeadershipService { | ... | @@ -62,4 +63,14 @@ public class LeadershipServiceAdapter implements LeadershipService { |
| 62 | public void removeListener(LeadershipEventListener listener) { | 63 | public void removeListener(LeadershipEventListener listener) { |
| 63 | 64 | ||
| 64 | } | 65 | } |
| 66 | + | ||
| 67 | + @Override | ||
| 68 | + public Map<String, List<NodeId>> getCandidates() { | ||
| 69 | + return null; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + @Override | ||
| 73 | + public List<NodeId> getCandidates(String path) { | ||
| 74 | + return null; | ||
| 75 | + } | ||
| 65 | } | 76 | } | ... | ... |
| ... | @@ -46,6 +46,7 @@ import org.slf4j.Logger; | ... | @@ -46,6 +46,7 @@ import org.slf4j.Logger; |
| 46 | import org.slf4j.LoggerFactory; | 46 | import org.slf4j.LoggerFactory; |
| 47 | 47 | ||
| 48 | import java.util.HashMap; | 48 | import java.util.HashMap; |
| 49 | +import java.util.List; | ||
| 49 | import java.util.Map; | 50 | import java.util.Map; |
| 50 | import java.util.Set; | 51 | import java.util.Set; |
| 51 | import java.util.concurrent.ExecutorService; | 52 | import java.util.concurrent.ExecutorService; |
| ... | @@ -573,4 +574,14 @@ public class HazelcastLeadershipService implements LeadershipService { | ... | @@ -573,4 +574,14 @@ public class HazelcastLeadershipService implements LeadershipService { |
| 573 | eventDispatcher.post(leadershipEvent); | 574 | eventDispatcher.post(leadershipEvent); |
| 574 | } | 575 | } |
| 575 | } | 576 | } |
| 577 | + | ||
| 578 | + @Override | ||
| 579 | + public Map<String, List<NodeId>> getCandidates() { | ||
| 580 | + return null; | ||
| 581 | + } | ||
| 582 | + | ||
| 583 | + @Override | ||
| 584 | + public List<NodeId> getCandidates(String path) { | ||
| 585 | + return null; | ||
| 586 | + } | ||
| 576 | } | 587 | } | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -17,6 +17,7 @@ package org.onosproject.store.trivial.impl; | ... | @@ -17,6 +17,7 @@ package org.onosproject.store.trivial.impl; |
| 17 | 17 | ||
| 18 | import static com.google.common.base.Preconditions.checkArgument; | 18 | import static com.google.common.base.Preconditions.checkArgument; |
| 19 | 19 | ||
| 20 | +import java.util.List; | ||
| 20 | import java.util.Map; | 21 | import java.util.Map; |
| 21 | import java.util.Map.Entry; | 22 | import java.util.Map.Entry; |
| 22 | import java.util.Set; | 23 | import java.util.Set; |
| ... | @@ -108,4 +109,14 @@ public class SimpleLeadershipManager implements LeadershipService { | ... | @@ -108,4 +109,14 @@ public class SimpleLeadershipManager implements LeadershipService { |
| 108 | public void removeListener(LeadershipEventListener listener) { | 109 | public void removeListener(LeadershipEventListener listener) { |
| 109 | listeners.remove(listener); | 110 | listeners.remove(listener); |
| 110 | } | 111 | } |
| 112 | + | ||
| 113 | + @Override | ||
| 114 | + public Map<String, List<NodeId>> getCandidates() { | ||
| 115 | + return null; | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + @Override | ||
| 119 | + public List<NodeId> getCandidates(String path) { | ||
| 120 | + return null; | ||
| 121 | + } | ||
| 111 | } | 122 | } | ... | ... |
-
Please register or login to post a comment