Ayaka Koshibe

handle devices agreed to be inactive during master re-election

Change-Id: Ia193d7210a8319f04ce957f2bd4a0479b88d15a8
...@@ -42,6 +42,7 @@ public interface DeviceService { ...@@ -42,6 +42,7 @@ public interface DeviceService {
42 * @param deviceId device identifier 42 * @param deviceId device identifier
43 * @return designated mastership role 43 * @return designated mastership role
44 */ 44 */
45 + //XXX do we want this method here when MastershipService already does?
45 MastershipRole getRole(DeviceId deviceId); 46 MastershipRole getRole(DeviceId deviceId);
46 47
47 48
......
...@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Component; ...@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Component;
10 import org.apache.felix.scr.annotations.Deactivate; 10 import org.apache.felix.scr.annotations.Deactivate;
11 import org.apache.felix.scr.annotations.Reference; 11 import org.apache.felix.scr.annotations.Reference;
12 import org.apache.felix.scr.annotations.ReferenceCardinality; 12 import org.apache.felix.scr.annotations.ReferenceCardinality;
13 +import org.apache.felix.scr.annotations.ReferencePolicy;
13 import org.apache.felix.scr.annotations.Service; 14 import org.apache.felix.scr.annotations.Service;
14 import org.onlab.onos.cluster.ClusterService; 15 import org.onlab.onos.cluster.ClusterService;
15 import org.onlab.onos.cluster.MastershipEvent; 16 import org.onlab.onos.cluster.MastershipEvent;
...@@ -19,6 +20,7 @@ import org.onlab.onos.cluster.MastershipTerm; ...@@ -19,6 +20,7 @@ import org.onlab.onos.cluster.MastershipTerm;
19 import org.onlab.onos.cluster.NodeId; 20 import org.onlab.onos.cluster.NodeId;
20 import org.onlab.onos.net.DeviceId; 21 import org.onlab.onos.net.DeviceId;
21 import org.onlab.onos.net.MastershipRole; 22 import org.onlab.onos.net.MastershipRole;
23 +import org.onlab.onos.net.device.DeviceService;
22 import org.onlab.onos.store.common.AbstractHazelcastStore; 24 import org.onlab.onos.store.common.AbstractHazelcastStore;
23 25
24 import com.google.common.collect.ImmutableSet; 26 import com.google.common.collect.ImmutableSet;
...@@ -51,6 +53,10 @@ implements MastershipStore { ...@@ -51,6 +53,10 @@ implements MastershipStore {
51 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 53 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 protected ClusterService clusterService; 54 protected ClusterService clusterService;
53 55
56 + //FIXME: need to guarantee that this will be met, sans circular dependencies
57 + @Reference(policy = ReferencePolicy.DYNAMIC)
58 + protected DeviceService deviceService;
59 +
54 @Override 60 @Override
55 @Activate 61 @Activate
56 public void activate() { 62 public void activate() {
...@@ -230,9 +236,11 @@ implements MastershipStore { ...@@ -230,9 +236,11 @@ implements MastershipStore {
230 236
231 //helper for "re-electing" a new master for a given device 237 //helper for "re-electing" a new master for a given device
232 private NodeId reelect(NodeId current, DeviceId deviceId) { 238 private NodeId reelect(NodeId current, DeviceId deviceId) {
239 +
233 for (byte [] node : backups.keySet()) { 240 for (byte [] node : backups.keySet()) {
234 NodeId nid = deserialize(node); 241 NodeId nid = deserialize(node);
235 - if (!current.equals(nid)) { 242 + //if a device dies we shouldn't pick another master for it.
243 + if (!current.equals(nid) && (deviceService.isAvailable(deviceId))) {
236 return nid; 244 return nid;
237 } 245 }
238 } 246 }
......
...@@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull; ...@@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull;
5 import static org.junit.Assert.assertTrue; 5 import static org.junit.Assert.assertTrue;
6 import static org.onlab.onos.net.MastershipRole.*; 6 import static org.onlab.onos.net.MastershipRole.*;
7 7
8 +import java.util.List;
8 import java.util.Set; 9 import java.util.Set;
9 import java.util.concurrent.CountDownLatch; 10 import java.util.concurrent.CountDownLatch;
10 import java.util.concurrent.TimeUnit; 11 import java.util.concurrent.TimeUnit;
...@@ -25,7 +26,13 @@ import org.onlab.onos.cluster.MastershipEvent.Type; ...@@ -25,7 +26,13 @@ import org.onlab.onos.cluster.MastershipEvent.Type;
25 import org.onlab.onos.cluster.MastershipStoreDelegate; 26 import org.onlab.onos.cluster.MastershipStoreDelegate;
26 import org.onlab.onos.cluster.MastershipTerm; 27 import org.onlab.onos.cluster.MastershipTerm;
27 import org.onlab.onos.cluster.NodeId; 28 import org.onlab.onos.cluster.NodeId;
29 +import org.onlab.onos.net.Device;
28 import org.onlab.onos.net.DeviceId; 30 import org.onlab.onos.net.DeviceId;
31 +import org.onlab.onos.net.MastershipRole;
32 +import org.onlab.onos.net.Port;
33 +import org.onlab.onos.net.PortNumber;
34 +import org.onlab.onos.net.device.DeviceListener;
35 +import org.onlab.onos.net.device.DeviceService;
29 import org.onlab.onos.store.common.StoreManager; 36 import org.onlab.onos.store.common.StoreManager;
30 import org.onlab.onos.store.common.StoreService; 37 import org.onlab.onos.store.common.StoreService;
31 import org.onlab.onos.store.common.TestStoreManager; 38 import org.onlab.onos.store.common.TestStoreManager;
...@@ -80,6 +87,7 @@ public class DistributedMastershipStoreTest { ...@@ -80,6 +87,7 @@ public class DistributedMastershipStoreTest {
80 87
81 dms = new TestDistributedMastershipStore(storeMgr, serializationMgr); 88 dms = new TestDistributedMastershipStore(storeMgr, serializationMgr);
82 dms.clusterService = new TestClusterService(); 89 dms.clusterService = new TestClusterService();
90 + dms.deviceService = new TestDeviceService();
83 dms.activate(); 91 dms.activate();
84 92
85 testStore = (TestDistributedMastershipStore) dms; 93 testStore = (TestDistributedMastershipStore) dms;
...@@ -179,8 +187,11 @@ public class DistributedMastershipStoreTest { ...@@ -179,8 +187,11 @@ public class DistributedMastershipStoreTest {
179 assertEquals("wrong role for NONE:", MASTER, dms.requestRole(DID1)); 187 assertEquals("wrong role for NONE:", MASTER, dms.requestRole(DID1));
180 //no backup, no new MASTER/event 188 //no backup, no new MASTER/event
181 assertNull("wrong event:", dms.unsetMaster(N1, DID1)); 189 assertNull("wrong event:", dms.unsetMaster(N1, DID1));
182 - //add backup CN2, get it elected MASTER 190 +
183 dms.requestRole(DID1); 191 dms.requestRole(DID1);
192 + ((TestDeviceService) dms.deviceService).active.add(DID1);
193 +
194 + //add backup CN2, get it elected MASTER by relinquishing
184 testStore.setCurrent(CN2); 195 testStore.setCurrent(CN2);
185 dms.requestRole(DID1); 196 dms.requestRole(DID1);
186 assertEquals("wrong event:", Type.MASTER_CHANGED, dms.unsetMaster(N1, DID1).type()); 197 assertEquals("wrong event:", Type.MASTER_CHANGED, dms.unsetMaster(N1, DID1).type());
...@@ -193,6 +204,12 @@ public class DistributedMastershipStoreTest { ...@@ -193,6 +204,12 @@ public class DistributedMastershipStoreTest {
193 //NONE - nothing happens 204 //NONE - nothing happens
194 assertNull("wrong event:", dms.unsetMaster(N1, DID2)); 205 assertNull("wrong event:", dms.unsetMaster(N1, DID2));
195 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2)); 206 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2));
207 +
208 + //for a device that turned off (not active) - status to NONE
209 + ((TestDeviceService) dms.deviceService).active.clear();
210 + assertNull("extraneous event:", dms.unsetMaster(N2, DID1));
211 + assertEquals("wrong role", NONE, dms.getRole(N2, DID1));
212 +
196 } 213 }
197 214
198 @Ignore("Ignore until Delegate spec. is clear.") 215 @Ignore("Ignore until Delegate spec. is clear.")
...@@ -299,4 +316,53 @@ public class DistributedMastershipStoreTest { ...@@ -299,4 +316,53 @@ public class DistributedMastershipStoreTest {
299 } 316 }
300 317
301 } 318 }
319 +
320 + private class TestDeviceService implements DeviceService {
321 +
322 + Set<DeviceId> active = Sets.newHashSet();
323 +
324 + @Override
325 + public int getDeviceCount() {
326 + return 0;
327 + }
328 +
329 + @Override
330 + public Iterable<Device> getDevices() {
331 + return null;
332 + }
333 +
334 + @Override
335 + public Device getDevice(DeviceId deviceId) {
336 + return null;
337 + }
338 +
339 + @Override
340 + public MastershipRole getRole(DeviceId deviceId) {
341 + return null;
342 + }
343 +
344 + @Override
345 + public List<Port> getPorts(DeviceId deviceId) {
346 + return null;
347 + }
348 +
349 + @Override
350 + public Port getPort(DeviceId deviceId, PortNumber portNumber) {
351 + return null;
352 + }
353 +
354 + @Override
355 + public boolean isAvailable(DeviceId deviceId) {
356 + return active.contains(deviceId);
357 + }
358 +
359 + @Override
360 + public void addListener(DeviceListener listener) {
361 + }
362 +
363 + @Override
364 + public void removeListener(DeviceListener listener) {
365 + }
366 +
367 + }
302 } 368 }
......