Ayaka Koshibe
Committed by Madan Jampani

Create local storage for topic candidates mapping. This also includes:

 - using Optional in Leadership, and some commenting.
 - using MutableBooleans + compute()

    part of: Device Mastership store on top of LeadershipService
    Reference: ONOS-76

Conflicts:
	core/api/src/main/java/org/onosproject/cluster/LeadershipService.java
	core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DistributedLeadershipManager.java

Change-Id: I7f090abb123cf23bb5126a935a6e72be00f3e3ce
...@@ -85,7 +85,7 @@ public class LeaderCommand extends AbstractShellCommand { ...@@ -85,7 +85,7 @@ public class LeaderCommand extends AbstractShellCommand {
85 } 85 }
86 86
87 private void displayCandidates(Map<String, Leadership> leaderBoard, 87 private void displayCandidates(Map<String, Leadership> leaderBoard,
88 - Map<String, List<NodeId>> candidates) { 88 + Map<String, Leadership> candidates) {
89 print("--------------------------------------------------------------"); 89 print("--------------------------------------------------------------");
90 print(FMT_C, "Topic", "Leader", "Candidates"); 90 print(FMT_C, "Topic", "Leader", "Candidates");
91 print("--------------------------------------------------------------"); 91 print("--------------------------------------------------------------");
...@@ -94,13 +94,13 @@ public class LeaderCommand extends AbstractShellCommand { ...@@ -94,13 +94,13 @@ public class LeaderCommand extends AbstractShellCommand {
94 .stream() 94 .stream()
95 .sorted(leadershipComparator) 95 .sorted(leadershipComparator)
96 .forEach(l -> { 96 .forEach(l -> {
97 - List<NodeId> list = candidates.get(l.topic()); 97 + List<NodeId> list = candidates.get(l.topic()).candidates();
98 print(FMT_C, 98 print(FMT_C,
99 l.topic(), 99 l.topic(),
100 l.leader(), 100 l.leader(),
101 - list.remove(0).toString()); 101 + list.get(0).toString());
102 // formatting hacks to get it into a table 102 // formatting hacks to get it into a table
103 - list.forEach(n -> print(FMT_C, " ", " ", n)); 103 + list.subList(1, list.size()).forEach(n -> print(FMT_C, " ", " ", n));
104 print(FMT_C, " ", " ", " "); 104 print(FMT_C, " ", " ", " ");
105 }); 105 });
106 print("--------------------------------------------------------------"); 106 print("--------------------------------------------------------------");
...@@ -139,7 +139,7 @@ public class LeaderCommand extends AbstractShellCommand { ...@@ -139,7 +139,7 @@ public class LeaderCommand extends AbstractShellCommand {
139 print("%s", json(leaderBoard)); 139 print("%s", json(leaderBoard));
140 } else { 140 } else {
141 if (showCandidates) { 141 if (showCandidates) {
142 - Map<String, List<NodeId>> candidates = leaderService.getCandidates(); 142 + Map<String, Leadership> candidates = leaderService.getCandidates();
143 displayCandidates(leaderBoard, candidates); 143 displayCandidates(leaderBoard, candidates);
144 } else { 144 } else {
145 displayLeaders(leaderBoard); 145 displayLeaders(leaderBoard);
......
...@@ -17,6 +17,7 @@ package org.onosproject.cluster; ...@@ -17,6 +17,7 @@ package org.onosproject.cluster;
17 17
18 import java.util.Objects; 18 import java.util.Objects;
19 import java.util.List; 19 import java.util.List;
20 +import java.util.Optional;
20 21
21 import org.joda.time.DateTime; 22 import org.joda.time.DateTime;
22 23
...@@ -33,19 +34,21 @@ import com.google.common.collect.ImmutableList; ...@@ -33,19 +34,21 @@ import com.google.common.collect.ImmutableList;
33 * rest in decreasing preference order.</li> 34 * rest in decreasing preference order.</li>
34 * <li>The epoch is the logical age of a Leadership construct, and should be 35 * <li>The epoch is the logical age of a Leadership construct, and should be
35 * used for comparing two Leaderships, but only of the same topic.</li> 36 * used for comparing two Leaderships, but only of the same topic.</li>
37 + * <li>The leader may be null if its accuracy can't be guaranteed. This applies
38 + * to CANDIDATES_CHANGED events and candidate board contents.</li>
36 * </ul> 39 * </ul>
37 */ 40 */
38 public class Leadership { 41 public class Leadership {
39 42
40 private final String topic; 43 private final String topic;
41 - private final NodeId leader; 44 + private final Optional<NodeId> leader;
42 private final List<NodeId> candidates; 45 private final List<NodeId> candidates;
43 private final long epoch; 46 private final long epoch;
44 private final long electedTime; 47 private final long electedTime;
45 48
46 public Leadership(String topic, NodeId leader, long epoch, long electedTime) { 49 public Leadership(String topic, NodeId leader, long epoch, long electedTime) {
47 this.topic = topic; 50 this.topic = topic;
48 - this.leader = leader; 51 + this.leader = Optional.of(leader);
49 this.candidates = ImmutableList.of(leader); 52 this.candidates = ImmutableList.of(leader);
50 this.epoch = epoch; 53 this.epoch = epoch;
51 this.electedTime = electedTime; 54 this.electedTime = electedTime;
...@@ -54,7 +57,16 @@ public class Leadership { ...@@ -54,7 +57,16 @@ public class Leadership {
54 public Leadership(String topic, NodeId leader, List<NodeId> candidates, 57 public Leadership(String topic, NodeId leader, List<NodeId> candidates,
55 long epoch, long electedTime) { 58 long epoch, long electedTime) {
56 this.topic = topic; 59 this.topic = topic;
57 - this.leader = leader; 60 + this.leader = Optional.of(leader);
61 + this.candidates = ImmutableList.copyOf(candidates);
62 + this.epoch = epoch;
63 + this.electedTime = electedTime;
64 + }
65 +
66 + public Leadership(String topic, List<NodeId> candidates,
67 + long epoch, long electedTime) {
68 + this.topic = topic;
69 + this.leader = Optional.empty();
58 this.candidates = ImmutableList.copyOf(candidates); 70 this.candidates = ImmutableList.copyOf(candidates);
59 this.epoch = epoch; 71 this.epoch = epoch;
60 this.electedTime = electedTime; 72 this.electedTime = electedTime;
...@@ -74,8 +86,9 @@ public class Leadership { ...@@ -74,8 +86,9 @@ public class Leadership {
74 * 86 *
75 * @return leader node. 87 * @return leader node.
76 */ 88 */
89 + // This will return Optional<NodeId> in the future.
77 public NodeId leader() { 90 public NodeId leader() {
78 - return leader; 91 + return leader.orElse(null);
79 } 92 }
80 93
81 /** 94 /**
......
...@@ -43,14 +43,14 @@ public class LeadershipEvent extends AbstractEvent<LeadershipEvent.Type, Leaders ...@@ -43,14 +43,14 @@ public class LeadershipEvent extends AbstractEvent<LeadershipEvent.Type, Leaders
43 LEADER_REELECTED, 43 LEADER_REELECTED,
44 44
45 /** 45 /**
46 - * Signifies that the leader has been booted and lost leadership. The event subject is the 46 + * Signifies that the leader has been booted and lost leadership. The
47 - * former leader. 47 + * event subject is the former leader.
48 */ 48 */
49 LEADER_BOOTED, 49 LEADER_BOOTED,
50 50
51 /** 51 /**
52 * Signifies that the list of candidates for leadership for a topic has 52 * Signifies that the list of candidates for leadership for a topic has
53 - * changed. 53 + * changed. This event does not guarantee accurate leader information.
54 */ 54 */
55 CANDIDATES_CHANGED 55 CANDIDATES_CHANGED
56 } 56 }
......
...@@ -76,9 +76,9 @@ public interface LeadershipService { ...@@ -76,9 +76,9 @@ public interface LeadershipService {
76 /** 76 /**
77 * Returns the candidates for all known topics. 77 * Returns the candidates for all known topics.
78 * 78 *
79 - * @return A map of topics to lists of NodeIds. 79 + * @return A mapping from topics to up-to-date candidate info.
80 */ 80 */
81 - Map<String, List<NodeId>> getCandidates(); 81 + Map<String, Leadership> getCandidates();
82 82
83 /** 83 /**
84 * Returns the candidates for a given topic. 84 * Returns the candidates for a given topic.
......
...@@ -65,7 +65,7 @@ public class LeadershipServiceAdapter implements LeadershipService { ...@@ -65,7 +65,7 @@ public class LeadershipServiceAdapter implements LeadershipService {
65 } 65 }
66 66
67 @Override 67 @Override
68 - public Map<String, List<NodeId>> getCandidates() { 68 + public Map<String, Leadership> getCandidates() {
69 return null; 69 return null;
70 } 70 }
71 71
......
...@@ -576,7 +576,7 @@ public class HazelcastLeadershipService implements LeadershipService { ...@@ -576,7 +576,7 @@ public class HazelcastLeadershipService implements LeadershipService {
576 } 576 }
577 577
578 @Override 578 @Override
579 - public Map<String, List<NodeId>> getCandidates() { 579 + public Map<String, Leadership> getCandidates() {
580 return null; 580 return null;
581 } 581 }
582 582
......
...@@ -111,7 +111,7 @@ public class SimpleLeadershipManager implements LeadershipService { ...@@ -111,7 +111,7 @@ public class SimpleLeadershipManager implements LeadershipService {
111 } 111 }
112 112
113 @Override 113 @Override
114 - public Map<String, List<NodeId>> getCandidates() { 114 + public Map<String, Leadership> getCandidates() {
115 return null; 115 return null;
116 } 116 }
117 117
......