Jonathan Hart

Remove hz/net files again

1 -package org.onlab.onos.store.device.impl;
2 -
3 -import static com.google.common.base.Predicates.notNull;
4 -
5 -import com.google.common.base.Optional;
6 -import com.google.common.cache.LoadingCache;
7 -import com.google.common.collect.FluentIterable;
8 -import com.google.common.collect.ImmutableList;
9 -import com.google.common.collect.ImmutableSet;
10 -import com.google.common.collect.ImmutableSet.Builder;
11 -import com.hazelcast.core.IMap;
12 -import com.hazelcast.core.ISet;
13 -
14 -import org.apache.felix.scr.annotations.Activate;
15 -import org.apache.felix.scr.annotations.Component;
16 -import org.apache.felix.scr.annotations.Deactivate;
17 -import org.apache.felix.scr.annotations.Service;
18 -import org.onlab.onos.net.DefaultDevice;
19 -import org.onlab.onos.net.DefaultPort;
20 -import org.onlab.onos.net.Device;
21 -import org.onlab.onos.net.DeviceId;
22 -import org.onlab.onos.net.Port;
23 -import org.onlab.onos.net.PortNumber;
24 -import org.onlab.onos.net.device.DeviceDescription;
25 -import org.onlab.onos.net.device.DeviceEvent;
26 -import org.onlab.onos.net.device.DeviceStore;
27 -import org.onlab.onos.net.device.DeviceStoreDelegate;
28 -import org.onlab.onos.net.device.PortDescription;
29 -import org.onlab.onos.net.provider.ProviderId;
30 -import org.onlab.onos.store.common.AbsentInvalidatingLoadingCache;
31 -import org.onlab.onos.store.common.AbstractHazelcastStore;
32 -import org.onlab.onos.store.common.OptionalCacheLoader;
33 -import org.slf4j.Logger;
34 -
35 -import java.util.ArrayList;
36 -import java.util.Collections;
37 -import java.util.HashMap;
38 -import java.util.HashSet;
39 -import java.util.Iterator;
40 -import java.util.List;
41 -import java.util.Map;
42 -import java.util.Objects;
43 -import java.util.Set;
44 -
45 -import static com.google.common.base.Preconditions.checkArgument;
46 -import static com.google.common.cache.CacheBuilder.newBuilder;
47 -import static org.onlab.onos.net.device.DeviceEvent.Type.*;
48 -import static org.slf4j.LoggerFactory.getLogger;
49 -
50 -//TODO: Add support for multiple provider and annotations
51 -/**
52 - * Manages inventory of infrastructure devices using Hazelcast-backed map.
53 - */
54 -@Component(immediate = true)
55 -@Service
56 -public class DistributedDeviceStore
57 - extends AbstractHazelcastStore<DeviceEvent, DeviceStoreDelegate>
58 - implements DeviceStore {
59 -
60 - private final Logger log = getLogger(getClass());
61 -
62 - public static final String DEVICE_NOT_FOUND = "Device with ID %s not found";
63 -
64 - // private IMap<DeviceId, DefaultDevice> cache;
65 - private IMap<byte[], byte[]> rawDevices;
66 - private LoadingCache<DeviceId, Optional<DefaultDevice>> devices;
67 -
68 - // private ISet<DeviceId> availableDevices;
69 - private ISet<byte[]> availableDevices;
70 -
71 - // TODO DevicePorts is very inefficient consider restructuring.
72 - // private IMap<DeviceId, Map<PortNumber, Port>> devicePorts;
73 - private IMap<byte[], byte[]> rawDevicePorts;
74 - private LoadingCache<DeviceId, Optional<Map<PortNumber, Port>>> devicePorts;
75 -
76 - private String devicesListener;
77 -
78 - private String portsListener;
79 -
80 - @Override
81 - @Activate
82 - public void activate() {
83 - super.activate();
84 -
85 - // IMap event handler needs value
86 - final boolean includeValue = true;
87 -
88 - // TODO decide on Map name scheme to avoid collision
89 - rawDevices = theInstance.getMap("devices");
90 - final OptionalCacheLoader<DeviceId, DefaultDevice> deviceLoader
91 - = new OptionalCacheLoader<>(serializer, rawDevices);
92 - devices = new AbsentInvalidatingLoadingCache<>(newBuilder().build(deviceLoader));
93 - // refresh/populate cache based on notification from other instance
94 - devicesListener = rawDevices.addEntryListener(new RemoteDeviceEventHandler(devices), includeValue);
95 -
96 - // TODO cache availableDevices
97 - availableDevices = theInstance.getSet("availableDevices");
98 -
99 - rawDevicePorts = theInstance.getMap("devicePorts");
100 - final OptionalCacheLoader<DeviceId, Map<PortNumber, Port>> devicePortLoader
101 - = new OptionalCacheLoader<>(serializer, rawDevicePorts);
102 - devicePorts = new AbsentInvalidatingLoadingCache<>(newBuilder().build(devicePortLoader));
103 - // refresh/populate cache based on notification from other instance
104 - portsListener = rawDevicePorts.addEntryListener(new RemotePortEventHandler(devicePorts), includeValue);
105 -
106 - loadDeviceCache();
107 - loadDevicePortsCache();
108 -
109 - log.info("Started");
110 - }
111 -
112 - @Deactivate
113 - public void deactivate() {
114 - rawDevicePorts.removeEntryListener(portsListener);
115 - rawDevices.removeEntryListener(devicesListener);
116 - log.info("Stopped");
117 - }
118 -
119 - @Override
120 - public int getDeviceCount() {
121 - return devices.asMap().size();
122 - }
123 -
124 - @Override
125 - public Iterable<Device> getDevices() {
126 - // TODO builder v.s. copyOf. Guava semms to be using copyOf?
127 - Builder<Device> builder = ImmutableSet.builder();
128 - for (Optional<DefaultDevice> e : devices.asMap().values()) {
129 - if (e.isPresent()) {
130 - builder.add(e.get());
131 - }
132 - }
133 - return builder.build();
134 - }
135 -
136 - private void loadDeviceCache() {
137 - for (byte[] keyBytes : rawDevices.keySet()) {
138 - final DeviceId id = deserialize(keyBytes);
139 - devices.refresh(id);
140 - }
141 - }
142 -
143 - private void loadDevicePortsCache() {
144 - for (byte[] keyBytes : rawDevicePorts.keySet()) {
145 - final DeviceId id = deserialize(keyBytes);
146 - devicePorts.refresh(id);
147 - }
148 - }
149 -
150 - @Override
151 - public Device getDevice(DeviceId deviceId) {
152 - // TODO revisit if ignoring exception is safe.
153 - return devices.getUnchecked(deviceId).orNull();
154 - }
155 -
156 - @Override
157 - public DeviceEvent createOrUpdateDevice(ProviderId providerId, DeviceId deviceId,
158 - DeviceDescription deviceDescription) {
159 - DefaultDevice device = devices.getUnchecked(deviceId).orNull();
160 - if (device == null) {
161 - return createDevice(providerId, deviceId, deviceDescription);
162 - }
163 - return updateDevice(providerId, device, deviceDescription);
164 - }
165 -
166 - // Creates the device and returns the appropriate event if necessary.
167 - private DeviceEvent createDevice(ProviderId providerId, DeviceId deviceId,
168 - DeviceDescription desc) {
169 - DefaultDevice device = new DefaultDevice(providerId, deviceId, desc.type(),
170 - desc.manufacturer(),
171 - desc.hwVersion(), desc.swVersion(),
172 - desc.serialNumber(), desc.chassisId());
173 -
174 - synchronized (this) {
175 - final byte[] deviceIdBytes = serialize(deviceId);
176 - rawDevices.put(deviceIdBytes, serialize(device));
177 - devices.put(deviceId, Optional.of(device));
178 -
179 - availableDevices.add(deviceIdBytes);
180 - }
181 - return new DeviceEvent(DEVICE_ADDED, device, null);
182 - }
183 -
184 - // Updates the device and returns the appropriate event if necessary.
185 - private DeviceEvent updateDevice(ProviderId providerId, DefaultDevice device,
186 - DeviceDescription desc) {
187 - // We allow only certain attributes to trigger update
188 - if (!Objects.equals(device.hwVersion(), desc.hwVersion()) ||
189 - !Objects.equals(device.swVersion(), desc.swVersion())) {
190 -
191 - DefaultDevice updated = new DefaultDevice(providerId, device.id(),
192 - desc.type(),
193 - desc.manufacturer(),
194 - desc.hwVersion(),
195 - desc.swVersion(),
196 - desc.serialNumber(),
197 - desc.chassisId());
198 - synchronized (this) {
199 - final byte[] deviceIdBytes = serialize(device.id());
200 - rawDevices.put(deviceIdBytes, serialize(updated));
201 - devices.put(device.id(), Optional.of(updated));
202 - availableDevices.add(serialize(device.id()));
203 - }
204 - return new DeviceEvent(DeviceEvent.Type.DEVICE_UPDATED, updated, null);
205 - }
206 -
207 - // Otherwise merely attempt to change availability
208 - synchronized (this) {
209 - boolean added = availableDevices.add(serialize(device.id()));
210 - return !added ? null :
211 - new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device, null);
212 - }
213 - }
214 -
215 - @Override
216 - public DeviceEvent markOffline(DeviceId deviceId) {
217 - synchronized (this) {
218 - Device device = devices.getUnchecked(deviceId).orNull();
219 - boolean removed = device != null && availableDevices.remove(serialize(deviceId));
220 - return !removed ? null :
221 - new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device, null);
222 - }
223 - }
224 -
225 - @Override
226 - public List<DeviceEvent> updatePorts(ProviderId providerId, DeviceId deviceId,
227 - List<PortDescription> portDescriptions) {
228 - List<DeviceEvent> events = new ArrayList<>();
229 - synchronized (this) {
230 - Device device = devices.getUnchecked(deviceId).orNull();
231 - checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
232 - Map<PortNumber, Port> ports = getPortMap(deviceId);
233 -
234 - // Add new ports
235 - Set<PortNumber> processed = new HashSet<>();
236 - for (PortDescription portDescription : portDescriptions) {
237 - Port port = ports.get(portDescription.portNumber());
238 - events.add(port == null ?
239 - createPort(device, portDescription, ports) :
240 - updatePort(device, port, portDescription, ports));
241 - processed.add(portDescription.portNumber());
242 - }
243 -
244 - updatePortMap(deviceId, ports);
245 -
246 - events.addAll(pruneOldPorts(device, ports, processed));
247 - }
248 - return FluentIterable.from(events).filter(notNull()).toList();
249 - }
250 -
251 - // Creates a new port based on the port description adds it to the map and
252 - // Returns corresponding event.
253 - //@GuardedBy("this")
254 - private DeviceEvent createPort(Device device, PortDescription portDescription,
255 - Map<PortNumber, Port> ports) {
256 - DefaultPort port = new DefaultPort(device, portDescription.portNumber(),
257 - portDescription.isEnabled());
258 - ports.put(port.number(), port);
259 - updatePortMap(device.id(), ports);
260 - return new DeviceEvent(PORT_ADDED, device, port);
261 - }
262 -
263 - // Checks if the specified port requires update and if so, it replaces the
264 - // existing entry in the map and returns corresponding event.
265 - //@GuardedBy("this")
266 - private DeviceEvent updatePort(Device device, Port port,
267 - PortDescription portDescription,
268 - Map<PortNumber, Port> ports) {
269 - if (port.isEnabled() != portDescription.isEnabled()) {
270 - DefaultPort updatedPort =
271 - new DefaultPort(device, portDescription.portNumber(),
272 - portDescription.isEnabled());
273 - ports.put(port.number(), updatedPort);
274 - updatePortMap(device.id(), ports);
275 - return new DeviceEvent(PORT_UPDATED, device, updatedPort);
276 - }
277 - return null;
278 - }
279 -
280 - // Prunes the specified list of ports based on which ports are in the
281 - // processed list and returns list of corresponding events.
282 - //@GuardedBy("this")
283 - private List<DeviceEvent> pruneOldPorts(Device device,
284 - Map<PortNumber, Port> ports,
285 - Set<PortNumber> processed) {
286 - List<DeviceEvent> events = new ArrayList<>();
287 - Iterator<PortNumber> iterator = ports.keySet().iterator();
288 - while (iterator.hasNext()) {
289 - PortNumber portNumber = iterator.next();
290 - if (!processed.contains(portNumber)) {
291 - events.add(new DeviceEvent(PORT_REMOVED, device,
292 - ports.get(portNumber)));
293 - iterator.remove();
294 - }
295 - }
296 - if (!events.isEmpty()) {
297 - updatePortMap(device.id(), ports);
298 - }
299 - return events;
300 - }
301 -
302 - // Gets the map of ports for the specified device; if one does not already
303 - // exist, it creates and registers a new one.
304 - // WARN: returned value is a copy, changes made to the Map
305 - // needs to be written back using updatePortMap
306 - //@GuardedBy("this")
307 - private Map<PortNumber, Port> getPortMap(DeviceId deviceId) {
308 - Map<PortNumber, Port> ports = devicePorts.getUnchecked(deviceId).orNull();
309 - if (ports == null) {
310 - ports = new HashMap<>();
311 - // this probably is waste of time in most cases.
312 - updatePortMap(deviceId, ports);
313 - }
314 - return ports;
315 - }
316 -
317 - //@GuardedBy("this")
318 - private void updatePortMap(DeviceId deviceId, Map<PortNumber, Port> ports) {
319 - rawDevicePorts.put(serialize(deviceId), serialize(ports));
320 - devicePorts.put(deviceId, Optional.of(ports));
321 - }
322 -
323 - @Override
324 - public DeviceEvent updatePortStatus(ProviderId providerId, DeviceId deviceId,
325 - PortDescription portDescription) {
326 - synchronized (this) {
327 - Device device = devices.getUnchecked(deviceId).orNull();
328 - checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
329 - Map<PortNumber, Port> ports = getPortMap(deviceId);
330 - Port port = ports.get(portDescription.portNumber());
331 - return updatePort(device, port, portDescription, ports);
332 - }
333 - }
334 -
335 - @Override
336 - public List<Port> getPorts(DeviceId deviceId) {
337 - Map<PortNumber, Port> ports = devicePorts.getUnchecked(deviceId).orNull();
338 - return ports == null ? Collections.<Port>emptyList() : ImmutableList.copyOf(ports.values());
339 - }
340 -
341 - @Override
342 - public Port getPort(DeviceId deviceId, PortNumber portNumber) {
343 - Map<PortNumber, Port> ports = devicePorts.getUnchecked(deviceId).orNull();
344 - return ports == null ? null : ports.get(portNumber);
345 - }
346 -
347 - @Override
348 - public boolean isAvailable(DeviceId deviceId) {
349 - return availableDevices.contains(serialize(deviceId));
350 - }
351 -
352 - @Override
353 - public DeviceEvent removeDevice(DeviceId deviceId) {
354 - synchronized (this) {
355 - byte[] deviceIdBytes = serialize(deviceId);
356 -
357 - // TODO conditional remove?
358 - Device device = deserialize(rawDevices.remove(deviceIdBytes));
359 - devices.invalidate(deviceId);
360 - return device == null ? null :
361 - new DeviceEvent(DEVICE_REMOVED, device, null);
362 - }
363 - }
364 -
365 - private class RemoteDeviceEventHandler extends RemoteCacheEventHandler<DeviceId, DefaultDevice> {
366 - public RemoteDeviceEventHandler(LoadingCache<DeviceId, Optional<DefaultDevice>> cache) {
367 - super(cache);
368 - }
369 -
370 - @Override
371 - protected void onAdd(DeviceId deviceId, DefaultDevice device) {
372 - notifyDelegate(new DeviceEvent(DEVICE_ADDED, device));
373 - }
374 -
375 - @Override
376 - protected void onRemove(DeviceId deviceId, DefaultDevice device) {
377 - notifyDelegate(new DeviceEvent(DEVICE_REMOVED, device));
378 - }
379 -
380 - @Override
381 - protected void onUpdate(DeviceId deviceId, DefaultDevice oldDevice, DefaultDevice device) {
382 - notifyDelegate(new DeviceEvent(DEVICE_UPDATED, device));
383 - }
384 - }
385 -
386 - private class RemotePortEventHandler extends RemoteCacheEventHandler<DeviceId, Map<PortNumber, Port>> {
387 - public RemotePortEventHandler(LoadingCache<DeviceId, Optional<Map<PortNumber, Port>>> cache) {
388 - super(cache);
389 - }
390 -
391 - @Override
392 - protected void onAdd(DeviceId deviceId, Map<PortNumber, Port> ports) {
393 -// notifyDelegate(new DeviceEvent(PORT_ADDED, getDevice(deviceId)));
394 - }
395 -
396 - @Override
397 - protected void onRemove(DeviceId deviceId, Map<PortNumber, Port> ports) {
398 -// notifyDelegate(new DeviceEvent(PORT_REMOVED, getDevice(deviceId)));
399 - }
400 -
401 - @Override
402 - protected void onUpdate(DeviceId deviceId, Map<PortNumber, Port> oldPorts, Map<PortNumber, Port> ports) {
403 -// notifyDelegate(new DeviceEvent(PORT_UPDATED, getDevice(deviceId)));
404 - }
405 - }
406 -
407 -
408 - // TODO cache serialized DeviceID if we suffer from serialization cost
409 -}
1 -/**
2 - *
3 - */
4 -package org.onlab.onos.store.device.impl;
5 -
6 -import static org.junit.Assert.*;
7 -import static org.onlab.onos.net.Device.Type.SWITCH;
8 -import static org.onlab.onos.net.DeviceId.deviceId;
9 -import static org.onlab.onos.net.device.DeviceEvent.Type.*;
10 -
11 -import java.util.Arrays;
12 -import java.util.HashMap;
13 -import java.util.List;
14 -import java.util.Map;
15 -import java.util.Set;
16 -import java.util.concurrent.CountDownLatch;
17 -import java.util.concurrent.TimeUnit;
18 -
19 -import org.junit.After;
20 -import org.junit.AfterClass;
21 -import org.junit.Before;
22 -import org.junit.BeforeClass;
23 -import org.junit.Ignore;
24 -import org.junit.Test;
25 -import org.onlab.onos.net.Device;
26 -import org.onlab.onos.net.DeviceId;
27 -import org.onlab.onos.net.Port;
28 -import org.onlab.onos.net.PortNumber;
29 -import org.onlab.onos.net.device.DefaultDeviceDescription;
30 -import org.onlab.onos.net.device.DefaultPortDescription;
31 -import org.onlab.onos.net.device.DeviceDescription;
32 -import org.onlab.onos.net.device.DeviceEvent;
33 -import org.onlab.onos.net.device.DeviceStoreDelegate;
34 -import org.onlab.onos.net.device.PortDescription;
35 -import org.onlab.onos.net.provider.ProviderId;
36 -import org.onlab.onos.store.common.StoreManager;
37 -import org.onlab.onos.store.common.StoreService;
38 -import org.onlab.onos.store.common.TestStoreManager;
39 -import com.google.common.collect.Iterables;
40 -import com.google.common.collect.Sets;
41 -import com.hazelcast.config.Config;
42 -import com.hazelcast.core.Hazelcast;
43 -import org.onlab.packet.ChassisId;
44 -
45 -/**
46 - * Test of the Hazelcast based distributed DeviceStore implementation.
47 - */
48 -public class DistributedDeviceStoreTest {
49 -
50 - private static final ProviderId PID = new ProviderId("of", "foo");
51 - private static final DeviceId DID1 = deviceId("of:foo");
52 - private static final DeviceId DID2 = deviceId("of:bar");
53 - private static final String MFR = "whitebox";
54 - private static final String HW = "1.1.x";
55 - private static final String SW1 = "3.8.1";
56 - private static final String SW2 = "3.9.5";
57 - private static final String SN = "43311-12345";
58 - private static final ChassisId CID = new ChassisId();
59 -
60 - private static final PortNumber P1 = PortNumber.portNumber(1);
61 - private static final PortNumber P2 = PortNumber.portNumber(2);
62 - private static final PortNumber P3 = PortNumber.portNumber(3);
63 -
64 - private DistributedDeviceStore deviceStore;
65 -
66 - private StoreManager storeManager;
67 -
68 -
69 - @BeforeClass
70 - public static void setUpBeforeClass() throws Exception {
71 - }
72 -
73 - @AfterClass
74 - public static void tearDownAfterClass() throws Exception {
75 - }
76 -
77 -
78 - @Before
79 - public void setUp() throws Exception {
80 - // TODO should find a way to clean Hazelcast instance without shutdown.
81 - Config config = TestStoreManager.getTestConfig();
82 -
83 - storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config));
84 - storeManager.activate();
85 -
86 - deviceStore = new TestDistributedDeviceStore(storeManager);
87 - deviceStore.activate();
88 - }
89 -
90 - @After
91 - public void tearDown() throws Exception {
92 - deviceStore.deactivate();
93 -
94 - storeManager.deactivate();
95 - }
96 -
97 - private void putDevice(DeviceId deviceId, String swVersion) {
98 - DeviceDescription description =
99 - new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
100 - HW, swVersion, SN, CID);
101 - deviceStore.createOrUpdateDevice(PID, deviceId, description);
102 - }
103 -
104 - private static void assertDevice(DeviceId id, String swVersion, Device device) {
105 - assertNotNull(device);
106 - assertEquals(id, device.id());
107 - assertEquals(MFR, device.manufacturer());
108 - assertEquals(HW, device.hwVersion());
109 - assertEquals(swVersion, device.swVersion());
110 - assertEquals(SN, device.serialNumber());
111 - }
112 -
113 - @Test
114 - public final void testGetDeviceCount() {
115 - assertEquals("initialy empty", 0, deviceStore.getDeviceCount());
116 -
117 - putDevice(DID1, SW1);
118 - putDevice(DID2, SW2);
119 - putDevice(DID1, SW1);
120 -
121 - assertEquals("expect 2 uniq devices", 2, deviceStore.getDeviceCount());
122 - }
123 -
124 - @Test
125 - public final void testGetDevices() {
126 - assertEquals("initialy empty", 0, Iterables.size(deviceStore.getDevices()));
127 -
128 - putDevice(DID1, SW1);
129 - putDevice(DID2, SW2);
130 - putDevice(DID1, SW1);
131 -
132 - assertEquals("expect 2 uniq devices",
133 - 2, Iterables.size(deviceStore.getDevices()));
134 -
135 - Map<DeviceId, Device> devices = new HashMap<>();
136 - for (Device device : deviceStore.getDevices()) {
137 - devices.put(device.id(), device);
138 - }
139 -
140 - assertDevice(DID1, SW1, devices.get(DID1));
141 - assertDevice(DID2, SW2, devices.get(DID2));
142 -
143 - // add case for new node?
144 - }
145 -
146 - @Test
147 - public final void testGetDevice() {
148 -
149 - putDevice(DID1, SW1);
150 -
151 - assertDevice(DID1, SW1, deviceStore.getDevice(DID1));
152 - assertNull("DID2 shouldn't be there", deviceStore.getDevice(DID2));
153 - }
154 -
155 - @Test
156 - public final void testCreateOrUpdateDevice() {
157 - DeviceDescription description =
158 - new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
159 - HW, SW1, SN, CID);
160 - DeviceEvent event = deviceStore.createOrUpdateDevice(PID, DID1, description);
161 - assertEquals(DEVICE_ADDED, event.type());
162 - assertDevice(DID1, SW1, event.subject());
163 -
164 - DeviceDescription description2 =
165 - new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
166 - HW, SW2, SN, CID);
167 - DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2);
168 - assertEquals(DEVICE_UPDATED, event2.type());
169 - assertDevice(DID1, SW2, event2.subject());
170 -
171 - assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2));
172 - }
173 -
174 - @Test
175 - public final void testMarkOffline() {
176 -
177 - putDevice(DID1, SW1);
178 - assertTrue(deviceStore.isAvailable(DID1));
179 -
180 - DeviceEvent event = deviceStore.markOffline(DID1);
181 - assertEquals(DEVICE_AVAILABILITY_CHANGED, event.type());
182 - assertDevice(DID1, SW1, event.subject());
183 - assertFalse(deviceStore.isAvailable(DID1));
184 -
185 - DeviceEvent event2 = deviceStore.markOffline(DID1);
186 - assertNull("No change, no event", event2);
187 -}
188 -
189 - @Test
190 - public final void testUpdatePorts() {
191 - putDevice(DID1, SW1);
192 - List<PortDescription> pds = Arrays.<PortDescription>asList(
193 - new DefaultPortDescription(P1, true),
194 - new DefaultPortDescription(P2, true)
195 - );
196 -
197 - List<DeviceEvent> events = deviceStore.updatePorts(PID, DID1, pds);
198 -
199 - Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
200 - for (DeviceEvent event : events) {
201 - assertEquals(PORT_ADDED, event.type());
202 - assertDevice(DID1, SW1, event.subject());
203 - assertTrue("PortNumber is one of expected",
204 - expectedPorts.remove(event.port().number()));
205 - assertTrue("Port is enabled", event.port().isEnabled());
206 - }
207 - assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
208 -
209 -
210 - List<PortDescription> pds2 = Arrays.<PortDescription>asList(
211 - new DefaultPortDescription(P1, false),
212 - new DefaultPortDescription(P2, true),
213 - new DefaultPortDescription(P3, true)
214 - );
215 -
216 - events = deviceStore.updatePorts(PID, DID1, pds2);
217 - assertFalse("event should be triggered", events.isEmpty());
218 - for (DeviceEvent event : events) {
219 - PortNumber num = event.port().number();
220 - if (P1.equals(num)) {
221 - assertEquals(PORT_UPDATED, event.type());
222 - assertDevice(DID1, SW1, event.subject());
223 - assertFalse("Port is disabled", event.port().isEnabled());
224 - } else if (P2.equals(num)) {
225 - fail("P2 event not expected.");
226 - } else if (P3.equals(num)) {
227 - assertEquals(PORT_ADDED, event.type());
228 - assertDevice(DID1, SW1, event.subject());
229 - assertTrue("Port is enabled", event.port().isEnabled());
230 - } else {
231 - fail("Unknown port number encountered: " + num);
232 - }
233 - }
234 -
235 - List<PortDescription> pds3 = Arrays.<PortDescription>asList(
236 - new DefaultPortDescription(P1, false),
237 - new DefaultPortDescription(P2, true)
238 - );
239 - events = deviceStore.updatePorts(PID, DID1, pds3);
240 - assertFalse("event should be triggered", events.isEmpty());
241 - for (DeviceEvent event : events) {
242 - PortNumber num = event.port().number();
243 - if (P1.equals(num)) {
244 - fail("P1 event not expected.");
245 - } else if (P2.equals(num)) {
246 - fail("P2 event not expected.");
247 - } else if (P3.equals(num)) {
248 - assertEquals(PORT_REMOVED, event.type());
249 - assertDevice(DID1, SW1, event.subject());
250 - assertTrue("Port was enabled", event.port().isEnabled());
251 - } else {
252 - fail("Unknown port number encountered: " + num);
253 - }
254 - }
255 -
256 - }
257 -
258 - @Test
259 - public final void testUpdatePortStatus() {
260 - putDevice(DID1, SW1);
261 - List<PortDescription> pds = Arrays.<PortDescription>asList(
262 - new DefaultPortDescription(P1, true)
263 - );
264 - deviceStore.updatePorts(PID, DID1, pds);
265 -
266 - DeviceEvent event = deviceStore.updatePortStatus(PID, DID1,
267 - new DefaultPortDescription(P1, false));
268 - assertEquals(PORT_UPDATED, event.type());
269 - assertDevice(DID1, SW1, event.subject());
270 - assertEquals(P1, event.port().number());
271 - assertFalse("Port is disabled", event.port().isEnabled());
272 - }
273 -
274 - @Test
275 - public final void testGetPorts() {
276 - putDevice(DID1, SW1);
277 - putDevice(DID2, SW1);
278 - List<PortDescription> pds = Arrays.<PortDescription>asList(
279 - new DefaultPortDescription(P1, true),
280 - new DefaultPortDescription(P2, true)
281 - );
282 - deviceStore.updatePorts(PID, DID1, pds);
283 -
284 - Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
285 - List<Port> ports = deviceStore.getPorts(DID1);
286 - for (Port port : ports) {
287 - assertTrue("Port is enabled", port.isEnabled());
288 - assertTrue("PortNumber is one of expected",
289 - expectedPorts.remove(port.number()));
290 - }
291 - assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
292 -
293 -
294 - assertTrue("DID2 has no ports", deviceStore.getPorts(DID2).isEmpty());
295 - }
296 -
297 - @Test
298 - public final void testGetPort() {
299 - putDevice(DID1, SW1);
300 - putDevice(DID2, SW1);
301 - List<PortDescription> pds = Arrays.<PortDescription>asList(
302 - new DefaultPortDescription(P1, true),
303 - new DefaultPortDescription(P2, false)
304 - );
305 - deviceStore.updatePorts(PID, DID1, pds);
306 -
307 - Port port1 = deviceStore.getPort(DID1, P1);
308 - assertEquals(P1, port1.number());
309 - assertTrue("Port is enabled", port1.isEnabled());
310 -
311 - Port port2 = deviceStore.getPort(DID1, P2);
312 - assertEquals(P2, port2.number());
313 - assertFalse("Port is disabled", port2.isEnabled());
314 -
315 - Port port3 = deviceStore.getPort(DID1, P3);
316 - assertNull("P3 not expected", port3);
317 - }
318 -
319 - @Test
320 - public final void testRemoveDevice() {
321 - putDevice(DID1, SW1);
322 - putDevice(DID2, SW1);
323 -
324 - assertEquals(2, deviceStore.getDeviceCount());
325 -
326 - DeviceEvent event = deviceStore.removeDevice(DID1);
327 - assertEquals(DEVICE_REMOVED, event.type());
328 - assertDevice(DID1, SW1, event.subject());
329 -
330 - assertEquals(1, deviceStore.getDeviceCount());
331 - }
332 -
333 - // TODO add test for Port events when we have them
334 - @Ignore("Ignore until Delegate spec. is clear.")
335 - @Test
336 - public final void testEvents() throws InterruptedException {
337 - final CountDownLatch addLatch = new CountDownLatch(1);
338 - DeviceStoreDelegate checkAdd = new DeviceStoreDelegate() {
339 - @Override
340 - public void notify(DeviceEvent event) {
341 - assertEquals(DEVICE_ADDED, event.type());
342 - assertDevice(DID1, SW1, event.subject());
343 - addLatch.countDown();
344 - }
345 - };
346 - final CountDownLatch updateLatch = new CountDownLatch(1);
347 - DeviceStoreDelegate checkUpdate = new DeviceStoreDelegate() {
348 - @Override
349 - public void notify(DeviceEvent event) {
350 - assertEquals(DEVICE_UPDATED, event.type());
351 - assertDevice(DID1, SW2, event.subject());
352 - updateLatch.countDown();
353 - }
354 - };
355 - final CountDownLatch removeLatch = new CountDownLatch(1);
356 - DeviceStoreDelegate checkRemove = new DeviceStoreDelegate() {
357 - @Override
358 - public void notify(DeviceEvent event) {
359 - assertEquals(DEVICE_REMOVED, event.type());
360 - assertDevice(DID1, SW2, event.subject());
361 - removeLatch.countDown();
362 - }
363 - };
364 -
365 - DeviceDescription description =
366 - new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
367 - HW, SW1, SN, CID);
368 - deviceStore.setDelegate(checkAdd);
369 - deviceStore.createOrUpdateDevice(PID, DID1, description);
370 - assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
371 -
372 -
373 - DeviceDescription description2 =
374 - new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
375 - HW, SW2, SN, CID);
376 - deviceStore.unsetDelegate(checkAdd);
377 - deviceStore.setDelegate(checkUpdate);
378 - deviceStore.createOrUpdateDevice(PID, DID1, description2);
379 - assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
380 -
381 - deviceStore.unsetDelegate(checkUpdate);
382 - deviceStore.setDelegate(checkRemove);
383 - deviceStore.removeDevice(DID1);
384 - assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
385 - }
386 -
387 - private class TestDistributedDeviceStore extends DistributedDeviceStore {
388 - public TestDistributedDeviceStore(StoreService storeService) {
389 - this.storeService = storeService;
390 - }
391 - }
392 -}