Ayaka Koshibe

modificiations to emit BACKUP_CHANGED Mastership events

Change-Id: Id61dcc9dc42c8c246313afbec8d19142e6c855a5

Conflicts:
	core/net/src/main/java/org/onlab/onos/net/device/impl/DeviceManager.java
...@@ -40,7 +40,9 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -40,7 +40,9 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
40 MASTER_CHANGED, 40 MASTER_CHANGED,
41 41
42 /** 42 /**
43 - * Signifies that the list of backup nodes has changed. 43 + * Signifies that the list of backup nodes has changed. If
44 + * the change in the backups list is accompanied by a change in
45 + * master, the event is subsumed by MASTER_CHANGED.
44 */ 46 */
45 BACKUPS_CHANGED 47 BACKUPS_CHANGED
46 } 48 }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onlab.onos.store.mastership.impl; 16 package org.onlab.onos.store.mastership.impl;
17 17
18 import static org.onlab.onos.mastership.MastershipEvent.Type.MASTER_CHANGED; 18 import static org.onlab.onos.mastership.MastershipEvent.Type.MASTER_CHANGED;
19 +import static org.onlab.onos.mastership.MastershipEvent.Type.BACKUPS_CHANGED;
19 import static org.apache.commons.lang3.concurrent.ConcurrentUtils.putIfAbsent; 20 import static org.apache.commons.lang3.concurrent.ConcurrentUtils.putIfAbsent;
20 21
21 import java.util.HashSet; 22 import java.util.HashSet;
...@@ -43,6 +44,7 @@ import org.onlab.onos.store.serializers.KryoNamespaces; ...@@ -43,6 +44,7 @@ import org.onlab.onos.store.serializers.KryoNamespaces;
43 import org.onlab.onos.store.serializers.KryoSerializer; 44 import org.onlab.onos.store.serializers.KryoSerializer;
44 import org.onlab.util.KryoNamespace; 45 import org.onlab.util.KryoNamespace;
45 46
47 +import com.google.common.base.Objects;
46 import com.hazelcast.core.EntryEvent; 48 import com.hazelcast.core.EntryEvent;
47 import com.hazelcast.core.EntryListener; 49 import com.hazelcast.core.EntryListener;
48 import com.hazelcast.core.IAtomicLong; 50 import com.hazelcast.core.IAtomicLong;
...@@ -297,8 +299,7 @@ implements MastershipStore { ...@@ -297,8 +299,7 @@ implements MastershipStore {
297 case NONE: 299 case NONE:
298 rv.reassign(nodeId, NONE, STANDBY); 300 rv.reassign(nodeId, NONE, STANDBY);
299 roleMap.put(deviceId, rv); 301 roleMap.put(deviceId, rv);
300 - // TODO: BACKUPS_CHANGED? 302 + return new MastershipEvent(BACKUPS_CHANGED, deviceId, rv.roleInfo());
301 - return null;
302 default: 303 default:
303 log.warn("unknown Mastership Role {}", currentRole); 304 log.warn("unknown Mastership Role {}", currentRole);
304 } 305 }
...@@ -327,7 +328,8 @@ implements MastershipStore { ...@@ -327,7 +328,8 @@ implements MastershipStore {
327 roleMap.put(deviceId, rv); 328 roleMap.put(deviceId, rv);
328 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo()); 329 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
329 } else { 330 } else {
330 - // no master candidate 331 + // No master candidate - no more backups, device is likely
332 + // fully disconnected
331 roleMap.put(deviceId, rv); 333 roleMap.put(deviceId, rv);
332 // Should there be new event type? 334 // Should there be new event type?
333 return null; 335 return null;
...@@ -338,8 +340,7 @@ implements MastershipStore { ...@@ -338,8 +340,7 @@ implements MastershipStore {
338 boolean modified = rv.reassign(nodeId, STANDBY, NONE); 340 boolean modified = rv.reassign(nodeId, STANDBY, NONE);
339 if (modified) { 341 if (modified) {
340 roleMap.put(deviceId, rv); 342 roleMap.put(deviceId, rv);
341 - // TODO: BACKUPS_CHANGED? 343 + return new MastershipEvent(BACKUPS_CHANGED, deviceId, rv.roleInfo());
342 - return null;
343 } 344 }
344 return null; 345 return null;
345 default: 346 default:
...@@ -441,8 +442,18 @@ implements MastershipStore { ...@@ -441,8 +442,18 @@ implements MastershipStore {
441 442
442 @Override 443 @Override
443 public void entryUpdated(EntryEvent<DeviceId, RoleValue> event) { 444 public void entryUpdated(EntryEvent<DeviceId, RoleValue> event) {
444 - notifyDelegate(new MastershipEvent( 445 + // compare old and current RoleValues. If master is different,
445 - MASTER_CHANGED, event.getKey(), event.getValue().roleInfo())); 446 + // emit MASTER_CHANGED. else, emit BACKUPS_CHANGED.
447 + RoleValue oldValue = event.getOldValue();
448 + RoleValue newValue = event.getValue();
449 +
450 + if (Objects.equal(oldValue.get(MASTER), newValue.get(MASTER))) {
451 + notifyDelegate(new MastershipEvent(
452 + MASTER_CHANGED, event.getKey(), event.getValue().roleInfo()));
453 + } else {
454 + notifyDelegate(new MastershipEvent(
455 + BACKUPS_CHANGED, event.getKey(), event.getValue().roleInfo()));
456 + }
446 } 457 }
447 458
448 @Override 459 @Override
......
...@@ -55,6 +55,13 @@ final class RoleValue { ...@@ -55,6 +55,13 @@ final class RoleValue {
55 return value.get(type); 55 return value.get(type);
56 } 56 }
57 57
58 + /**
59 + * Returns the first node to match the MastershipRole, or if there
60 + * are none, null.
61 + *
62 + * @param type the role
63 + * @return a node ID or null
64 + */
58 public NodeId get(MastershipRole type) { 65 public NodeId get(MastershipRole type) {
59 return value.get(type).isEmpty() ? null : value.get(type).get(0); 66 return value.get(type).isEmpty() ? null : value.get(type).get(0);
60 } 67 }
......
...@@ -214,11 +214,11 @@ public class DistributedMastershipStoreTest { ...@@ -214,11 +214,11 @@ public class DistributedMastershipStoreTest {
214 dms.roleMap.get(DID1).nodesOfRole(STANDBY).size()); 214 dms.roleMap.get(DID1).nodesOfRole(STANDBY).size());
215 215
216 //If STANDBY, should drop to NONE 216 //If STANDBY, should drop to NONE
217 - assertNull("wrong event:", dms.relinquishRole(N1, DID1)); 217 + assertEquals("wrong event:", Type.BACKUPS_CHANGED, dms.relinquishRole(N1, DID1).type());
218 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1)); 218 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1));
219 219
220 //NONE - nothing happens 220 //NONE - nothing happens
221 - assertNull("wrong event:", dms.relinquishRole(N1, DID2)); 221 + assertEquals("wrong event:", Type.BACKUPS_CHANGED, dms.relinquishRole(N1, DID2).type());
222 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2)); 222 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2));
223 223
224 } 224 }
......
...@@ -51,13 +51,6 @@ import com.google.common.cache.CacheBuilder; ...@@ -51,13 +51,6 @@ import com.google.common.cache.CacheBuilder;
51 * After a role request is submitted the role changer keeps track of the 51 * After a role request is submitted the role changer keeps track of the
52 * pending request, collects the reply (if any) and times out the request 52 * pending request, collects the reply (if any) and times out the request
53 * if necessary. 53 * if necessary.
54 - *
55 - * To simplify role handling we only keep track of the /last/ pending
56 - * role reply send to the switch. If multiple requests are pending and
57 - * we receive replies for earlier requests we ignore them. However, this
58 - * way of handling pending requests implies that we could wait forever if
59 - * a new request is submitted before the timeout triggers. If necessary
60 - * we could work around that though.
61 */ 54 */
62 class RoleManager implements RoleHandler { 55 class RoleManager implements RoleHandler {
63 protected static final long NICIRA_EXPERIMENTER = 0x2320; 56 protected static final long NICIRA_EXPERIMENTER = 0x2320;
......