tom

Merge remote-tracking branch 'origin/master'

...@@ -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 +}