Showing
7 changed files
with
180 additions
and
4 deletions
... | @@ -8,6 +8,8 @@ import org.onlab.onos.net.DeviceId; | ... | @@ -8,6 +8,8 @@ import org.onlab.onos.net.DeviceId; |
8 | */ | 8 | */ |
9 | public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceId> { | 9 | public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceId> { |
10 | 10 | ||
11 | + //do we worry about explicitly setting slaves/equals? probably not, | ||
12 | + //to keep it simple | ||
11 | NodeId master; | 13 | NodeId master; |
12 | 14 | ||
13 | /** | 15 | /** |
... | @@ -28,7 +30,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI | ... | @@ -28,7 +30,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI |
28 | * @param device event device subject | 30 | * @param device event device subject |
29 | * @param master master ID subject | 31 | * @param master master ID subject |
30 | */ | 32 | */ |
31 | - protected MastershipEvent(Type type, DeviceId device, NodeId master) { | 33 | + public MastershipEvent(Type type, DeviceId device, NodeId master) { |
32 | super(type, device); | 34 | super(type, device); |
33 | this.master = master; | 35 | this.master = master; |
34 | } | 36 | } |
... | @@ -42,7 +44,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI | ... | @@ -42,7 +44,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI |
42 | * @param master master ID subject | 44 | * @param master master ID subject |
43 | * @param time occurrence time | 45 | * @param time occurrence time |
44 | */ | 46 | */ |
45 | - protected MastershipEvent(Type type, DeviceId device, NodeId master, long time) { | 47 | + public MastershipEvent(Type type, DeviceId device, NodeId master, long time) { |
46 | super(type, device, time); | 48 | super(type, device, time); |
47 | this.master = master; | 49 | this.master = master; |
48 | } | 50 | } | ... | ... |
... | @@ -65,7 +65,10 @@ public class MastershipManager | ... | @@ -65,7 +65,10 @@ public class MastershipManager |
65 | checkNotNull(nodeId, NODE_ID_NULL); | 65 | checkNotNull(nodeId, NODE_ID_NULL); |
66 | checkNotNull(deviceId, DEVICE_ID_NULL); | 66 | checkNotNull(deviceId, DEVICE_ID_NULL); |
67 | checkNotNull(role, ROLE_NULL); | 67 | checkNotNull(role, ROLE_NULL); |
68 | - store.setRole(nodeId, deviceId, role); | 68 | + MastershipEvent event = store.setRole(nodeId, deviceId, role); |
69 | + if (event != null) { | ||
70 | + post(event); | ||
71 | + } | ||
69 | } | 72 | } |
70 | 73 | ||
71 | @Override | 74 | @Override | ... | ... |
... | @@ -6,6 +6,7 @@ import org.apache.felix.scr.annotations.Deactivate; | ... | @@ -6,6 +6,7 @@ import org.apache.felix.scr.annotations.Deactivate; |
6 | import org.apache.felix.scr.annotations.Reference; | 6 | import org.apache.felix.scr.annotations.Reference; |
7 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 7 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
8 | import org.apache.felix.scr.annotations.Service; | 8 | import org.apache.felix.scr.annotations.Service; |
9 | +import org.onlab.onos.cluster.MastershipService; | ||
9 | import org.onlab.onos.event.AbstractListenerRegistry; | 10 | import org.onlab.onos.event.AbstractListenerRegistry; |
10 | import org.onlab.onos.event.EventDeliveryService; | 11 | import org.onlab.onos.event.EventDeliveryService; |
11 | import org.onlab.onos.net.Device; | 12 | import org.onlab.onos.net.Device; |
... | @@ -29,6 +30,7 @@ import org.slf4j.Logger; | ... | @@ -29,6 +30,7 @@ import org.slf4j.Logger; |
29 | 30 | ||
30 | import java.util.List; | 31 | import java.util.List; |
31 | 32 | ||
33 | +import static org.onlab.onos.net.device.DeviceEvent.Type.*; | ||
32 | import static com.google.common.base.Preconditions.checkNotNull; | 34 | import static com.google.common.base.Preconditions.checkNotNull; |
33 | import static org.slf4j.LoggerFactory.getLogger; | 35 | import static org.slf4j.LoggerFactory.getLogger; |
34 | 36 | ||
... | @@ -58,6 +60,9 @@ public class DeviceManager | ... | @@ -58,6 +60,9 @@ public class DeviceManager |
58 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 60 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
59 | protected EventDeliveryService eventDispatcher; | 61 | protected EventDeliveryService eventDispatcher; |
60 | 62 | ||
63 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
64 | + protected MastershipService mastershipService; | ||
65 | + | ||
61 | @Activate | 66 | @Activate |
62 | public void activate() { | 67 | public void activate() { |
63 | eventDispatcher.addSink(DeviceEvent.class, listenerRegistry); | 68 | eventDispatcher.addSink(DeviceEvent.class, listenerRegistry); |
... | @@ -171,6 +176,10 @@ public class DeviceManager | ... | @@ -171,6 +176,10 @@ public class DeviceManager |
171 | // If there was a change of any kind, trigger role selection process. | 176 | // If there was a change of any kind, trigger role selection process. |
172 | if (event != null) { | 177 | if (event != null) { |
173 | log.info("Device {} connected", deviceId); | 178 | log.info("Device {} connected", deviceId); |
179 | + if (event.type().equals(DEVICE_ADDED)) { | ||
180 | + MastershipRole role = mastershipService.requestRoleFor(deviceId); | ||
181 | + store.setRole(deviceId, role); | ||
182 | + } | ||
174 | Device device = event.subject(); | 183 | Device device = event.subject(); |
175 | provider().roleChanged(device, store.getRole(device.id())); | 184 | provider().roleChanged(device, store.getRole(device.id())); |
176 | post(event); | 185 | post(event); | ... | ... |
... | @@ -3,6 +3,9 @@ package org.onlab.onos.net.device.impl; | ... | @@ -3,6 +3,9 @@ package org.onlab.onos.net.device.impl; |
3 | import org.junit.After; | 3 | import org.junit.After; |
4 | import org.junit.Before; | 4 | import org.junit.Before; |
5 | import org.junit.Test; | 5 | import org.junit.Test; |
6 | +import org.onlab.onos.cluster.MastershipListener; | ||
7 | +import org.onlab.onos.cluster.MastershipService; | ||
8 | +import org.onlab.onos.cluster.NodeId; | ||
6 | import org.onlab.onos.event.Event; | 9 | import org.onlab.onos.event.Event; |
7 | import org.onlab.onos.net.Device; | 10 | import org.onlab.onos.net.Device; |
8 | import org.onlab.onos.net.DeviceId; | 11 | import org.onlab.onos.net.DeviceId; |
... | @@ -25,9 +28,12 @@ import org.onlab.onos.net.provider.ProviderId; | ... | @@ -25,9 +28,12 @@ import org.onlab.onos.net.provider.ProviderId; |
25 | import org.onlab.onos.event.impl.TestEventDispatcher; | 28 | import org.onlab.onos.event.impl.TestEventDispatcher; |
26 | import org.onlab.onos.net.trivial.impl.SimpleDeviceStore; | 29 | import org.onlab.onos.net.trivial.impl.SimpleDeviceStore; |
27 | 30 | ||
31 | +import com.google.common.collect.Sets; | ||
32 | + | ||
28 | import java.util.ArrayList; | 33 | import java.util.ArrayList; |
29 | import java.util.Iterator; | 34 | import java.util.Iterator; |
30 | import java.util.List; | 35 | import java.util.List; |
36 | +import java.util.Set; | ||
31 | 37 | ||
32 | import static org.junit.Assert.*; | 38 | import static org.junit.Assert.*; |
33 | import static org.onlab.onos.net.Device.Type.SWITCH; | 39 | import static org.onlab.onos.net.Device.Type.SWITCH; |
... | @@ -69,6 +75,7 @@ public class DeviceManagerTest { | ... | @@ -69,6 +75,7 @@ public class DeviceManagerTest { |
69 | registry = mgr; | 75 | registry = mgr; |
70 | mgr.store = new SimpleDeviceStore(); | 76 | mgr.store = new SimpleDeviceStore(); |
71 | mgr.eventDispatcher = new TestEventDispatcher(); | 77 | mgr.eventDispatcher = new TestEventDispatcher(); |
78 | + mgr.mastershipService = new TestMastershipService(); | ||
72 | mgr.activate(); | 79 | mgr.activate(); |
73 | 80 | ||
74 | service.addListener(listener); | 81 | service.addListener(listener); |
... | @@ -252,4 +259,31 @@ public class DeviceManagerTest { | ... | @@ -252,4 +259,31 @@ public class DeviceManagerTest { |
252 | } | 259 | } |
253 | } | 260 | } |
254 | 261 | ||
262 | + private static class TestMastershipService implements MastershipService { | ||
263 | + | ||
264 | + @Override | ||
265 | + public NodeId getMasterFor(DeviceId deviceId) { | ||
266 | + return null; | ||
267 | + } | ||
268 | + | ||
269 | + @Override | ||
270 | + public Set<DeviceId> getDevicesOf(NodeId nodeId) { | ||
271 | + return Sets.newHashSet(DID1, DID2); | ||
272 | + } | ||
273 | + | ||
274 | + @Override | ||
275 | + public MastershipRole requestRoleFor(DeviceId deviceId) { | ||
276 | + return MastershipRole.MASTER; | ||
277 | + } | ||
278 | + | ||
279 | + @Override | ||
280 | + public void addListener(MastershipListener listener) { | ||
281 | + } | ||
282 | + | ||
283 | + @Override | ||
284 | + public void removeListener(MastershipListener listener) { | ||
285 | + } | ||
286 | + | ||
287 | + } | ||
288 | + | ||
255 | } | 289 | } | ... | ... |
1 | package org.onlab.onos.net.device.impl; | 1 | package org.onlab.onos.net.device.impl; |
2 | 2 | ||
3 | import com.google.common.collect.Iterables; | 3 | import com.google.common.collect.Iterables; |
4 | +import com.google.common.collect.Sets; | ||
4 | import com.hazelcast.config.Config; | 5 | import com.hazelcast.config.Config; |
5 | import com.hazelcast.core.Hazelcast; | 6 | import com.hazelcast.core.Hazelcast; |
6 | import com.hazelcast.core.HazelcastInstance; | 7 | import com.hazelcast.core.HazelcastInstance; |
8 | + | ||
7 | import org.junit.After; | 9 | import org.junit.After; |
8 | import org.junit.Before; | 10 | import org.junit.Before; |
9 | import org.junit.Test; | 11 | import org.junit.Test; |
12 | +import org.onlab.onos.cluster.MastershipListener; | ||
13 | +import org.onlab.onos.cluster.MastershipService; | ||
14 | +import org.onlab.onos.cluster.NodeId; | ||
10 | import org.onlab.onos.event.Event; | 15 | import org.onlab.onos.event.Event; |
11 | import org.onlab.onos.event.impl.TestEventDispatcher; | 16 | import org.onlab.onos.event.impl.TestEventDispatcher; |
12 | import org.onlab.onos.net.Device; | 17 | import org.onlab.onos.net.Device; |
... | @@ -34,6 +39,7 @@ import org.onlab.onos.store.impl.StoreManager; | ... | @@ -34,6 +39,7 @@ import org.onlab.onos.store.impl.StoreManager; |
34 | import java.util.ArrayList; | 39 | import java.util.ArrayList; |
35 | import java.util.Iterator; | 40 | import java.util.Iterator; |
36 | import java.util.List; | 41 | import java.util.List; |
42 | +import java.util.Set; | ||
37 | import java.util.UUID; | 43 | import java.util.UUID; |
38 | 44 | ||
39 | import static org.junit.Assert.*; | 45 | import static org.junit.Assert.*; |
... | @@ -98,6 +104,7 @@ public class DistributedDeviceManagerTest { | ... | @@ -98,6 +104,7 @@ public class DistributedDeviceManagerTest { |
98 | dstore.activate(); | 104 | dstore.activate(); |
99 | mgr.store = dstore; | 105 | mgr.store = dstore; |
100 | mgr.eventDispatcher = new TestEventDispatcher(); | 106 | mgr.eventDispatcher = new TestEventDispatcher(); |
107 | + mgr.mastershipService = new TestMastershipService(); | ||
101 | mgr.activate(); | 108 | mgr.activate(); |
102 | 109 | ||
103 | service.addListener(listener); | 110 | service.addListener(listener); |
... | @@ -302,4 +309,32 @@ public class DistributedDeviceManagerTest { | ... | @@ -302,4 +309,32 @@ public class DistributedDeviceManagerTest { |
302 | setupKryoPool(); | 309 | setupKryoPool(); |
303 | } | 310 | } |
304 | } | 311 | } |
312 | + | ||
313 | + private static class TestMastershipService implements MastershipService { | ||
314 | + | ||
315 | + @Override | ||
316 | + public NodeId getMasterFor(DeviceId deviceId) { | ||
317 | + return null; | ||
318 | + } | ||
319 | + | ||
320 | + @Override | ||
321 | + public Set<DeviceId> getDevicesOf(NodeId nodeId) { | ||
322 | + return Sets.newHashSet(DID1, DID2); | ||
323 | + } | ||
324 | + | ||
325 | + @Override | ||
326 | + public MastershipRole requestRoleFor(DeviceId deviceId) { | ||
327 | + return MastershipRole.MASTER; | ||
328 | + } | ||
329 | + | ||
330 | + @Override | ||
331 | + public void addListener(MastershipListener listener) { | ||
332 | + } | ||
333 | + | ||
334 | + @Override | ||
335 | + public void removeListener(MastershipListener listener) { | ||
336 | + } | ||
337 | + | ||
338 | + } | ||
339 | + | ||
305 | } | 340 | } | ... | ... |
... | @@ -98,7 +98,7 @@ public class SimpleDeviceStore implements DeviceStore { | ... | @@ -98,7 +98,7 @@ public class SimpleDeviceStore implements DeviceStore { |
98 | availableDevices.add(deviceId); | 98 | availableDevices.add(deviceId); |
99 | 99 | ||
100 | // For now claim the device as a master automatically. | 100 | // For now claim the device as a master automatically. |
101 | - roles.put(deviceId, MastershipRole.MASTER); | 101 | + // roles.put(deviceId, MastershipRole.MASTER); |
102 | } | 102 | } |
103 | return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device, null); | 103 | return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device, null); |
104 | } | 104 | } | ... | ... |
1 | +package org.onlab.onos.net.trivial.impl; | ||
2 | + | ||
3 | +import static org.slf4j.LoggerFactory.getLogger; | ||
4 | + | ||
5 | +import java.util.Collections; | ||
6 | +import java.util.Set; | ||
7 | +import java.util.concurrent.ConcurrentHashMap; | ||
8 | +import java.util.concurrent.ConcurrentMap; | ||
9 | + | ||
10 | +import org.apache.felix.scr.annotations.Activate; | ||
11 | +import org.apache.felix.scr.annotations.Component; | ||
12 | +import org.apache.felix.scr.annotations.Deactivate; | ||
13 | +import org.apache.felix.scr.annotations.Service; | ||
14 | +import org.onlab.onos.cluster.ControllerNode; | ||
15 | +import org.onlab.onos.cluster.DefaultControllerNode; | ||
16 | +import org.onlab.onos.cluster.MastershipEvent; | ||
17 | +import org.onlab.onos.cluster.MastershipStore; | ||
18 | +import org.onlab.onos.cluster.NodeId; | ||
19 | +import org.onlab.onos.net.DeviceId; | ||
20 | +import org.onlab.onos.net.MastershipRole; | ||
21 | +import org.onlab.packet.IpPrefix; | ||
22 | +import org.slf4j.Logger; | ||
23 | + | ||
24 | +import static org.onlab.onos.cluster.MastershipEvent.Type.*; | ||
25 | + | ||
26 | +/** | ||
27 | + * Manages inventory of controller mastership over devices using | ||
28 | + * trivial in-memory structures implementation. | ||
29 | + */ | ||
30 | +@Component(immediate = true) | ||
31 | +@Service | ||
32 | +public class SimpleMastershipStore implements MastershipStore { | ||
33 | + | ||
34 | + public static final IpPrefix LOCALHOST = IpPrefix.valueOf("127.0.0.1"); | ||
35 | + | ||
36 | + private final Logger log = getLogger(getClass()); | ||
37 | + | ||
38 | + private ControllerNode instance; | ||
39 | + | ||
40 | + protected final ConcurrentMap<DeviceId, MastershipRole> roleMap = | ||
41 | + new ConcurrentHashMap<DeviceId, MastershipRole>(); | ||
42 | + | ||
43 | + @Activate | ||
44 | + public void activate() { | ||
45 | + instance = new DefaultControllerNode(new NodeId("local"), LOCALHOST); | ||
46 | + log.info("Started"); | ||
47 | + } | ||
48 | + | ||
49 | + @Deactivate | ||
50 | + public void deactivate() { | ||
51 | + log.info("Stopped"); | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public MastershipEvent setRole(NodeId nodeId, DeviceId deviceId, | ||
56 | + MastershipRole role) { | ||
57 | + if (roleMap.get(deviceId) == null) { | ||
58 | + return null; | ||
59 | + } | ||
60 | + roleMap.put(deviceId, role); | ||
61 | + return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId); | ||
62 | + } | ||
63 | + | ||
64 | + @Override | ||
65 | + public MastershipEvent addOrUpdateDevice(NodeId instance, | ||
66 | + DeviceId deviceId, MastershipRole role) { | ||
67 | + //TODO refine when we do listeners | ||
68 | + roleMap.put(deviceId, role); | ||
69 | + return null; | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + public NodeId getMaster(DeviceId deviceId) { | ||
74 | + return instance.id(); | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public Set<DeviceId> getDevices(NodeId nodeId) { | ||
79 | + return Collections.unmodifiableSet(roleMap.keySet()); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) { | ||
84 | + MastershipRole role = roleMap.get(deviceId); | ||
85 | + if (role == null) { | ||
86 | + //say MASTER. If clustered, we'd figure out if anyone's got dibs here. | ||
87 | + role = MastershipRole.MASTER; | ||
88 | + roleMap.put(deviceId, role); | ||
89 | + } | ||
90 | + return role; | ||
91 | + } | ||
92 | + | ||
93 | +} |
-
Please register or login to post a comment