Ayaka Koshibe

add roleInfo structure and backup_changed mastership event

Change-Id: Iedee219fe250d681377d73a50a71f5fa72cd7802
...@@ -11,7 +11,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -11,7 +11,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
11 11
12 //do we worry about explicitly setting slaves/equals? probably not, 12 //do we worry about explicitly setting slaves/equals? probably not,
13 //to keep it simple 13 //to keep it simple
14 - NodeId master; 14 + NodeId node;
15 15
16 /** 16 /**
17 * Type of mastership events. 17 * Type of mastership events.
...@@ -20,7 +20,12 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -20,7 +20,12 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
20 /** 20 /**
21 * Signifies that the master for a device has changed. 21 * Signifies that the master for a device has changed.
22 */ 22 */
23 - MASTER_CHANGED 23 + MASTER_CHANGED,
24 +
25 + /**
26 + * Signifies that the list of backup nodes has changed.
27 + */
28 + BACKUPS_CHANGED
24 } 29 }
25 30
26 /** 31 /**
...@@ -29,11 +34,11 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -29,11 +34,11 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
29 * 34 *
30 * @param type device event type 35 * @param type device event type
31 * @param device event device subject 36 * @param device event device subject
32 - * @param master master ID subject 37 + * @param node master ID subject
33 */ 38 */
34 - public MastershipEvent(Type type, DeviceId device, NodeId master) { 39 + public MastershipEvent(Type type, DeviceId device, NodeId node) {
35 super(type, device); 40 super(type, device);
36 - this.master = master; 41 + this.node = node;
37 } 42 }
38 43
39 /** 44 /**
...@@ -47,15 +52,15 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -47,15 +52,15 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
47 */ 52 */
48 public MastershipEvent(Type type, DeviceId device, NodeId master, long time) { 53 public MastershipEvent(Type type, DeviceId device, NodeId master, long time) {
49 super(type, device, time); 54 super(type, device, time);
50 - this.master = master; 55 + this.node = master;
51 } 56 }
52 57
53 /** 58 /**
54 - * Returns the current master's ID as a subject. 59 + * Returns the NodeID of the node responsible for triggering the event.
55 * 60 *
56 - * @return master ID subject 61 + * @return node ID as a subject
57 */ 62 */
58 - public NodeId master() { 63 + public NodeId node() {
59 - return master; 64 + return node;
60 } 65 }
61 } 66 }
......
...@@ -228,8 +228,8 @@ implements MastershipService, MastershipAdminService { ...@@ -228,8 +228,8 @@ implements MastershipService, MastershipAdminService {
228 return true; 228 return true;
229 } 229 }
230 //else { 230 //else {
231 - //FIXME: break tie for equal-sized clusters, 231 + //FIXME: break tie for equal-sized clusters, by number of
232 - // maybe by number of connected switches 232 + // connected switches, then masters, then nodeId hash
233 // } 233 // }
234 return false; 234 return false;
235 } 235 }
......
...@@ -367,7 +367,7 @@ public class DeviceManager ...@@ -367,7 +367,7 @@ public class DeviceManager
367 final NodeId myNodeId = clusterService.getLocalNode().id(); 367 final NodeId myNodeId = clusterService.getLocalNode().id();
368 368
369 log.info("## got Mastershipevent for dev {}", did); 369 log.info("## got Mastershipevent for dev {}", did);
370 - if (myNodeId.equals(event.master())) { 370 + if (myNodeId.equals(event.node())) {
371 MastershipTerm term = termService.getMastershipTerm(did); 371 MastershipTerm term = termService.getMastershipTerm(did);
372 372
373 if (!myNodeId.equals(term.master())) { 373 if (!myNodeId.equals(term.master())) {
......
...@@ -86,7 +86,7 @@ public class ReplicaInfoManager implements ReplicaInfoService { ...@@ -86,7 +86,7 @@ public class ReplicaInfoManager implements ReplicaInfoService {
86 final List<NodeId> standbyList = Collections.<NodeId>emptyList(); 86 final List<NodeId> standbyList = Collections.<NodeId>emptyList();
87 eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED, 87 eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED,
88 event.subject(), 88 event.subject(),
89 - new ReplicaInfo(event.master(), standbyList))); 89 + new ReplicaInfo(event.node(), standbyList)));
90 } 90 }
91 } 91 }
92 92
......
...@@ -79,9 +79,9 @@ implements MastershipStore { ...@@ -79,9 +79,9 @@ implements MastershipStore {
79 }; 79 };
80 80
81 roleMap = new SMap(theInstance.getMap("nodeRoles"), this.serializer); 81 roleMap = new SMap(theInstance.getMap("nodeRoles"), this.serializer);
82 + roleMap.addEntryListener((new RemoteMasterShipEventHandler()), true);
82 terms = new SMap(theInstance.getMap("terms"), this.serializer); 83 terms = new SMap(theInstance.getMap("terms"), this.serializer);
83 clusterSize = theInstance.getAtomicLong("clustersize"); 84 clusterSize = theInstance.getAtomicLong("clustersize");
84 - roleMap.addEntryListener((new RemoteMasterShipEventHandler()), true);
85 85
86 log.info("Started"); 86 log.info("Started");
87 } 87 }
......
...@@ -8,6 +8,7 @@ import java.util.Map; ...@@ -8,6 +8,7 @@ import java.util.Map;
8 8
9 import org.onlab.onos.cluster.NodeId; 9 import org.onlab.onos.cluster.NodeId;
10 import org.onlab.onos.net.MastershipRole; 10 import org.onlab.onos.net.MastershipRole;
11 +import org.onlab.onos.store.common.RoleInfo;
11 12
12 /** 13 /**
13 * A structure that holds node mastership roles associated with a 14 * A structure that holds node mastership roles associated with a
...@@ -77,7 +78,6 @@ public class RoleValue { ...@@ -77,7 +78,6 @@ public class RoleValue {
77 * @param from the old role 78 * @param from the old role
78 * @param to the new role 79 * @param to the new role
79 */ 80 */
80 - // might want to add anyways as default behavior
81 public void reassign(NodeId nodeId, MastershipRole from, MastershipRole to) { 81 public void reassign(NodeId nodeId, MastershipRole from, MastershipRole to) {
82 remove(from, nodeId); 82 remove(from, nodeId);
83 add(to, nodeId); 83 add(to, nodeId);
...@@ -91,12 +91,22 @@ public class RoleValue { ...@@ -91,12 +91,22 @@ public class RoleValue {
91 * @param to the new NodeId 91 * @param to the new NodeId
92 * @param type the role associated with the old NodeId 92 * @param type the role associated with the old NodeId
93 */ 93 */
94 - // might want to add anyways as default behavior
95 public void replace(NodeId from, NodeId to, MastershipRole type) { 94 public void replace(NodeId from, NodeId to, MastershipRole type) {
96 remove(type, from); 95 remove(type, from);
97 add(type, to); 96 add(type, to);
98 } 97 }
99 98
99 + /**
100 + * Summarizes this RoleValue as a RoleInfo. Note that master and/or backups
101 + * may be empty, so the values should be checked for safety.
102 + *
103 + * @return the RoleInfo.
104 + */
105 + public RoleInfo roleInfo() {
106 + return new RoleInfo(
107 + get(MastershipRole.MASTER), nodesOfRole(MastershipRole.STANDBY));
108 + }
109 +
100 @Override 110 @Override
101 public String toString() { 111 public String toString() {
102 final StringBuilder builder = new StringBuilder(); 112 final StringBuilder builder = new StringBuilder();
......
...@@ -218,7 +218,7 @@ public class DistributedMastershipStoreTest { ...@@ -218,7 +218,7 @@ public class DistributedMastershipStoreTest {
218 public void notify(MastershipEvent event) { 218 public void notify(MastershipEvent event) {
219 assertEquals("wrong event:", Type.MASTER_CHANGED, event.type()); 219 assertEquals("wrong event:", Type.MASTER_CHANGED, event.type());
220 assertEquals("wrong subject", DID1, event.subject()); 220 assertEquals("wrong subject", DID1, event.subject());
221 - assertEquals("wrong subject", N1, event.master()); 221 + assertEquals("wrong subject", N1, event.node());
222 addLatch.countDown(); 222 addLatch.countDown();
223 } 223 }
224 }; 224 };
......
1 +package org.onlab.onos.store.common;
2 +
3 +import java.util.Collections;
4 +import java.util.LinkedList;
5 +import java.util.List;
6 +import java.util.Objects;
7 +
8 +import org.onlab.onos.cluster.NodeId;
9 +
10 +import static com.google.common.base.Preconditions.checkNotNull;
11 +
12 +/**
13 + * A container for detailed role information for a device,
14 + * within the current cluster. Role attributes include current
15 + * master and a preference-ordered list of backup nodes.
16 + */
17 +public class RoleInfo {
18 + private final NodeId master;
19 + private final List<NodeId> backups;
20 +
21 + public RoleInfo(NodeId master, List<NodeId> backups) {
22 + this.master = master;
23 + this.backups = new LinkedList<>();
24 +
25 + this.backups.addAll(checkNotNull(backups));
26 + }
27 +
28 + public NodeId master() {
29 + return master;
30 + }
31 +
32 + public List<NodeId> backups() {
33 + return Collections.unmodifiableList(backups);
34 + }
35 +
36 + @Override
37 + public boolean equals(Object other) {
38 + if (other == null) {
39 + return false;
40 + }
41 + if (!(other instanceof RoleInfo)) {
42 + return false;
43 + }
44 + RoleInfo that = (RoleInfo) other;
45 + if (!Objects.equals(this.master, that.master)) {
46 + return false;
47 + }
48 + if (!Objects.equals(this.backups, that.backups)) {
49 + return false;
50 + }
51 + return true;
52 + }
53 +
54 + @Override
55 + public int hashCode() {
56 + return Objects.hash(master, backups.hashCode());
57 + }
58 +
59 + @Override
60 + public String toString() {
61 + final StringBuilder builder = new StringBuilder();
62 + builder.append("master: \n\t").append(master).append("\n");
63 + builder.append("backups: \n");
64 + for (NodeId n : backups) {
65 + builder.append("\t").append(n).append("\n");
66 + }
67 + return builder.toString();
68 + }
69 +}
1 +package org.onlab.onos.store.common;
2 +
3 +import java.util.List;
4 +
5 +import org.junit.Test;
6 +import org.onlab.onos.cluster.NodeId;
7 +
8 +import com.google.common.collect.Lists;
9 +
10 +import static org.junit.Assert.assertEquals;
11 +import static org.junit.Assert.assertNotEquals;
12 +
13 +/**
14 + * Test to check behavioral correctness of the RoleInfo structure.
15 + */
16 +public class RoleInfoTest {
17 + private static final NodeId N1 = new NodeId("n1");
18 + private static final NodeId N2 = new NodeId("n2");
19 + private static final NodeId N3 = new NodeId("n3");
20 + private static final NodeId N4 = new NodeId("n4");
21 +
22 + private static final List<NodeId> BKUP1 = Lists.newArrayList(N2, N3);
23 + private static final List<NodeId> BKUP2 = Lists.newArrayList(N3, N4);
24 +
25 + private static final RoleInfo RI1 = new RoleInfo(N1, BKUP1);
26 + private static final RoleInfo RI2 = new RoleInfo(N1, BKUP2);
27 + private static final RoleInfo RI3 = new RoleInfo(N2, BKUP1);
28 +
29 + @Test
30 + public void basics() {
31 + assertEquals("wrong master", new NodeId("n1"), RI1.master());
32 + System.out.println(RI1.toString());
33 + assertEquals("wrong Backups", RI1.backups(), Lists.newArrayList(N2, N3));
34 +
35 + assertNotEquals("equals() broken", RI1, RI2);
36 + assertNotEquals("equals() broken", RI1, RI3);
37 +
38 + List<NodeId> bkup3 = Lists.newArrayList(N3, new NodeId("n4"));
39 + assertEquals("equals() broken", new RoleInfo(N1, bkup3), RI2);
40 + }
41 +}