Ayaka Koshibe

handle devices agreed to be inactive during master re-election

Change-Id: Ia193d7210a8319f04ce957f2bd4a0479b88d15a8
......@@ -42,6 +42,7 @@ public interface DeviceService {
* @param deviceId device identifier
* @return designated mastership role
*/
//XXX do we want this method here when MastershipService already does?
MastershipRole getRole(DeviceId deviceId);
......
......@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.cluster.ClusterService;
import org.onlab.onos.cluster.MastershipEvent;
......@@ -19,6 +20,7 @@ import org.onlab.onos.cluster.MastershipTerm;
import org.onlab.onos.cluster.NodeId;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.net.device.DeviceService;
import org.onlab.onos.store.common.AbstractHazelcastStore;
import com.google.common.collect.ImmutableSet;
......@@ -51,6 +53,10 @@ implements MastershipStore {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterService clusterService;
//FIXME: need to guarantee that this will be met, sans circular dependencies
@Reference(policy = ReferencePolicy.DYNAMIC)
protected DeviceService deviceService;
@Override
@Activate
public void activate() {
......@@ -230,9 +236,11 @@ implements MastershipStore {
//helper for "re-electing" a new master for a given device
private NodeId reelect(NodeId current, DeviceId deviceId) {
for (byte [] node : backups.keySet()) {
NodeId nid = deserialize(node);
if (!current.equals(nid)) {
//if a device dies we shouldn't pick another master for it.
if (!current.equals(nid) && (deviceService.isAvailable(deviceId))) {
return nid;
}
}
......
......@@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.onlab.onos.net.MastershipRole.*;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
......@@ -25,7 +26,13 @@ import org.onlab.onos.cluster.MastershipEvent.Type;
import org.onlab.onos.cluster.MastershipStoreDelegate;
import org.onlab.onos.cluster.MastershipTerm;
import org.onlab.onos.cluster.NodeId;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.net.Port;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.device.DeviceListener;
import org.onlab.onos.net.device.DeviceService;
import org.onlab.onos.store.common.StoreManager;
import org.onlab.onos.store.common.StoreService;
import org.onlab.onos.store.common.TestStoreManager;
......@@ -80,6 +87,7 @@ public class DistributedMastershipStoreTest {
dms = new TestDistributedMastershipStore(storeMgr, serializationMgr);
dms.clusterService = new TestClusterService();
dms.deviceService = new TestDeviceService();
dms.activate();
testStore = (TestDistributedMastershipStore) dms;
......@@ -179,8 +187,11 @@ public class DistributedMastershipStoreTest {
assertEquals("wrong role for NONE:", MASTER, dms.requestRole(DID1));
//no backup, no new MASTER/event
assertNull("wrong event:", dms.unsetMaster(N1, DID1));
//add backup CN2, get it elected MASTER
dms.requestRole(DID1);
((TestDeviceService) dms.deviceService).active.add(DID1);
//add backup CN2, get it elected MASTER by relinquishing
testStore.setCurrent(CN2);
dms.requestRole(DID1);
assertEquals("wrong event:", Type.MASTER_CHANGED, dms.unsetMaster(N1, DID1).type());
......@@ -193,6 +204,12 @@ public class DistributedMastershipStoreTest {
//NONE - nothing happens
assertNull("wrong event:", dms.unsetMaster(N1, DID2));
assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2));
//for a device that turned off (not active) - status to NONE
((TestDeviceService) dms.deviceService).active.clear();
assertNull("extraneous event:", dms.unsetMaster(N2, DID1));
assertEquals("wrong role", NONE, dms.getRole(N2, DID1));
}
@Ignore("Ignore until Delegate spec. is clear.")
......@@ -299,4 +316,53 @@ public class DistributedMastershipStoreTest {
}
}
private class TestDeviceService implements DeviceService {
Set<DeviceId> active = Sets.newHashSet();
@Override
public int getDeviceCount() {
return 0;
}
@Override
public Iterable<Device> getDevices() {
return null;
}
@Override
public Device getDevice(DeviceId deviceId) {
return null;
}
@Override
public MastershipRole getRole(DeviceId deviceId) {
return null;
}
@Override
public List<Port> getPorts(DeviceId deviceId) {
return null;
}
@Override
public Port getPort(DeviceId deviceId, PortNumber portNumber) {
return null;
}
@Override
public boolean isAvailable(DeviceId deviceId) {
return active.contains(deviceId);
}
@Override
public void addListener(DeviceListener listener) {
}
@Override
public void removeListener(DeviceListener listener) {
}
}
}
......