handle devices agreed to be inactive during master re-election
Change-Id: Ia193d7210a8319f04ce957f2bd4a0479b88d15a8
Showing
3 changed files
with
77 additions
and
2 deletions
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment