Ayaka Koshibe

fixes related to getRole() assumptions

Change-Id: Icf19d95714dc217200eed021a495d9a78440ca8e
1 package org.onlab.onos.mastership; 1 package org.onlab.onos.mastership;
2 2
3 -import org.onlab.onos.cluster.NodeId;
4 import org.onlab.onos.cluster.RoleInfo; 3 import org.onlab.onos.cluster.RoleInfo;
5 import org.onlab.onos.event.AbstractEvent; 4 import org.onlab.onos.event.AbstractEvent;
6 import org.onlab.onos.net.DeviceId; 5 import org.onlab.onos.net.DeviceId;
...@@ -56,19 +55,6 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -56,19 +55,6 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
56 } 55 }
57 56
58 /** 57 /**
59 - * Returns the NodeID of the node associated with the event.
60 - * For MASTER_CHANGED this is the newly elected master, and for
61 - * BACKUPS_CHANGED, this is the node that was newly added, removed, or
62 - * whose position was changed in the list.
63 - *
64 - * @return node ID as a subject
65 - */
66 - //XXX to-be removed - or keep for convenience?
67 - public NodeId node() {
68 - return roleInfo.master();
69 - }
70 -
71 - /**
72 * Returns the current role state for the subject. 58 * Returns the current role state for the subject.
73 * 59 *
74 * @return RoleInfo associated with Device ID subject 60 * @return RoleInfo associated with Device ID subject
......
...@@ -227,10 +227,14 @@ implements MastershipService, MastershipAdminService { ...@@ -227,10 +227,14 @@ implements MastershipService, MastershipAdminService {
227 if (clusterService.getNodes().size() > (clusterSize.intValue() / 2)) { 227 if (clusterService.getNodes().size() > (clusterSize.intValue() / 2)) {
228 return true; 228 return true;
229 } 229 }
230 - //else { 230 +// else {
231 //FIXME: break tie for equal-sized clusters, by number of 231 //FIXME: break tie for equal-sized clusters, by number of
232 // connected switches, then masters, then nodeId hash 232 // connected switches, then masters, then nodeId hash
233 - // } 233 + // problem is, how do we get at channel info cleanly here?
234 + // Also, what's the time hit for a distributed store look-up
235 + // versus channel re-negotiation? bet on the latter being worse.
236 +
237 +// }
234 return false; 238 return false;
235 } 239 }
236 240
......
...@@ -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.node(), standbyList))); 89 + new ReplicaInfo(event.roleInfo().master(), standbyList)));
90 } 90 }
91 } 91 }
92 92
......
...@@ -91,23 +91,14 @@ implements MastershipStore { ...@@ -91,23 +91,14 @@ implements MastershipStore {
91 91
92 @Override 92 @Override
93 public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) { 93 public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) {
94 - NodeId current = getNode(MASTER, deviceId); 94 + final RoleValue roleInfo = getRoleValue(deviceId);
95 - if (current == null) { 95 + if (roleInfo.contains(MASTER, nodeId)) {
96 - if (isRole(STANDBY, nodeId, deviceId)) { 96 + return MASTER;
97 - //was previously standby, or set to standby from master 97 + }
98 - return MastershipRole.STANDBY; 98 + if (roleInfo.contains(STANDBY, nodeId)) {
99 - } else { 99 + return STANDBY;
100 - return MastershipRole.NONE;
101 - }
102 - } else {
103 - if (current.equals(nodeId)) {
104 - //*should* be in unusable, not always
105 - return MastershipRole.MASTER;
106 - } else {
107 - //may be in backups or unusable from earlier retirement
108 - return MastershipRole.STANDBY;
109 - }
110 } 100 }
101 + return NONE;
111 } 102 }
112 103
113 @Override 104 @Override
...@@ -124,10 +115,11 @@ implements MastershipStore { ...@@ -124,10 +115,11 @@ implements MastershipStore {
124 roleMap.put(deviceId, rv); 115 roleMap.put(deviceId, rv);
125 return null; 116 return null;
126 case STANDBY: 117 case STANDBY:
118 + case NONE:
127 NodeId current = rv.get(MASTER); 119 NodeId current = rv.get(MASTER);
128 if (current != null) { 120 if (current != null) {
129 //backup and replace current master 121 //backup and replace current master
130 - rv.reassign(nodeId, NONE, STANDBY); 122 + rv.reassign(current, NONE, STANDBY);
131 rv.replace(current, nodeId, MASTER); 123 rv.replace(current, nodeId, MASTER);
132 } else { 124 } else {
133 //no master before so just add. 125 //no master before so just add.
...@@ -137,12 +129,6 @@ implements MastershipStore { ...@@ -137,12 +129,6 @@ implements MastershipStore {
137 roleMap.put(deviceId, rv); 129 roleMap.put(deviceId, rv);
138 updateTerm(deviceId); 130 updateTerm(deviceId);
139 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo()); 131 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
140 - case NONE:
141 - rv.add(MASTER, nodeId);
142 - rv.reassign(nodeId, STANDBY, NONE);
143 - roleMap.put(deviceId, rv);
144 - updateTerm(deviceId);
145 - return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
146 default: 132 default:
147 log.warn("unknown Mastership Role {}", role); 133 log.warn("unknown Mastership Role {}", role);
148 return null; 134 return null;
...@@ -193,21 +179,28 @@ implements MastershipStore { ...@@ -193,21 +179,28 @@ implements MastershipStore {
193 switch (role) { 179 switch (role) {
194 case MASTER: 180 case MASTER:
195 rv.reassign(local, STANDBY, NONE); 181 rv.reassign(local, STANDBY, NONE);
182 + terms.putIfAbsent(deviceId, INIT);
196 roleMap.put(deviceId, rv); 183 roleMap.put(deviceId, rv);
197 break; 184 break;
198 case STANDBY: 185 case STANDBY:
199 rv.reassign(local, NONE, STANDBY); 186 rv.reassign(local, NONE, STANDBY);
200 roleMap.put(deviceId, rv); 187 roleMap.put(deviceId, rv);
201 terms.putIfAbsent(deviceId, INIT); 188 terms.putIfAbsent(deviceId, INIT);
202 -
203 break; 189 break;
204 case NONE: 190 case NONE:
205 - //claim mastership 191 + //either we're the first standby, or first to device.
206 - rv.add(MASTER, local); 192 + //for latter, claim mastership.
207 - rv.reassign(local, STANDBY, NONE); 193 + if (rv.get(MASTER) == null) {
194 + rv.add(MASTER, local);
195 + rv.reassign(local, STANDBY, NONE);
196 + updateTerm(deviceId);
197 + role = MastershipRole.MASTER;
198 + } else {
199 + rv.add(STANDBY, local);
200 + rv.reassign(local, NONE, STANDBY);
201 + role = MastershipRole.STANDBY;
202 + }
208 roleMap.put(deviceId, rv); 203 roleMap.put(deviceId, rv);
209 - updateTerm(deviceId);
210 - role = MastershipRole.MASTER;
211 break; 204 break;
212 default: 205 default:
213 log.warn("unknown Mastership Role {}", role); 206 log.warn("unknown Mastership Role {}", role);
...@@ -315,7 +308,10 @@ implements MastershipStore { ...@@ -315,7 +308,10 @@ implements MastershipStore {
315 RoleValue value = roleMap.get(deviceId); 308 RoleValue value = roleMap.get(deviceId);
316 if (value == null) { 309 if (value == null) {
317 value = new RoleValue(); 310 value = new RoleValue();
318 - roleMap.put(deviceId, value); 311 + RoleValue concurrentlyAdded = roleMap.putIfAbsent(deviceId, value);
312 + if (concurrentlyAdded != null) {
313 + return concurrentlyAdded;
314 + }
319 } 315 }
320 return value; 316 return value;
321 } 317 }
...@@ -329,16 +325,6 @@ implements MastershipStore { ...@@ -329,16 +325,6 @@ implements MastershipStore {
329 return null; 325 return null;
330 } 326 }
331 327
332 - //check if node is a certain role given a device
333 - private boolean isRole(
334 - MastershipRole role, NodeId nodeId, DeviceId deviceId) {
335 - RoleValue value = roleMap.get(deviceId);
336 - if (value != null) {
337 - return value.contains(role, nodeId);
338 - }
339 - return false;
340 - }
341 -
342 //adds or updates term information. 328 //adds or updates term information.
343 private void updateTerm(DeviceId deviceId) { 329 private void updateTerm(DeviceId deviceId) {
344 terms.lock(deviceId); 330 terms.lock(deviceId);
......
...@@ -97,6 +97,7 @@ public class DistributedMastershipStoreTest { ...@@ -97,6 +97,7 @@ public class DistributedMastershipStoreTest {
97 assertEquals("wrong role:", NONE, dms.getRole(N1, DID1)); 97 assertEquals("wrong role:", NONE, dms.getRole(N1, DID1));
98 testStore.put(DID1, N1, true, false, true); 98 testStore.put(DID1, N1, true, false, true);
99 assertEquals("wrong role:", MASTER, dms.getRole(N1, DID1)); 99 assertEquals("wrong role:", MASTER, dms.getRole(N1, DID1));
100 + testStore.put(DID1, N2, false, true, false);
100 assertEquals("wrong role:", STANDBY, dms.getRole(N2, DID1)); 101 assertEquals("wrong role:", STANDBY, dms.getRole(N2, DID1));
101 } 102 }
102 103
...@@ -155,6 +156,7 @@ public class DistributedMastershipStoreTest { ...@@ -155,6 +156,7 @@ public class DistributedMastershipStoreTest {
155 156
156 //switch over to N2 157 //switch over to N2
157 assertEquals("wrong event:", Type.MASTER_CHANGED, dms.setMaster(N2, DID1).type()); 158 assertEquals("wrong event:", Type.MASTER_CHANGED, dms.setMaster(N2, DID1).type());
159 + System.out.println(dms.getTermFor(DID1).master() + ":" + dms.getTermFor(DID1).termNumber());
158 assertEquals("wrong term", MastershipTerm.of(N2, 1), dms.getTermFor(DID1)); 160 assertEquals("wrong term", MastershipTerm.of(N2, 1), dms.getTermFor(DID1));
159 161
160 //orphan switch - should be rare case 162 //orphan switch - should be rare case
...@@ -182,14 +184,9 @@ public class DistributedMastershipStoreTest { ...@@ -182,14 +184,9 @@ public class DistributedMastershipStoreTest {
182 assertEquals("wrong event:", Type.MASTER_CHANGED, dms.relinquishRole(N1, DID1).type()); 184 assertEquals("wrong event:", Type.MASTER_CHANGED, dms.relinquishRole(N1, DID1).type());
183 assertEquals("wrong master", N2, dms.getMaster(DID1)); 185 assertEquals("wrong master", N2, dms.getMaster(DID1));
184 186
185 - //STANDBY - nothing here, either
186 - assertNull("wrong event:", dms.relinquishRole(N1, DID1));
187 - assertEquals("wrong role for node:", STANDBY, dms.getRole(N1, DID1));
188 -
189 //all nodes "give up" on device, which goes back to NONE. 187 //all nodes "give up" on device, which goes back to NONE.
190 assertNull("wrong event:", dms.relinquishRole(N2, DID1)); 188 assertNull("wrong event:", dms.relinquishRole(N2, DID1));
191 assertEquals("wrong role for node:", NONE, dms.getRole(N2, DID1)); 189 assertEquals("wrong role for node:", NONE, dms.getRole(N2, DID1));
192 - assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1));
193 190
194 assertEquals("wrong number of retired nodes", 2, 191 assertEquals("wrong number of retired nodes", 2,
195 dms.roleMap.get(DID1).nodesOfRole(NONE).size()); 192 dms.roleMap.get(DID1).nodesOfRole(NONE).size());
...@@ -201,6 +198,10 @@ public class DistributedMastershipStoreTest { ...@@ -201,6 +198,10 @@ public class DistributedMastershipStoreTest {
201 assertEquals("wrong number of backup nodes", 1, 198 assertEquals("wrong number of backup nodes", 1,
202 dms.roleMap.get(DID1).nodesOfRole(STANDBY).size()); 199 dms.roleMap.get(DID1).nodesOfRole(STANDBY).size());
203 200
201 + //If STANDBY, should drop to NONE
202 + assertNull("wrong event:", dms.relinquishRole(N1, DID1));
203 + assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1));
204 +
204 //NONE - nothing happens 205 //NONE - nothing happens
205 assertNull("wrong event:", dms.relinquishRole(N1, DID2)); 206 assertNull("wrong event:", dms.relinquishRole(N1, DID2));
206 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2)); 207 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2));
...@@ -218,7 +219,7 @@ public class DistributedMastershipStoreTest { ...@@ -218,7 +219,7 @@ public class DistributedMastershipStoreTest {
218 public void notify(MastershipEvent event) { 219 public void notify(MastershipEvent event) {
219 assertEquals("wrong event:", Type.MASTER_CHANGED, event.type()); 220 assertEquals("wrong event:", Type.MASTER_CHANGED, event.type());
220 assertEquals("wrong subject", DID1, event.subject()); 221 assertEquals("wrong subject", DID1, event.subject());
221 - assertEquals("wrong subject", N1, event.node()); 222 + assertEquals("wrong subject", N1, event.roleInfo().master());
222 addLatch.countDown(); 223 addLatch.countDown();
223 } 224 }
224 }; 225 };
......