Yuta HIGUCHI

Stop sharing Roles in DistributedDeviceStore

Change-Id: Icd0302871c1d6f48379b93eb61f83bfa6df4ce20
...@@ -4,13 +4,15 @@ import com.google.common.collect.Iterables; ...@@ -4,13 +4,15 @@ import com.google.common.collect.Iterables;
4 import com.google.common.collect.Sets; 4 import com.google.common.collect.Sets;
5 import com.hazelcast.config.Config; 5 import com.hazelcast.config.Config;
6 import com.hazelcast.core.Hazelcast; 6 import com.hazelcast.core.Hazelcast;
7 -import com.hazelcast.core.HazelcastInstance; 7 +
8 import org.junit.After; 8 import org.junit.After;
9 import org.junit.Before; 9 import org.junit.Before;
10 import org.junit.Test; 10 import org.junit.Test;
11 +import org.onlab.onos.cluster.DefaultControllerNode;
11 import org.onlab.onos.cluster.MastershipServiceAdapter; 12 import org.onlab.onos.cluster.MastershipServiceAdapter;
12 import org.onlab.onos.cluster.NodeId; 13 import org.onlab.onos.cluster.NodeId;
13 import org.onlab.onos.event.Event; 14 import org.onlab.onos.event.Event;
15 +import org.onlab.onos.event.EventDeliveryService;
14 import org.onlab.onos.event.impl.TestEventDispatcher; 16 import org.onlab.onos.event.impl.TestEventDispatcher;
15 import org.onlab.onos.net.Device; 17 import org.onlab.onos.net.Device;
16 import org.onlab.onos.net.DeviceId; 18 import org.onlab.onos.net.DeviceId;
...@@ -30,15 +32,20 @@ import org.onlab.onos.net.device.DeviceService; ...@@ -30,15 +32,20 @@ import org.onlab.onos.net.device.DeviceService;
30 import org.onlab.onos.net.device.PortDescription; 32 import org.onlab.onos.net.device.PortDescription;
31 import org.onlab.onos.net.provider.AbstractProvider; 33 import org.onlab.onos.net.provider.AbstractProvider;
32 import org.onlab.onos.net.provider.ProviderId; 34 import org.onlab.onos.net.provider.ProviderId;
33 -import org.onlab.onos.store.common.StoreService;
34 import org.onlab.onos.store.device.impl.DistributedDeviceStore; 35 import org.onlab.onos.store.device.impl.DistributedDeviceStore;
35 import org.onlab.onos.store.impl.StoreManager; 36 import org.onlab.onos.store.impl.StoreManager;
36 import org.onlab.onos.store.impl.TestStoreManager; 37 import org.onlab.onos.store.impl.TestStoreManager;
38 +import org.onlab.packet.IpPrefix;
37 39
38 import java.util.ArrayList; 40 import java.util.ArrayList;
41 +import java.util.HashSet;
39 import java.util.Iterator; 42 import java.util.Iterator;
40 import java.util.List; 43 import java.util.List;
44 +import java.util.Map.Entry;
41 import java.util.Set; 45 import java.util.Set;
46 +import java.util.concurrent.ConcurrentHashMap;
47 +import java.util.concurrent.ConcurrentMap;
48 +
42 import static org.junit.Assert.*; 49 import static org.junit.Assert.*;
43 import static org.onlab.onos.net.Device.Type.SWITCH; 50 import static org.onlab.onos.net.Device.Type.SWITCH;
44 import static org.onlab.onos.net.DeviceId.deviceId; 51 import static org.onlab.onos.net.DeviceId.deviceId;
...@@ -65,6 +72,11 @@ public class DistributedDeviceManagerTest { ...@@ -65,6 +72,11 @@ public class DistributedDeviceManagerTest {
65 private static final PortNumber P2 = PortNumber.portNumber(2); 72 private static final PortNumber P2 = PortNumber.portNumber(2);
66 private static final PortNumber P3 = PortNumber.portNumber(3); 73 private static final PortNumber P3 = PortNumber.portNumber(3);
67 74
75 + private static final DefaultControllerNode SELF
76 + = new DefaultControllerNode(new NodeId("foobar"),
77 + IpPrefix.valueOf("127.0.0.1"));
78 +
79 +
68 private DeviceManager mgr; 80 private DeviceManager mgr;
69 81
70 protected StoreManager storeManager; 82 protected StoreManager storeManager;
...@@ -75,6 +87,8 @@ public class DistributedDeviceManagerTest { ...@@ -75,6 +87,8 @@ public class DistributedDeviceManagerTest {
75 protected TestProvider provider; 87 protected TestProvider provider;
76 protected TestListener listener = new TestListener(); 88 protected TestListener listener = new TestListener();
77 private DistributedDeviceStore dstore; 89 private DistributedDeviceStore dstore;
90 + private TestMastershipManager masterManager;
91 + private EventDeliveryService eventService;
78 92
79 @Before 93 @Before
80 public void setUp() { 94 public void setUp() {
...@@ -85,14 +99,18 @@ public class DistributedDeviceManagerTest { ...@@ -85,14 +99,18 @@ public class DistributedDeviceManagerTest {
85 // TODO should find a way to clean Hazelcast instance without shutdown. 99 // TODO should find a way to clean Hazelcast instance without shutdown.
86 Config config = TestStoreManager.getTestConfig(); 100 Config config = TestStoreManager.getTestConfig();
87 101
102 + masterManager = new TestMastershipManager();
103 +
88 storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config)); 104 storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config));
89 storeManager.activate(); 105 storeManager.activate();
90 106
91 - dstore = new TestDistributedDeviceStore(storeManager); 107 + dstore = new TestDistributedDeviceStore();
92 dstore.activate(); 108 dstore.activate();
109 +
93 mgr.store = dstore; 110 mgr.store = dstore;
94 - mgr.eventDispatcher = new TestEventDispatcher(); 111 + eventService = new TestEventDispatcher();
95 - mgr.mastershipService = new TestMastershipService(); 112 + mgr.eventDispatcher = eventService;
113 + mgr.mastershipService = masterManager;
96 mgr.activate(); 114 mgr.activate();
97 115
98 service.addListener(listener); 116 service.addListener(listener);
...@@ -272,13 +290,21 @@ public class DistributedDeviceManagerTest { ...@@ -272,13 +290,21 @@ public class DistributedDeviceManagerTest {
272 } 290 }
273 291
274 private class TestDistributedDeviceStore extends DistributedDeviceStore { 292 private class TestDistributedDeviceStore extends DistributedDeviceStore {
275 - public TestDistributedDeviceStore(StoreService storeService) { 293 +
276 - this.storeService = storeService; 294 + public TestDistributedDeviceStore() {
295 + this.storeService = storeManager;
277 } 296 }
278 } 297 }
279 298
280 - private static class TestMastershipService extends MastershipServiceAdapter { 299 + private static class TestMastershipManager extends MastershipServiceAdapter {
281 300
301 + private ConcurrentMap<DeviceId, NodeId> masters = new ConcurrentHashMap<>();
302 +
303 + public TestMastershipManager() {
304 + // SELF master of all initially
305 + masters.put(DID1, SELF.id());
306 + masters.put(DID1, SELF.id());
307 + }
282 @Override 308 @Override
283 public MastershipRole getLocalRole(DeviceId deviceId) { 309 public MastershipRole getLocalRole(DeviceId deviceId) {
284 return MastershipRole.MASTER; 310 return MastershipRole.MASTER;
...@@ -286,12 +312,27 @@ public class DistributedDeviceManagerTest { ...@@ -286,12 +312,27 @@ public class DistributedDeviceManagerTest {
286 312
287 @Override 313 @Override
288 public Set<DeviceId> getDevicesOf(NodeId nodeId) { 314 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
289 - return Sets.newHashSet(DID1, DID2); 315 + HashSet<DeviceId> set = Sets.newHashSet();
316 + for (Entry<DeviceId, NodeId> e : masters.entrySet()) {
317 + if (e.getValue().equals(nodeId)) {
318 + set.add(e.getKey());
319 + }
320 + }
321 + return set;
290 } 322 }
291 323
292 @Override 324 @Override
293 public MastershipRole requestRoleFor(DeviceId deviceId) { 325 public MastershipRole requestRoleFor(DeviceId deviceId) {
294 - return MastershipRole.MASTER; 326 + if (SELF.id().equals(masters.get(deviceId))) {
327 + return MastershipRole.MASTER;
328 + } else {
329 + return MastershipRole.STANDBY;
330 + }
331 + }
332 +
333 + @Override
334 + public void relinquishMastership(DeviceId deviceId) {
335 + masters.remove(deviceId, SELF.id());
295 } 336 }
296 } 337 }
297 } 338 }
......
...@@ -7,6 +7,7 @@ import com.google.common.collect.ImmutableSet; ...@@ -7,6 +7,7 @@ import com.google.common.collect.ImmutableSet;
7 import com.google.common.collect.ImmutableSet.Builder; 7 import com.google.common.collect.ImmutableSet.Builder;
8 import com.hazelcast.core.IMap; 8 import com.hazelcast.core.IMap;
9 import com.hazelcast.core.ISet; 9 import com.hazelcast.core.ISet;
10 +
10 import org.apache.felix.scr.annotations.Activate; 11 import org.apache.felix.scr.annotations.Activate;
11 import org.apache.felix.scr.annotations.Component; 12 import org.apache.felix.scr.annotations.Component;
12 import org.apache.felix.scr.annotations.Deactivate; 13 import org.apache.felix.scr.annotations.Deactivate;
...@@ -15,7 +16,6 @@ import org.onlab.onos.net.DefaultDevice; ...@@ -15,7 +16,6 @@ import org.onlab.onos.net.DefaultDevice;
15 import org.onlab.onos.net.DefaultPort; 16 import org.onlab.onos.net.DefaultPort;
16 import org.onlab.onos.net.Device; 17 import org.onlab.onos.net.Device;
17 import org.onlab.onos.net.DeviceId; 18 import org.onlab.onos.net.DeviceId;
18 -import org.onlab.onos.net.MastershipRole;
19 import org.onlab.onos.net.Port; 19 import org.onlab.onos.net.Port;
20 import org.onlab.onos.net.PortNumber; 20 import org.onlab.onos.net.PortNumber;
21 import org.onlab.onos.net.device.DeviceDescription; 21 import org.onlab.onos.net.device.DeviceDescription;
...@@ -38,7 +38,6 @@ import java.util.List; ...@@ -38,7 +38,6 @@ import java.util.List;
38 import java.util.Map; 38 import java.util.Map;
39 import java.util.Objects; 39 import java.util.Objects;
40 import java.util.Set; 40 import java.util.Set;
41 -
42 import static com.google.common.base.Preconditions.checkArgument; 41 import static com.google.common.base.Preconditions.checkArgument;
43 import static com.google.common.cache.CacheBuilder.newBuilder; 42 import static com.google.common.cache.CacheBuilder.newBuilder;
44 import static org.onlab.onos.net.device.DeviceEvent.Type.*; 43 import static org.onlab.onos.net.device.DeviceEvent.Type.*;
...@@ -61,10 +60,6 @@ public class DistributedDeviceStore ...@@ -61,10 +60,6 @@ public class DistributedDeviceStore
61 private IMap<byte[], byte[]> rawDevices; 60 private IMap<byte[], byte[]> rawDevices;
62 private LoadingCache<DeviceId, Optional<DefaultDevice>> devices; 61 private LoadingCache<DeviceId, Optional<DefaultDevice>> devices;
63 62
64 - // private IMap<DeviceId, MastershipRole> roles;
65 - private IMap<byte[], byte[]> rawRoles;
66 - private LoadingCache<DeviceId, Optional<MastershipRole>> roles;
67 -
68 // private ISet<DeviceId> availableDevices; 63 // private ISet<DeviceId> availableDevices;
69 private ISet<byte[]> availableDevices; 64 private ISet<byte[]> availableDevices;
70 65
...@@ -89,13 +84,6 @@ public class DistributedDeviceStore ...@@ -89,13 +84,6 @@ public class DistributedDeviceStore
89 // refresh/populate cache based on notification from other instance 84 // refresh/populate cache based on notification from other instance
90 rawDevices.addEntryListener(new RemoteEventHandler<>(devices), includeValue); 85 rawDevices.addEntryListener(new RemoteEventHandler<>(devices), includeValue);
91 86
92 - rawRoles = theInstance.getMap("roles");
93 - final OptionalCacheLoader<DeviceId, MastershipRole> rolesLoader
94 - = new OptionalCacheLoader<>(storeService, rawRoles);
95 - roles = new AbsentInvalidatingLoadingCache<>(newBuilder().build(rolesLoader));
96 - // refresh/populate cache based on notification from other instance
97 - rawRoles.addEntryListener(new RemoteEventHandler<>(roles), includeValue);
98 -
99 // TODO cache availableDevices 87 // TODO cache availableDevices
100 availableDevices = theInstance.getSet("availableDevices"); 88 availableDevices = theInstance.getSet("availableDevices");
101 89
...@@ -173,10 +161,6 @@ public class DistributedDeviceStore ...@@ -173,10 +161,6 @@ public class DistributedDeviceStore
173 devices.put(deviceId, Optional.of(device)); 161 devices.put(deviceId, Optional.of(device));
174 162
175 availableDevices.add(deviceIdBytes); 163 availableDevices.add(deviceIdBytes);
176 -
177 - // For now claim the device as a master automatically.
178 - //rawRoles.put(deviceIdBytes, serialize(MastershipRole.MASTER));
179 - //roles.put(deviceId, Optional.of(MastershipRole.MASTER));
180 } 164 }
181 return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device, null); 165 return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device, null);
182 } 166 }
...@@ -350,8 +334,6 @@ public class DistributedDeviceStore ...@@ -350,8 +334,6 @@ public class DistributedDeviceStore
350 public DeviceEvent removeDevice(DeviceId deviceId) { 334 public DeviceEvent removeDevice(DeviceId deviceId) {
351 synchronized (this) { 335 synchronized (this) {
352 byte[] deviceIdBytes = serialize(deviceId); 336 byte[] deviceIdBytes = serialize(deviceId);
353 - rawRoles.remove(deviceIdBytes);
354 - roles.invalidate(deviceId);
355 337
356 // TODO conditional remove? 338 // TODO conditional remove?
357 Device device = deserialize(rawDevices.remove(deviceIdBytes)); 339 Device device = deserialize(rawDevices.remove(deviceIdBytes));
......