HIGUCHI Yuta
Committed by Gerrit Code Review

ONOS-3206 refactoring LLDP link provider.

- refactoring to unify LinkDiscovery helper instantiation
- Support suppression rule update at runtime

Change-Id: I2a6db6e82fcb90ee5635f0ac09564efd55276ebf
...@@ -61,7 +61,7 @@ class LinkDiscovery implements TimerTask { ...@@ -61,7 +61,7 @@ class LinkDiscovery implements TimerTask {
61 61
62 private final ONOSLLDP lldpPacket; 62 private final ONOSLLDP lldpPacket;
63 private final Ethernet ethPacket; 63 private final Ethernet ethPacket;
64 - private Ethernet bddpEth; 64 + private final Ethernet bddpEth;
65 65
66 private Timeout timeout; 66 private Timeout timeout;
67 private volatile boolean isStopped; 67 private volatile boolean isStopped;
...@@ -126,7 +126,7 @@ class LinkDiscovery implements TimerTask { ...@@ -126,7 +126,7 @@ class LinkDiscovery implements TimerTask {
126 } 126 }
127 127
128 /** 128 /**
129 - * Add physical port port to discovery process. 129 + * Add physical port to discovery process.
130 * Send out initial LLDP and label it as slow port. 130 * Send out initial LLDP and label it as slow port.
131 * 131 *
132 * @param port the port 132 * @param port the port
...@@ -141,6 +141,14 @@ class LinkDiscovery implements TimerTask { ...@@ -141,6 +141,14 @@ class LinkDiscovery implements TimerTask {
141 } 141 }
142 142
143 /** 143 /**
144 + * removed physical port from discovery process.
145 + * @param port the port number
146 + */
147 + void removePort(PortNumber port) {
148 + ports.remove(port.toLong());
149 + }
150 +
151 + /**
144 * Handles an incoming LLDP packet. Creates link in topology and adds the 152 * Handles an incoming LLDP packet. Creates link in topology and adds the
145 * link for staleness tracking. 153 * link for staleness tracking.
146 * 154 *
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.provider.lldp.impl; 16 package org.onosproject.provider.lldp.impl;
17 17
18 import com.google.common.collect.ArrayListMultimap; 18 import com.google.common.collect.ArrayListMultimap;
19 +import com.google.common.collect.ImmutableList;
19 import com.google.common.collect.Lists; 20 import com.google.common.collect.Lists;
20 import com.google.common.collect.Maps; 21 import com.google.common.collect.Maps;
21 import org.junit.After; 22 import org.junit.After;
...@@ -32,7 +33,9 @@ import org.onosproject.core.CoreService; ...@@ -32,7 +33,9 @@ import org.onosproject.core.CoreService;
32 import org.onosproject.core.DefaultApplicationId; 33 import org.onosproject.core.DefaultApplicationId;
33 import org.onosproject.mastership.MastershipListener; 34 import org.onosproject.mastership.MastershipListener;
34 import org.onosproject.mastership.MastershipService; 35 import org.onosproject.mastership.MastershipService;
36 +import org.onosproject.net.Annotations;
35 import org.onosproject.net.ConnectPoint; 37 import org.onosproject.net.ConnectPoint;
38 +import org.onosproject.net.DefaultAnnotations;
36 import org.onosproject.net.DefaultDevice; 39 import org.onosproject.net.DefaultDevice;
37 import org.onosproject.net.DefaultPort; 40 import org.onosproject.net.DefaultPort;
38 import org.onosproject.net.Device; 41 import org.onosproject.net.Device;
...@@ -73,6 +76,7 @@ public class LLDPLinkProviderTest { ...@@ -73,6 +76,7 @@ public class LLDPLinkProviderTest {
73 76
74 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001"); 77 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
75 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002"); 78 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
79 + private static final DeviceId DID3 = DeviceId.deviceId("of:0000000000000003");
76 80
77 private static Port pd1; 81 private static Port pd1;
78 private static Port pd2; 82 private static Port pd2;
...@@ -133,10 +137,35 @@ public class LLDPLinkProviderTest { ...@@ -133,10 +137,35 @@ public class LLDPLinkProviderTest {
133 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); 137 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
134 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1)); 138 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
135 139
136 - assertTrue("Discoverer is not gone", provider.discoverers.get(DID1).isStopped()); 140 + final LinkDiscovery linkDiscovery = provider.discoverers.get(DID1);
141 + if (linkDiscovery != null) {
142 + // If LinkDiscovery helper is there after DEVICE_REMOVED,
143 + // it should be stopped
144 + assertTrue("Discoverer is not stopped", linkDiscovery.isStopped());
145 + }
137 assertTrue("Device is not gone.", vanishedDpid(DID1)); 146 assertTrue("Device is not gone.", vanishedDpid(DID1));
138 } 147 }
139 148
149 + /**
150 + * Checks that links on a reconfigured switch are properly removed.
151 + */
152 + @Test
153 + public void switchSuppressed() {
154 + // add device to stub DeviceService
155 + deviceService.putDevice(device(DID3));
156 + deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
157 +
158 + assertFalse("Device not added", provider.discoverers.isEmpty());
159 +
160 + // update device in stub DeviceService with suppression config
161 + deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
162 + .set(LLDPLinkProvider.NO_LLDP, "true")
163 + .build()));
164 + deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
165 +
166 + assertTrue("Links on suppressed Device was expected to vanish.", vanishedDpid(DID3));
167 + }
168 +
140 @Test 169 @Test
141 public void portUp() { 170 public void portUp() {
142 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); 171 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
...@@ -152,27 +181,101 @@ public class LLDPLinkProviderTest { ...@@ -152,27 +181,101 @@ public class LLDPLinkProviderTest {
152 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); 181 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
153 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false))); 182 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
154 183
155 -
156 -
157 assertFalse("Port added to discoverer", 184 assertFalse("Port added to discoverer",
158 provider.discoverers.get(DID1).containsPort(1L)); 185 provider.discoverers.get(DID1).containsPort(1L));
159 assertTrue("Port is not gone.", vanishedPort(1L)); 186 assertTrue("Port is not gone.", vanishedPort(1L));
160 } 187 }
161 188
162 @Test 189 @Test
190 + public void portRemoved() {
191 + deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
192 + deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
193 + deviceListener.event(portEvent(DeviceEvent.Type.PORT_REMOVED, DID1, port(DID1, 3, true)));
194 +
195 + assertTrue("Port is not gone.", vanishedPort(3L));
196 + assertFalse("Port was not removed from discoverer",
197 + provider.discoverers.get(DID1).containsPort(3L));
198 + }
199 +
200 + /**
201 + * Checks that discovery on reconfigured switch are properly restarted.
202 + */
203 + @Test
204 + public void portSuppressedByDeviceConfig() {
205 +
206 + /// When Device is configured with suppression:ON, Port also is same
207 +
208 + // add device in stub DeviceService with suppression configured
209 + deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
210 + .set(LLDPLinkProvider.NO_LLDP, "true")
211 + .build()));
212 + deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
213 +
214 + // non-suppressed port added to suppressed device
215 + final long portno3 = 3L;
216 + deviceService.putPorts(DID3, port(DID3, portno3, true));
217 + deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
218 +
219 + // discovery on device is expected to be stopped
220 + LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
221 + if (linkDiscovery != null) {
222 + assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
223 + }
224 +
225 + /// When Device is reconfigured without suppression:OFF,
226 + /// Port should be included for discovery
227 +
228 + // update device in stub DeviceService without suppression configured
229 + deviceService.putDevice(device(DID3));
230 + // update the Port in stub DeviceService. (Port has reference to Device)
231 + deviceService.putPorts(DID3, port(DID3, portno3, true));
232 + deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
233 +
234 + // discovery should come back on
235 + assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
236 + assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
237 + }
238 +
239 + /**
240 + * Checks that discovery on reconfigured port are properly restarted.
241 + */
242 + @Test
243 + public void portSuppressedByPortConfig() {
244 + // add device in stub DeviceService without suppression configured
245 + deviceService.putDevice(device(DID3));
246 + deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
247 +
248 + // suppressed port added to non-suppressed device
249 + final long portno3 = 3L;
250 + final Port port3 = port(DID3, portno3, true,
251 + DefaultAnnotations.builder()
252 + .set(LLDPLinkProvider.NO_LLDP, "true")
253 + .build());
254 + deviceService.putPorts(DID3, port3);
255 + deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
256 +
257 + // discovery helper should be there turned on
258 + assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
259 + assertFalse("Discoverer should not contain the port there",
260 + provider.discoverers.get(DID3).containsPort(portno3));
261 + }
262 +
263 + @Test
163 public void portUnknown() { 264 public void portUnknown() {
164 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); 265 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
165 - deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, 1, false))); 266 + // Note: DID3 hasn't been added to TestDeviceService, but only port is added
267 + deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, 1, false)));
166 268
167 269
168 assertNull("DeviceId exists", 270 assertNull("DeviceId exists",
169 - provider.discoverers.get(DID2)); 271 + provider.discoverers.get(DID3));
170 } 272 }
171 273
172 @Test 274 @Test
173 public void unknownPktCtx() { 275 public void unknownPktCtx() {
174 276
175 - PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2)); 277 + // Note: DID3 hasn't been added to TestDeviceService
278 + PacketContext pktCtx = new TestPacketContext(device(DID3));
176 279
177 testProcessor.process(pktCtx); 280 testProcessor.process(pktCtx);
178 assertFalse("Context should still be free", pktCtx.isHandled()); 281 assertFalse("Context should still be free", pktCtx.isHandled());
...@@ -206,6 +309,16 @@ public class LLDPLinkProviderTest { ...@@ -206,6 +309,16 @@ public class LLDPLinkProviderTest {
206 309
207 } 310 }
208 311
312 + private DefaultDevice device(DeviceId did) {
313 + return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
314 + "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
315 + }
316 +
317 + private DefaultDevice device(DeviceId did, Annotations annotations) {
318 + return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
319 + "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations);
320 + }
321 +
209 @SuppressWarnings(value = { "unused" }) 322 @SuppressWarnings(value = { "unused" })
210 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) { 323 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
211 return new DeviceEvent(type, deviceService.getDevice(did), 324 return new DeviceEvent(type, deviceService.getDevice(did),
...@@ -221,6 +334,10 @@ public class LLDPLinkProviderTest { ...@@ -221,6 +334,10 @@ public class LLDPLinkProviderTest {
221 PortNumber.portNumber(port), enabled); 334 PortNumber.portNumber(port), enabled);
222 } 335 }
223 336
337 + private Port port(DeviceId did, long port, boolean enabled, Annotations annotations) {
338 + return new DefaultPort(deviceService.getDevice(did),
339 + PortNumber.portNumber(port), enabled, annotations);
340 + }
224 341
225 private boolean vanishedDpid(DeviceId... dids) { 342 private boolean vanishedDpid(DeviceId... dids) {
226 for (int i = 0; i < dids.length; i++) { 343 for (int i = 0; i < dids.length; i++) {
...@@ -384,10 +501,9 @@ public class LLDPLinkProviderTest { ...@@ -384,10 +501,9 @@ public class LLDPLinkProviderTest {
384 501
385 private class TestDeviceService extends DeviceServiceAdapter { 502 private class TestDeviceService extends DeviceServiceAdapter {
386 503
387 - private Map<DeviceId, Device> devices = new HashMap<>(); 504 + private final Map<DeviceId, Device> devices = new HashMap<>();
388 private final ArrayListMultimap<DeviceId, Port> ports = 505 private final ArrayListMultimap<DeviceId, Port> ports =
389 ArrayListMultimap.create(); 506 ArrayListMultimap.create();
390 -
391 public TestDeviceService() { 507 public TestDeviceService() {
392 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH, 508 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
393 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId()); 509 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
...@@ -395,7 +511,6 @@ public class LLDPLinkProviderTest { ...@@ -395,7 +511,6 @@ public class LLDPLinkProviderTest {
395 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId()); 511 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
396 devices.put(DID1, d1); 512 devices.put(DID1, d1);
397 devices.put(DID2, d2); 513 devices.put(DID2, d2);
398 -
399 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true); 514 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
400 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true); 515 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
401 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true); 516 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
...@@ -405,6 +520,15 @@ public class LLDPLinkProviderTest { ...@@ -405,6 +520,15 @@ public class LLDPLinkProviderTest {
405 ports.putAll(DID2, Lists.newArrayList(pd3, pd4)); 520 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
406 } 521 }
407 522
523 + private void putDevice(Device device) {
524 + DeviceId deviceId = device.id();
525 + devices.put(deviceId, device);
526 + }
527 +
528 + private void putPorts(DeviceId did, Port...ports) {
529 + this.ports.putAll(did, Lists.newArrayList(ports));
530 + }
531 +
408 @Override 532 @Override
409 public int getDeviceCount() { 533 public int getDeviceCount() {
410 return devices.values().size(); 534 return devices.values().size();
...@@ -412,7 +536,7 @@ public class LLDPLinkProviderTest { ...@@ -412,7 +536,7 @@ public class LLDPLinkProviderTest {
412 536
413 @Override 537 @Override
414 public Iterable<Device> getDevices() { 538 public Iterable<Device> getDevices() {
415 - return Collections.emptyList(); 539 + return ImmutableList.copyOf(devices.values());
416 } 540 }
417 541
418 @Override 542 @Override
......