Committed by
Gerrit Code Review
[ONOS-3205] Migrate LLDP Link Discovery configuration to Network Configuration System
- deviceIds under suppression will be moved out to different location. (See ONOS-3461) Change-Id: I6ebe0ce7f5f2d26e7ee7175974e19305f7c17fad
Showing
11 changed files
with
707 additions
and
312 deletions
... | @@ -333,6 +333,26 @@ public abstract class Config<S> { | ... | @@ -333,6 +333,26 @@ public abstract class Config<S> { |
333 | } | 333 | } |
334 | 334 | ||
335 | /** | 335 | /** |
336 | + * Gets the specified array property as a list of items. | ||
337 | + * | ||
338 | + * @param name property name | ||
339 | + * @param function mapper from string to item | ||
340 | + * @param defaultValue default value if property not set | ||
341 | + * @param <T> type of item | ||
342 | + * @return list of items | ||
343 | + */ | ||
344 | + protected <T> List<T> getList(String name, Function<String, T> function, List<T> defaultValue) { | ||
345 | + List<T> list = Lists.newArrayList(); | ||
346 | + JsonNode jsonNode = object.path(name); | ||
347 | + if (jsonNode.isMissingNode()) { | ||
348 | + return defaultValue; | ||
349 | + } | ||
350 | + ArrayNode arrayNode = (ArrayNode) jsonNode; | ||
351 | + arrayNode.forEach(i -> list.add(function.apply(i.asText()))); | ||
352 | + return list; | ||
353 | + } | ||
354 | + | ||
355 | + /** | ||
336 | * Sets the specified property as an array of items in a given collection or | 356 | * Sets the specified property as an array of items in a given collection or |
337 | * clears it if null is given. | 357 | * clears it if null is given. |
338 | * | 358 | * | ... | ... |
... | @@ -55,5 +55,9 @@ | ... | @@ -55,5 +55,9 @@ |
55 | <scope>test</scope> | 55 | <scope>test</scope> |
56 | </dependency> | 56 | </dependency> |
57 | 57 | ||
58 | + <dependency> | ||
59 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
60 | + <artifactId>jackson-databind</artifactId> | ||
61 | + </dependency> | ||
58 | </dependencies> | 62 | </dependencies> |
59 | </project> | 63 | </project> | ... | ... |
... | @@ -38,6 +38,9 @@ import org.onosproject.net.Device; | ... | @@ -38,6 +38,9 @@ import org.onosproject.net.Device; |
38 | import org.onosproject.net.DeviceId; | 38 | import org.onosproject.net.DeviceId; |
39 | import org.onosproject.net.LinkKey; | 39 | import org.onosproject.net.LinkKey; |
40 | import org.onosproject.net.Port; | 40 | import org.onosproject.net.Port; |
41 | +import org.onosproject.net.config.ConfigFactory; | ||
42 | +import org.onosproject.net.config.NetworkConfigEvent; | ||
43 | +import org.onosproject.net.config.NetworkConfigListener; | ||
41 | import org.onosproject.net.config.NetworkConfigRegistry; | 44 | import org.onosproject.net.config.NetworkConfigRegistry; |
42 | import org.onosproject.net.device.DeviceEvent; | 45 | import org.onosproject.net.device.DeviceEvent; |
43 | import org.onosproject.net.device.DeviceListener; | 46 | import org.onosproject.net.device.DeviceListener; |
... | @@ -58,12 +61,12 @@ import org.onosproject.net.provider.ProviderId; | ... | @@ -58,12 +61,12 @@ import org.onosproject.net.provider.ProviderId; |
58 | import org.osgi.service.component.ComponentContext; | 61 | import org.osgi.service.component.ComponentContext; |
59 | import org.slf4j.Logger; | 62 | import org.slf4j.Logger; |
60 | 63 | ||
61 | -import java.io.IOException; | ||
62 | import java.util.Dictionary; | 64 | import java.util.Dictionary; |
63 | import java.util.EnumSet; | 65 | import java.util.EnumSet; |
64 | import java.util.Map; | 66 | import java.util.Map; |
65 | import java.util.Optional; | 67 | import java.util.Optional; |
66 | import java.util.Properties; | 68 | import java.util.Properties; |
69 | +import java.util.Set; | ||
67 | import java.util.concurrent.ConcurrentHashMap; | 70 | import java.util.concurrent.ConcurrentHashMap; |
68 | import java.util.concurrent.ScheduledExecutorService; | 71 | import java.util.concurrent.ScheduledExecutorService; |
69 | 72 | ||
... | @@ -75,6 +78,7 @@ import static org.onlab.packet.Ethernet.TYPE_LLDP; | ... | @@ -75,6 +78,7 @@ import static org.onlab.packet.Ethernet.TYPE_LLDP; |
75 | import static org.onlab.util.Tools.get; | 78 | import static org.onlab.util.Tools.get; |
76 | import static org.onlab.util.Tools.groupedThreads; | 79 | import static org.onlab.util.Tools.groupedThreads; |
77 | import static org.onosproject.net.Link.Type.DIRECT; | 80 | import static org.onosproject.net.Link.Type.DIRECT; |
81 | +import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; | ||
78 | import static org.slf4j.LoggerFactory.getLogger; | 82 | import static org.slf4j.LoggerFactory.getLogger; |
79 | 83 | ||
80 | /** | 84 | /** |
... | @@ -87,12 +91,11 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -87,12 +91,11 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
87 | 91 | ||
88 | private static final String FORMAT = | 92 | private static final String FORMAT = |
89 | "Settings: enabled={}, useBDDP={}, probeRate={}, " + | 93 | "Settings: enabled={}, useBDDP={}, probeRate={}, " + |
90 | - "staleLinkAge={}, lldpSuppression={}"; | 94 | + "staleLinkAge={}"; |
91 | 95 | ||
92 | // When a Device/Port has this annotation, do not send out LLDP/BDDP | 96 | // When a Device/Port has this annotation, do not send out LLDP/BDDP |
93 | public static final String NO_LLDP = "no-lldp"; | 97 | public static final String NO_LLDP = "no-lldp"; |
94 | 98 | ||
95 | - | ||
96 | private final Logger log = getLogger(getClass()); | 99 | private final Logger log = getLogger(getClass()); |
97 | 100 | ||
98 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 101 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
... | @@ -152,13 +155,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -152,13 +155,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
152 | label = "Number of millis beyond which links will be considered stale") | 155 | label = "Number of millis beyond which links will be considered stale") |
153 | private int staleLinkAge = DEFAULT_STALE_LINK_AGE; | 156 | private int staleLinkAge = DEFAULT_STALE_LINK_AGE; |
154 | 157 | ||
155 | - // FIXME: convert to use network config subsystem instead | ||
156 | - private static final String PROP_LLDP_SUPPRESSION = "lldpSuppression"; | ||
157 | - private static final String DEFAULT_LLDP_SUPPRESSION_CONFIG = "../config/lldp_suppression.json"; | ||
158 | - @Property(name = PROP_LLDP_SUPPRESSION, value = DEFAULT_LLDP_SUPPRESSION_CONFIG, | ||
159 | - label = "Path to LLDP suppression configuration file") | ||
160 | - private String lldpSuppression = DEFAULT_LLDP_SUPPRESSION_CONFIG; | ||
161 | - | ||
162 | private final DiscoveryContext context = new InternalDiscoveryContext(); | 158 | private final DiscoveryContext context = new InternalDiscoveryContext(); |
163 | private final InternalRoleListener roleListener = new InternalRoleListener(); | 159 | private final InternalRoleListener roleListener = new InternalRoleListener(); |
164 | private final InternalDeviceListener deviceListener = new InternalDeviceListener(); | 160 | private final InternalDeviceListener deviceListener = new InternalDeviceListener(); |
... | @@ -171,9 +167,31 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -171,9 +167,31 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
171 | // destination connection point is mastered by this controller instance. | 167 | // destination connection point is mastered by this controller instance. |
172 | private final Map<LinkKey, Long> linkTimes = Maps.newConcurrentMap(); | 168 | private final Map<LinkKey, Long> linkTimes = Maps.newConcurrentMap(); |
173 | 169 | ||
174 | - private SuppressionRules rules; | ||
175 | private ApplicationId appId; | 170 | private ApplicationId appId; |
176 | 171 | ||
172 | + static final SuppressionRules DEFAULT_RULES | ||
173 | + = new SuppressionRules(ImmutableSet.of(), | ||
174 | + EnumSet.of(Device.Type.ROADM), | ||
175 | + ImmutableMap.of(NO_LLDP, SuppressionRules.ANY_VALUE)); | ||
176 | + | ||
177 | + private SuppressionRules rules = LldpLinkProvider.DEFAULT_RULES; | ||
178 | + | ||
179 | + public static final String CONFIG_KEY = "suppression"; | ||
180 | + | ||
181 | + private final Set<ConfigFactory> factories = ImmutableSet.of( | ||
182 | + new ConfigFactory<ApplicationId, SuppressionConfig>(APP_SUBJECT_FACTORY, | ||
183 | + SuppressionConfig.class, | ||
184 | + CONFIG_KEY) { | ||
185 | + @Override | ||
186 | + public SuppressionConfig createConfig() { | ||
187 | + return new SuppressionConfig(); | ||
188 | + } | ||
189 | + } | ||
190 | + ); | ||
191 | + | ||
192 | + private final InternalConfigListener cfgListener = new InternalConfigListener(); | ||
193 | + | ||
194 | + | ||
177 | /** | 195 | /** |
178 | * Creates an OpenFlow link provider. | 196 | * Creates an OpenFlow link provider. |
179 | */ | 197 | */ |
... | @@ -185,12 +203,30 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -185,12 +203,30 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
185 | public void activate(ComponentContext context) { | 203 | public void activate(ComponentContext context) { |
186 | cfgService.registerProperties(getClass()); | 204 | cfgService.registerProperties(getClass()); |
187 | appId = coreService.registerApplication(PROVIDER_NAME); | 205 | appId = coreService.registerApplication(PROVIDER_NAME); |
206 | + | ||
207 | + cfgRegistry.addListener(cfgListener); | ||
208 | + factories.forEach(cfgRegistry::registerConfigFactory); | ||
209 | + | ||
210 | + SuppressionConfig cfg = cfgRegistry.getConfig(appId, SuppressionConfig.class); | ||
211 | + if (cfg == null) { | ||
212 | + // If no configuration is found, register default. | ||
213 | + cfg = cfgRegistry.addConfig(appId, SuppressionConfig.class); | ||
214 | + cfg.deviceIds(DEFAULT_RULES.getSuppressedDevice()) | ||
215 | + .deviceTypes(DEFAULT_RULES.getSuppressedDeviceType()) | ||
216 | + .annotation(DEFAULT_RULES.getSuppressedAnnotation()) | ||
217 | + .apply(); | ||
218 | + } | ||
219 | + cfgListener.reconfigureSuppressionRules(cfg); | ||
220 | + | ||
188 | modified(context); | 221 | modified(context); |
189 | log.info("Started"); | 222 | log.info("Started"); |
190 | } | 223 | } |
191 | 224 | ||
192 | @Deactivate | 225 | @Deactivate |
193 | public void deactivate() { | 226 | public void deactivate() { |
227 | + cfgRegistry.removeListener(cfgListener); | ||
228 | + factories.forEach(cfgRegistry::unregisterConfigFactory); | ||
229 | + | ||
194 | cfgService.unregisterProperties(getClass(), false); | 230 | cfgService.unregisterProperties(getClass(), false); |
195 | disable(); | 231 | disable(); |
196 | log.info("Stopped"); | 232 | log.info("Stopped"); |
... | @@ -202,7 +238,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -202,7 +238,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
202 | 238 | ||
203 | boolean newEnabled, newUseBddp; | 239 | boolean newEnabled, newUseBddp; |
204 | int newProbeRate, newStaleLinkAge; | 240 | int newProbeRate, newStaleLinkAge; |
205 | - String newLldpSuppression; | ||
206 | try { | 241 | try { |
207 | String s = get(properties, PROP_ENABLED); | 242 | String s = get(properties, PROP_ENABLED); |
208 | newEnabled = isNullOrEmpty(s) || Boolean.parseBoolean(s.trim()); | 243 | newEnabled = isNullOrEmpty(s) || Boolean.parseBoolean(s.trim()); |
... | @@ -216,16 +251,12 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -216,16 +251,12 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
216 | s = get(properties, PROP_STALE_LINK_AGE); | 251 | s = get(properties, PROP_STALE_LINK_AGE); |
217 | newStaleLinkAge = isNullOrEmpty(s) ? staleLinkAge : Integer.parseInt(s.trim()); | 252 | newStaleLinkAge = isNullOrEmpty(s) ? staleLinkAge : Integer.parseInt(s.trim()); |
218 | 253 | ||
219 | - s = get(properties, PROP_LLDP_SUPPRESSION); | ||
220 | - newLldpSuppression = isNullOrEmpty(s) ? DEFAULT_LLDP_SUPPRESSION_CONFIG : s; | ||
221 | - | ||
222 | } catch (NumberFormatException e) { | 254 | } catch (NumberFormatException e) { |
223 | log.warn("Component configuration had invalid values", e); | 255 | log.warn("Component configuration had invalid values", e); |
224 | newEnabled = enabled; | 256 | newEnabled = enabled; |
225 | newUseBddp = useBddp; | 257 | newUseBddp = useBddp; |
226 | newProbeRate = probeRate; | 258 | newProbeRate = probeRate; |
227 | newStaleLinkAge = staleLinkAge; | 259 | newStaleLinkAge = staleLinkAge; |
228 | - newLldpSuppression = lldpSuppression; | ||
229 | } | 260 | } |
230 | 261 | ||
231 | boolean wasEnabled = enabled; | 262 | boolean wasEnabled = enabled; |
... | @@ -234,23 +265,19 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -234,23 +265,19 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
234 | useBddp = newUseBddp; | 265 | useBddp = newUseBddp; |
235 | probeRate = newProbeRate; | 266 | probeRate = newProbeRate; |
236 | staleLinkAge = newStaleLinkAge; | 267 | staleLinkAge = newStaleLinkAge; |
237 | - lldpSuppression = newLldpSuppression; | ||
238 | 268 | ||
239 | if (!wasEnabled && enabled) { | 269 | if (!wasEnabled && enabled) { |
240 | enable(); | 270 | enable(); |
241 | } else if (wasEnabled && !enabled) { | 271 | } else if (wasEnabled && !enabled) { |
242 | disable(); | 272 | disable(); |
243 | } else { | 273 | } else { |
244 | - // reflect changes in suppression rules to discovery helpers | ||
245 | - // FIXME: After migrating to Network Configuration Subsystem, | ||
246 | - // it should be possible to update only changed subset | ||
247 | if (enabled) { | 274 | if (enabled) { |
248 | // update all discovery helper state | 275 | // update all discovery helper state |
249 | loadDevices(); | 276 | loadDevices(); |
250 | } | 277 | } |
251 | } | 278 | } |
252 | 279 | ||
253 | - log.info(FORMAT, enabled, useBddp, probeRate, staleLinkAge, lldpSuppression); | 280 | + log.info(FORMAT, enabled, useBddp, probeRate, staleLinkAge); |
254 | } | 281 | } |
255 | 282 | ||
256 | /** | 283 | /** |
... | @@ -262,7 +289,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -262,7 +289,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
262 | deviceService.addListener(deviceListener); | 289 | deviceService.addListener(deviceListener); |
263 | packetService.addProcessor(packetProcessor, PacketProcessor.advisor(0)); | 290 | packetService.addProcessor(packetProcessor, PacketProcessor.advisor(0)); |
264 | 291 | ||
265 | - loadSuppressionRules(); | ||
266 | loadDevices(); | 292 | loadDevices(); |
267 | 293 | ||
268 | executor = newSingleThreadScheduledExecutor(groupedThreads("onos/link", "discovery-%d")); | 294 | executor = newSingleThreadScheduledExecutor(groupedThreads("onos/link", "discovery-%d")); |
... | @@ -285,6 +311,7 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -285,6 +311,7 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
285 | deviceService.removeListener(deviceListener); | 311 | deviceService.removeListener(deviceListener); |
286 | packetService.removeProcessor(packetProcessor); | 312 | packetService.removeProcessor(packetProcessor); |
287 | 313 | ||
314 | + | ||
288 | if (executor != null) { | 315 | if (executor != null) { |
289 | executor.shutdownNow(); | 316 | executor.shutdownNow(); |
290 | } | 317 | } |
... | @@ -298,6 +325,9 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -298,6 +325,9 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
298 | * Loads available devices and registers their ports to be probed. | 325 | * Loads available devices and registers their ports to be probed. |
299 | */ | 326 | */ |
300 | private void loadDevices() { | 327 | private void loadDevices() { |
328 | + if (!enabled) { | ||
329 | + return; | ||
330 | + } | ||
301 | deviceService.getAvailableDevices() | 331 | deviceService.getAvailableDevices() |
302 | .forEach(d -> updateDevice(d) | 332 | .forEach(d -> updateDevice(d) |
303 | .ifPresent(ld -> updatePorts(ld, d.id()))); | 333 | .ifPresent(ld -> updatePorts(ld, d.id()))); |
... | @@ -333,7 +363,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -333,7 +363,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
333 | private void removeDevice(final DeviceId deviceId) { | 363 | private void removeDevice(final DeviceId deviceId) { |
334 | discoverers.computeIfPresent(deviceId, (did, ld) -> { | 364 | discoverers.computeIfPresent(deviceId, (did, ld) -> { |
335 | ld.stop(); | 365 | ld.stop(); |
336 | - providerService.linksVanished(deviceId); | ||
337 | return null; | 366 | return null; |
338 | }); | 367 | }); |
339 | 368 | ||
... | @@ -357,6 +386,7 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -357,6 +386,7 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
357 | // silently ignore logical ports | 386 | // silently ignore logical ports |
358 | return; | 387 | return; |
359 | } | 388 | } |
389 | + | ||
360 | if (rules.isSuppressed(port)) { | 390 | if (rules.isSuppressed(port)) { |
361 | log.trace("LinkDiscovery from {} disabled by configuration", port); | 391 | log.trace("LinkDiscovery from {} disabled by configuration", port); |
362 | removePort(port); | 392 | removePort(port); |
... | @@ -383,35 +413,12 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -383,35 +413,12 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
383 | if (ld != null) { | 413 | if (ld != null) { |
384 | ld.removePort(port.number()); | 414 | ld.removePort(port.number()); |
385 | } | 415 | } |
386 | - | ||
387 | - ConnectPoint point = new ConnectPoint(d.id(), port.number()); | ||
388 | - providerService.linksVanished(point); | ||
389 | } else { | 416 | } else { |
390 | log.warn("Attempted to remove non-Device port", port); | 417 | log.warn("Attempted to remove non-Device port", port); |
391 | } | 418 | } |
392 | } | 419 | } |
393 | 420 | ||
394 | /** | 421 | /** |
395 | - * Loads LLDP suppression rules. | ||
396 | - */ | ||
397 | - private void loadSuppressionRules() { | ||
398 | - // FIXME: convert to use network configuration | ||
399 | - SuppressionRulesStore store = new SuppressionRulesStore(lldpSuppression); | ||
400 | - try { | ||
401 | - log.info("Reading suppression rules from {}", lldpSuppression); | ||
402 | - rules = store.read(); | ||
403 | - } catch (IOException e) { | ||
404 | - log.info("Failed to load {}, using built-in rules", lldpSuppression); | ||
405 | - // default rule to suppress ROADM to maintain compatibility | ||
406 | - rules = new SuppressionRules(ImmutableSet.of(), | ||
407 | - EnumSet.of(Device.Type.ROADM), | ||
408 | - ImmutableMap.of(NO_LLDP, SuppressionRules.ANY_VALUE)); | ||
409 | - } | ||
410 | - | ||
411 | - // should refresh discoverers when we need dynamic reconfiguration | ||
412 | - } | ||
413 | - | ||
414 | - /** | ||
415 | * Requests packet intercepts. | 422 | * Requests packet intercepts. |
416 | */ | 423 | */ |
417 | private void requestIntercepts() { | 424 | private void requestIntercepts() { |
... | @@ -438,6 +445,17 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -438,6 +445,17 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
438 | packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId); | 445 | packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId); |
439 | } | 446 | } |
440 | 447 | ||
448 | + protected SuppressionRules rules() { | ||
449 | + return rules; | ||
450 | + } | ||
451 | + | ||
452 | + protected void updateRules(SuppressionRules newRules) { | ||
453 | + if (!rules.equals(newRules)) { | ||
454 | + rules = newRules; | ||
455 | + loadDevices(); | ||
456 | + } | ||
457 | + } | ||
458 | + | ||
441 | /** | 459 | /** |
442 | * Processes device mastership role changes. | 460 | * Processes device mastership role changes. |
443 | */ | 461 | */ |
... | @@ -459,7 +477,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -459,7 +477,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
459 | updateDevice(device).ifPresent(ld -> updatePorts(ld, device.id())); | 477 | updateDevice(device).ifPresent(ld -> updatePorts(ld, device.id())); |
460 | } | 478 | } |
461 | } | 479 | } |
462 | - | ||
463 | } | 480 | } |
464 | 481 | ||
465 | /** | 482 | /** |
... | @@ -488,16 +505,21 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -488,16 +505,21 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
488 | } else { | 505 | } else { |
489 | log.debug("Port down {}", port); | 506 | log.debug("Port down {}", port); |
490 | removePort(port); | 507 | removePort(port); |
508 | + providerService.linksVanished(new ConnectPoint(port.element().id(), | ||
509 | + port.number())); | ||
491 | } | 510 | } |
492 | break; | 511 | break; |
493 | case PORT_REMOVED: | 512 | case PORT_REMOVED: |
494 | log.debug("Port removed {}", port); | 513 | log.debug("Port removed {}", port); |
495 | removePort(port); | 514 | removePort(port); |
515 | + providerService.linksVanished(new ConnectPoint(port.element().id(), | ||
516 | + port.number())); | ||
496 | break; | 517 | break; |
497 | case DEVICE_REMOVED: | 518 | case DEVICE_REMOVED: |
498 | case DEVICE_SUSPENDED: | 519 | case DEVICE_SUSPENDED: |
499 | log.debug("Device removed {}", deviceId); | 520 | log.debug("Device removed {}", deviceId); |
500 | removeDevice(deviceId); | 521 | removeDevice(deviceId); |
522 | + providerService.linksVanished(deviceId); | ||
501 | break; | 523 | break; |
502 | case DEVICE_AVAILABILITY_CHANGED: | 524 | case DEVICE_AVAILABILITY_CHANGED: |
503 | if (deviceService.isAvailable(deviceId)) { | 525 | if (deviceService.isAvailable(deviceId)) { |
... | @@ -506,6 +528,7 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -506,6 +528,7 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
506 | } else { | 528 | } else { |
507 | log.debug("Device down {}", deviceId); | 529 | log.debug("Device down {}", deviceId); |
508 | removeDevice(deviceId); | 530 | removeDevice(deviceId); |
531 | + providerService.linksVanished(deviceId); | ||
509 | } | 532 | } |
510 | break; | 533 | break; |
511 | case PORT_STATS_UPDATED: | 534 | case PORT_STATS_UPDATED: |
... | @@ -636,4 +659,30 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -636,4 +659,30 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
636 | } | 659 | } |
637 | } | 660 | } |
638 | 661 | ||
662 | + private class InternalConfigListener implements NetworkConfigListener { | ||
663 | + | ||
664 | + private synchronized void reconfigureSuppressionRules(SuppressionConfig cfg) { | ||
665 | + if (cfg == null) { | ||
666 | + log.error("Suppression Config is null."); | ||
667 | + return; | ||
668 | + } | ||
669 | + | ||
670 | + SuppressionRules newRules = new SuppressionRules(cfg.deviceIds(), | ||
671 | + cfg.deviceTypes(), | ||
672 | + cfg.annotation()); | ||
673 | + | ||
674 | + updateRules(newRules); | ||
675 | + } | ||
676 | + | ||
677 | + @Override | ||
678 | + public void event(NetworkConfigEvent event) { | ||
679 | + if (event.configClass().equals(SuppressionConfig.class) && | ||
680 | + (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || | ||
681 | + event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) { | ||
682 | + SuppressionConfig cfg = cfgRegistry.getConfig(appId, SuppressionConfig.class); | ||
683 | + reconfigureSuppressionRules(cfg); | ||
684 | + log.trace("Network config reconfigured"); | ||
685 | + } | ||
686 | + } | ||
687 | + } | ||
639 | } | 688 | } | ... | ... |
1 | +/* | ||
2 | + * Copyright 2014-2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.provider.lldp.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.core.JsonProcessingException; | ||
19 | +import com.fasterxml.jackson.databind.JsonNode; | ||
20 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
21 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
22 | +import com.google.common.collect.ImmutableList; | ||
23 | +import com.google.common.collect.ImmutableMap; | ||
24 | +import com.google.common.collect.ImmutableSet; | ||
25 | +import com.google.common.collect.Maps; | ||
26 | + | ||
27 | +import org.onosproject.core.ApplicationId; | ||
28 | +import org.onosproject.net.Device; | ||
29 | +import org.onosproject.net.DeviceId; | ||
30 | +import org.onosproject.net.config.Config; | ||
31 | +import org.slf4j.Logger; | ||
32 | + | ||
33 | +import java.io.IOException; | ||
34 | +import java.util.Iterator; | ||
35 | +import java.util.List; | ||
36 | +import java.util.Map; | ||
37 | +import java.util.Set; | ||
38 | +import static org.onosproject.provider.lldp.impl.LldpLinkProvider.DEFAULT_RULES; | ||
39 | +import static org.slf4j.LoggerFactory.getLogger; | ||
40 | + | ||
41 | +/** | ||
42 | + * LLDP suppression config class. | ||
43 | + */ | ||
44 | +public class SuppressionConfig extends Config<ApplicationId> { | ||
45 | + private static final String DEVICE_IDS = "deviceIds"; | ||
46 | + private static final String DEVICE_TYPES = "deviceTypes"; | ||
47 | + private static final String ANNOTATION = "annotation"; | ||
48 | + | ||
49 | + private static final ObjectMapper MAPPER = new ObjectMapper(); | ||
50 | + private static final List<DeviceId> DEFAULT_DEVICE_IDS | ||
51 | + = ImmutableList.copyOf(DEFAULT_RULES.getSuppressedDevice()); | ||
52 | + private static final List<Device.Type> DEFAULT_DEVICE_TYPES | ||
53 | + = ImmutableList.copyOf(DEFAULT_RULES.getSuppressedDeviceType()); | ||
54 | + | ||
55 | + private final Logger log = getLogger(getClass()); | ||
56 | + | ||
57 | + /** | ||
58 | + * Returns device IDs on which LLDP is suppressed. | ||
59 | + * | ||
60 | + * @return Set of DeviceId objects | ||
61 | + */ | ||
62 | + @Deprecated | ||
63 | + public Set<DeviceId> deviceIds() { | ||
64 | + return ImmutableSet.copyOf(getList(DEVICE_IDS, DeviceId::deviceId, DEFAULT_DEVICE_IDS)); | ||
65 | + } | ||
66 | + | ||
67 | + /** | ||
68 | + * Sets device IDs on which LLDP is suppressed. | ||
69 | + * | ||
70 | + * @param deviceIds new set of device IDs; null to clear | ||
71 | + * @return self | ||
72 | + */ | ||
73 | + @Deprecated | ||
74 | + public SuppressionConfig deviceIds(Set<DeviceId> deviceIds) { | ||
75 | + return (SuppressionConfig) setOrClear(DEVICE_IDS, deviceIds); | ||
76 | + } | ||
77 | + | ||
78 | + /** | ||
79 | + * Returns types of devices on which LLDP is suppressed. | ||
80 | + * | ||
81 | + * @return set of device types | ||
82 | + */ | ||
83 | + public Set<Device.Type> deviceTypes() { | ||
84 | + return ImmutableSet.copyOf(getList(DEVICE_TYPES, Device.Type::valueOf, DEFAULT_DEVICE_TYPES)); | ||
85 | + } | ||
86 | + | ||
87 | + /** | ||
88 | + * Sets types of devices on which LLDP is suppressed. | ||
89 | + * | ||
90 | + * @param deviceTypes new set of device types; null to clear | ||
91 | + * @return self | ||
92 | + */ | ||
93 | + public SuppressionConfig deviceTypes(Set<Device.Type> deviceTypes) { | ||
94 | + return (SuppressionConfig) setOrClear(DEVICE_TYPES, deviceTypes); | ||
95 | + } | ||
96 | + | ||
97 | + /** | ||
98 | + * Returns annotation of Ports on which LLDP is suppressed. | ||
99 | + * | ||
100 | + * @return key-value pairs of annotation | ||
101 | + */ | ||
102 | + public Map<String, String> annotation() { | ||
103 | + ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); | ||
104 | + | ||
105 | + String jsonAnnotation = get(ANNOTATION, null); | ||
106 | + if (jsonAnnotation == null || jsonAnnotation.isEmpty()) { | ||
107 | + return ImmutableMap.of(); | ||
108 | + } | ||
109 | + | ||
110 | + JsonNode annotationNode; | ||
111 | + try { | ||
112 | + annotationNode = MAPPER.readTree(jsonAnnotation); | ||
113 | + } catch (IOException e) { | ||
114 | + log.error("Failed to read JSON tree from: {}", jsonAnnotation); | ||
115 | + return ImmutableMap.of(); | ||
116 | + } | ||
117 | + | ||
118 | + if (annotationNode.isObject()) { | ||
119 | + ObjectNode obj = (ObjectNode) annotationNode; | ||
120 | + Iterator<Map.Entry<String, JsonNode>> it = obj.fields(); | ||
121 | + while (it.hasNext()) { | ||
122 | + Map.Entry<String, JsonNode> entry = it.next(); | ||
123 | + final String key = entry.getKey(); | ||
124 | + final JsonNode value = entry.getValue(); | ||
125 | + | ||
126 | + if (value.isValueNode()) { | ||
127 | + if (value.isNull()) { | ||
128 | + builder.put(key, SuppressionRules.ANY_VALUE); | ||
129 | + } else { | ||
130 | + builder.put(key, value.asText()); | ||
131 | + } | ||
132 | + } else { | ||
133 | + log.warn("Encountered unexpected JSON field {} for annotation", entry); | ||
134 | + } | ||
135 | + } | ||
136 | + } else { | ||
137 | + log.error("Encountered unexpected JSONNode {} for annotation", annotationNode); | ||
138 | + return ImmutableMap.of(); | ||
139 | + } | ||
140 | + | ||
141 | + return builder.build(); | ||
142 | + } | ||
143 | + | ||
144 | + /** | ||
145 | + * Sets annotation of Ports on which LLDP is suppressed. | ||
146 | + * | ||
147 | + * @param annotation new key-value pair of annotation; null to clear | ||
148 | + * @return self | ||
149 | + */ | ||
150 | + public SuppressionConfig annotation(Map<String, String> annotation) { | ||
151 | + | ||
152 | + // ANY_VALUE should be null in JSON | ||
153 | + Map<String, String> config = Maps.transformValues(annotation, | ||
154 | + v -> (v == SuppressionRules.ANY_VALUE) ? null : v); | ||
155 | + | ||
156 | + String jsonAnnotation = null; | ||
157 | + | ||
158 | + try { | ||
159 | + // TODO Store annotation as a Map instead of a String (which needs NetworkConfigRegistry modification) | ||
160 | + jsonAnnotation = MAPPER.writeValueAsString(config); | ||
161 | + } catch (JsonProcessingException e) { | ||
162 | + log.error("Failed to write JSON from: {}", annotation); | ||
163 | + } | ||
164 | + | ||
165 | + return (SuppressionConfig) setOrClear(ANNOTATION, jsonAnnotation); | ||
166 | + } | ||
167 | +} |
... | @@ -18,6 +18,7 @@ package org.onosproject.provider.lldp.impl; | ... | @@ -18,6 +18,7 @@ package org.onosproject.provider.lldp.impl; |
18 | 18 | ||
19 | import java.util.Map; | 19 | import java.util.Map; |
20 | import java.util.Map.Entry; | 20 | import java.util.Map.Entry; |
21 | +import java.util.Objects; | ||
21 | import java.util.Set; | 22 | import java.util.Set; |
22 | 23 | ||
23 | import org.onosproject.net.Annotations; | 24 | import org.onosproject.net.Annotations; |
... | @@ -28,6 +29,7 @@ import org.onosproject.net.Port; | ... | @@ -28,6 +29,7 @@ import org.onosproject.net.Port; |
28 | 29 | ||
29 | import com.google.common.collect.ImmutableMap; | 30 | import com.google.common.collect.ImmutableMap; |
30 | import com.google.common.collect.ImmutableSet; | 31 | import com.google.common.collect.ImmutableSet; |
32 | +import com.google.common.base.MoreObjects; | ||
31 | 33 | ||
32 | public class SuppressionRules { | 34 | public class SuppressionRules { |
33 | 35 | ||
... | @@ -103,4 +105,34 @@ public class SuppressionRules { | ... | @@ -103,4 +105,34 @@ public class SuppressionRules { |
103 | Map<String, String> getSuppressedAnnotation() { | 105 | Map<String, String> getSuppressedAnnotation() { |
104 | return suppressedAnnotation; | 106 | return suppressedAnnotation; |
105 | } | 107 | } |
108 | + | ||
109 | + @Override | ||
110 | + public int hashCode() { | ||
111 | + return Objects.hash(suppressedDevice, | ||
112 | + suppressedDeviceType, | ||
113 | + suppressedAnnotation); | ||
114 | + } | ||
115 | + | ||
116 | + @Override | ||
117 | + public boolean equals(Object object) { | ||
118 | + if (object != null && getClass() == object.getClass()) { | ||
119 | + SuppressionRules that = (SuppressionRules) object; | ||
120 | + return Objects.equals(this.suppressedDevice, | ||
121 | + that.suppressedDevice) | ||
122 | + && Objects.equals(this.suppressedDeviceType, | ||
123 | + that.suppressedDeviceType) | ||
124 | + && Objects.equals(this.suppressedAnnotation, | ||
125 | + that.suppressedAnnotation); | ||
126 | + } | ||
127 | + return false; | ||
128 | + } | ||
129 | + | ||
130 | + @Override | ||
131 | + public String toString() { | ||
132 | + return MoreObjects.toStringHelper(this) | ||
133 | + .add("suppressedDevice", suppressedDevice) | ||
134 | + .add("suppressedDeviceType", suppressedDeviceType) | ||
135 | + .add("suppressedAnnotation", suppressedAnnotation) | ||
136 | + .toString(); | ||
137 | + } | ||
106 | } | 138 | } | ... | ... |
providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionRulesStore.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-2015 Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.provider.lldp.impl; | ||
17 | - | ||
18 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
19 | -import static org.slf4j.LoggerFactory.getLogger; | ||
20 | - | ||
21 | -import com.fasterxml.jackson.core.JsonEncoding; | ||
22 | -import com.fasterxml.jackson.core.JsonFactory; | ||
23 | -import com.fasterxml.jackson.databind.JsonNode; | ||
24 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
25 | -import com.fasterxml.jackson.databind.node.ArrayNode; | ||
26 | -import com.fasterxml.jackson.databind.node.ObjectNode; | ||
27 | - | ||
28 | -import org.onosproject.net.Device; | ||
29 | -import org.onosproject.net.DeviceId; | ||
30 | -import org.slf4j.Logger; | ||
31 | - | ||
32 | -import java.io.File; | ||
33 | -import java.io.IOException; | ||
34 | -import java.util.EnumSet; | ||
35 | -import java.util.HashMap; | ||
36 | -import java.util.HashSet; | ||
37 | -import java.util.Iterator; | ||
38 | -import java.util.Map; | ||
39 | -import java.util.Map.Entry; | ||
40 | -import java.util.Set; | ||
41 | - | ||
42 | -/* | ||
43 | - * JSON file example | ||
44 | - * | ||
45 | - | ||
46 | -{ | ||
47 | - "deviceId" : [ "of:2222000000000000" ], | ||
48 | - "deviceType" : [ "ROADM" ], | ||
49 | - "annotation" : { "no-lldp" : null, "sendLLDP" : "false" } | ||
50 | -} | ||
51 | - */ | ||
52 | - | ||
53 | -/** | ||
54 | - * Allows for reading and writing LLDP suppression definition as a JSON file. | ||
55 | - */ | ||
56 | -public class SuppressionRulesStore { | ||
57 | - | ||
58 | - private static final String DEVICE_ID = "deviceId"; | ||
59 | - private static final String DEVICE_TYPE = "deviceType"; | ||
60 | - private static final String ANNOTATION = "annotation"; | ||
61 | - | ||
62 | - private final Logger log = getLogger(getClass()); | ||
63 | - | ||
64 | - private final File file; | ||
65 | - | ||
66 | - /** | ||
67 | - * Creates a reader/writer of the LLDP suppression definition file. | ||
68 | - * | ||
69 | - * @param filePath location of the definition file | ||
70 | - */ | ||
71 | - public SuppressionRulesStore(String filePath) { | ||
72 | - file = new File(filePath); | ||
73 | - } | ||
74 | - | ||
75 | - /** | ||
76 | - * Creates a reader/writer of the LLDP suppression definition file. | ||
77 | - * | ||
78 | - * @param file definition file | ||
79 | - */ | ||
80 | - public SuppressionRulesStore(File file) { | ||
81 | - this.file = checkNotNull(file); | ||
82 | - } | ||
83 | - | ||
84 | - /** | ||
85 | - * Returns SuppressionRules. | ||
86 | - * | ||
87 | - * @return SuppressionRules | ||
88 | - * @throws IOException if error occurred while reading the data | ||
89 | - */ | ||
90 | - public SuppressionRules read() throws IOException { | ||
91 | - final Set<DeviceId> suppressedDevice = new HashSet<>(); | ||
92 | - final EnumSet<Device.Type> suppressedDeviceType = EnumSet.noneOf(Device.Type.class); | ||
93 | - final Map<String, String> suppressedAnnotation = new HashMap<>(); | ||
94 | - | ||
95 | - ObjectMapper mapper = new ObjectMapper(); | ||
96 | - ObjectNode root = (ObjectNode) mapper.readTree(file); | ||
97 | - | ||
98 | - for (JsonNode deviceId : root.get(DEVICE_ID)) { | ||
99 | - if (deviceId.isTextual()) { | ||
100 | - suppressedDevice.add(DeviceId.deviceId(deviceId.asText())); | ||
101 | - } else { | ||
102 | - log.warn("Encountered unexpected JSONNode {} for deviceId", deviceId); | ||
103 | - } | ||
104 | - } | ||
105 | - | ||
106 | - for (JsonNode deviceType : root.get(DEVICE_TYPE)) { | ||
107 | - if (deviceType.isTextual()) { | ||
108 | - suppressedDeviceType.add(Device.Type.valueOf(deviceType.asText())); | ||
109 | - } else { | ||
110 | - log.warn("Encountered unexpected JSONNode {} for deviceType", deviceType); | ||
111 | - } | ||
112 | - } | ||
113 | - | ||
114 | - JsonNode annotation = root.get(ANNOTATION); | ||
115 | - if (annotation.isObject()) { | ||
116 | - ObjectNode obj = (ObjectNode) annotation; | ||
117 | - Iterator<Entry<String, JsonNode>> it = obj.fields(); | ||
118 | - while (it.hasNext()) { | ||
119 | - Entry<String, JsonNode> entry = it.next(); | ||
120 | - final String key = entry.getKey(); | ||
121 | - final JsonNode value = entry.getValue(); | ||
122 | - | ||
123 | - if (value.isValueNode()) { | ||
124 | - if (value.isNull()) { | ||
125 | - suppressedAnnotation.put(key, SuppressionRules.ANY_VALUE); | ||
126 | - } else { | ||
127 | - suppressedAnnotation.put(key, value.asText()); | ||
128 | - } | ||
129 | - } else { | ||
130 | - log.warn("Encountered unexpected JSON field {} for annotation", entry); | ||
131 | - } | ||
132 | - } | ||
133 | - } else { | ||
134 | - log.warn("Encountered unexpected JSONNode {} for annotation", annotation); | ||
135 | - } | ||
136 | - | ||
137 | - return new SuppressionRules(suppressedDevice, | ||
138 | - suppressedDeviceType, | ||
139 | - suppressedAnnotation); | ||
140 | - } | ||
141 | - | ||
142 | - /** | ||
143 | - * Writes the given SuppressionRules. | ||
144 | - * | ||
145 | - * @param rules SuppressionRules | ||
146 | - * @throws IOException if error occurred while writing the data | ||
147 | - */ | ||
148 | - public void write(SuppressionRules rules) throws IOException { | ||
149 | - ObjectMapper mapper = new ObjectMapper(); | ||
150 | - ObjectNode root = mapper.createObjectNode(); | ||
151 | - ArrayNode deviceIds = mapper.createArrayNode(); | ||
152 | - ArrayNode deviceTypes = mapper.createArrayNode(); | ||
153 | - ObjectNode annotations = mapper.createObjectNode(); | ||
154 | - root.set(DEVICE_ID, deviceIds); | ||
155 | - root.set(DEVICE_TYPE, deviceTypes); | ||
156 | - root.set(ANNOTATION, annotations); | ||
157 | - | ||
158 | - rules.getSuppressedDevice() | ||
159 | - .forEach(deviceId -> deviceIds.add(deviceId.toString())); | ||
160 | - | ||
161 | - rules.getSuppressedDeviceType() | ||
162 | - .forEach(type -> deviceTypes.add(type.toString())); | ||
163 | - | ||
164 | - rules.getSuppressedAnnotation().forEach((key, value) -> { | ||
165 | - if (value == SuppressionRules.ANY_VALUE) { | ||
166 | - annotations.putNull(key); | ||
167 | - } else { | ||
168 | - annotations.put(key, value); | ||
169 | - } | ||
170 | - }); | ||
171 | - mapper.writeTree(new JsonFactory().createGenerator(file, JsonEncoding.UTF8), | ||
172 | - root); | ||
173 | - } | ||
174 | -} |
... | @@ -15,8 +15,11 @@ | ... | @@ -15,8 +15,11 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.provider.lldp.impl; | 16 | package org.onosproject.provider.lldp.impl; |
17 | 17 | ||
18 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
18 | import com.google.common.collect.ArrayListMultimap; | 19 | import com.google.common.collect.ArrayListMultimap; |
19 | import com.google.common.collect.ImmutableList; | 20 | import com.google.common.collect.ImmutableList; |
21 | +import com.google.common.collect.ImmutableMap; | ||
22 | +import com.google.common.collect.ImmutableSet; | ||
20 | import com.google.common.collect.Lists; | 23 | import com.google.common.collect.Lists; |
21 | import com.google.common.collect.Maps; | 24 | import com.google.common.collect.Maps; |
22 | import org.junit.After; | 25 | import org.junit.After; |
... | @@ -43,6 +46,11 @@ import org.onosproject.net.DeviceId; | ... | @@ -43,6 +46,11 @@ import org.onosproject.net.DeviceId; |
43 | import org.onosproject.net.MastershipRole; | 46 | import org.onosproject.net.MastershipRole; |
44 | import org.onosproject.net.Port; | 47 | import org.onosproject.net.Port; |
45 | import org.onosproject.net.PortNumber; | 48 | import org.onosproject.net.PortNumber; |
49 | +import org.onosproject.net.config.Config; | ||
50 | +import org.onosproject.net.config.ConfigApplyDelegate; | ||
51 | +import org.onosproject.net.config.NetworkConfigEvent; | ||
52 | +import org.onosproject.net.config.NetworkConfigListener; | ||
53 | +import org.onosproject.net.config.NetworkConfigRegistryAdapter; | ||
46 | import org.onosproject.net.device.DeviceEvent; | 54 | import org.onosproject.net.device.DeviceEvent; |
47 | import org.onosproject.net.device.DeviceListener; | 55 | import org.onosproject.net.device.DeviceListener; |
48 | import org.onosproject.net.device.DeviceServiceAdapter; | 56 | import org.onosproject.net.device.DeviceServiceAdapter; |
... | @@ -62,15 +70,25 @@ import org.onosproject.net.provider.AbstractProviderService; | ... | @@ -62,15 +70,25 @@ import org.onosproject.net.provider.AbstractProviderService; |
62 | import org.onosproject.net.provider.ProviderId; | 70 | import org.onosproject.net.provider.ProviderId; |
63 | 71 | ||
64 | import java.nio.ByteBuffer; | 72 | import java.nio.ByteBuffer; |
65 | -import java.util.Collections; | ||
66 | import java.util.HashMap; | 73 | import java.util.HashMap; |
74 | +import java.util.HashSet; | ||
67 | import java.util.List; | 75 | import java.util.List; |
68 | import java.util.Map; | 76 | import java.util.Map; |
69 | import java.util.Set; | 77 | import java.util.Set; |
78 | +import java.util.Collections; | ||
70 | import java.util.concurrent.CompletableFuture; | 79 | import java.util.concurrent.CompletableFuture; |
71 | 80 | ||
72 | -import static org.easymock.EasyMock.*; | 81 | +import static org.easymock.EasyMock.createMock; |
73 | -import static org.junit.Assert.*; | 82 | +import static org.easymock.EasyMock.expect; |
83 | +import static org.easymock.EasyMock.replay; | ||
84 | + | ||
85 | +import static org.junit.Assert.assertNull; | ||
86 | +import static org.junit.Assert.assertNotNull; | ||
87 | +import static org.junit.Assert.assertEquals; | ||
88 | +import static org.junit.Assert.assertTrue; | ||
89 | +import static org.onosproject.provider.lldp.impl.LldpLinkProvider.DEFAULT_RULES; | ||
90 | +import static org.junit.Assert.assertFalse; | ||
91 | + | ||
74 | 92 | ||
75 | public class LldpLinkProviderTest { | 93 | public class LldpLinkProviderTest { |
76 | 94 | ||
... | @@ -89,18 +107,23 @@ public class LldpLinkProviderTest { | ... | @@ -89,18 +107,23 @@ public class LldpLinkProviderTest { |
89 | private final TestPacketService packetService = new TestPacketService(); | 107 | private final TestPacketService packetService = new TestPacketService(); |
90 | private final TestDeviceService deviceService = new TestDeviceService(); | 108 | private final TestDeviceService deviceService = new TestDeviceService(); |
91 | private final TestMasterShipService masterService = new TestMasterShipService(); | 109 | private final TestMasterShipService masterService = new TestMasterShipService(); |
110 | + private final TestNetworkConfigRegistry configRegistry = new TestNetworkConfigRegistry(); | ||
92 | 111 | ||
93 | private CoreService coreService; | 112 | private CoreService coreService; |
94 | private TestLinkProviderService providerService; | 113 | private TestLinkProviderService providerService; |
95 | 114 | ||
96 | private PacketProcessor testProcessor; | 115 | private PacketProcessor testProcessor; |
97 | private DeviceListener deviceListener; | 116 | private DeviceListener deviceListener; |
117 | + private NetworkConfigListener configListener; | ||
98 | 118 | ||
99 | private ApplicationId appId = | 119 | private ApplicationId appId = |
100 | new DefaultApplicationId(100, "org.onosproject.provider.lldp"); | 120 | new DefaultApplicationId(100, "org.onosproject.provider.lldp"); |
101 | 121 | ||
122 | + private TestSuppressionConfig cfg; | ||
123 | + | ||
102 | @Before | 124 | @Before |
103 | public void setUp() { | 125 | public void setUp() { |
126 | + cfg = new TestSuppressionConfig(); | ||
104 | coreService = createMock(CoreService.class); | 127 | coreService = createMock(CoreService.class); |
105 | expect(coreService.registerApplication(appId.name())) | 128 | expect(coreService.registerApplication(appId.name())) |
106 | .andReturn(appId).anyTimes(); | 129 | .andReturn(appId).anyTimes(); |
... | @@ -108,6 +131,7 @@ public class LldpLinkProviderTest { | ... | @@ -108,6 +131,7 @@ public class LldpLinkProviderTest { |
108 | 131 | ||
109 | provider.cfgService = new ComponentConfigAdapter(); | 132 | provider.cfgService = new ComponentConfigAdapter(); |
110 | provider.coreService = coreService; | 133 | provider.coreService = coreService; |
134 | + provider.cfgRegistry = configRegistry; | ||
111 | 135 | ||
112 | provider.deviceService = deviceService; | 136 | provider.deviceService = deviceService; |
113 | provider.linkService = linkService; | 137 | provider.linkService = linkService; |
... | @@ -151,6 +175,7 @@ public class LldpLinkProviderTest { | ... | @@ -151,6 +175,7 @@ public class LldpLinkProviderTest { |
151 | */ | 175 | */ |
152 | @Test | 176 | @Test |
153 | public void switchSuppressed() { | 177 | public void switchSuppressed() { |
178 | + | ||
154 | // add device to stub DeviceService | 179 | // add device to stub DeviceService |
155 | deviceService.putDevice(device(DID3)); | 180 | deviceService.putDevice(device(DID3)); |
156 | deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); | 181 | deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); |
... | @@ -163,7 +188,11 @@ public class LldpLinkProviderTest { | ... | @@ -163,7 +188,11 @@ public class LldpLinkProviderTest { |
163 | .build())); | 188 | .build())); |
164 | deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3)); | 189 | deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3)); |
165 | 190 | ||
166 | - assertTrue("Links on suppressed Device was expected to vanish.", vanishedDpid(DID3)); | 191 | + // discovery on device is expected to be gone or stopped |
192 | + LinkDiscovery linkDiscovery = provider.discoverers.get(DID3); | ||
193 | + if (linkDiscovery != null) { | ||
194 | + assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped()); | ||
195 | + } | ||
167 | } | 196 | } |
168 | 197 | ||
169 | @Test | 198 | @Test |
... | @@ -201,7 +230,7 @@ public class LldpLinkProviderTest { | ... | @@ -201,7 +230,7 @@ public class LldpLinkProviderTest { |
201 | * Checks that discovery on reconfigured switch are properly restarted. | 230 | * Checks that discovery on reconfigured switch are properly restarted. |
202 | */ | 231 | */ |
203 | @Test | 232 | @Test |
204 | - public void portSuppressedByDeviceConfig() { | 233 | + public void portSuppressedByDeviceAnnotationConfig() { |
205 | 234 | ||
206 | /// When Device is configured with suppression:ON, Port also is same | 235 | /// When Device is configured with suppression:ON, Port also is same |
207 | 236 | ||
... | @@ -237,10 +266,91 @@ public class LldpLinkProviderTest { | ... | @@ -237,10 +266,91 @@ public class LldpLinkProviderTest { |
237 | } | 266 | } |
238 | 267 | ||
239 | /** | 268 | /** |
269 | + * Checks that discovery on reconfigured switch are properly restarted. | ||
270 | + */ | ||
271 | + @Test | ||
272 | + public void portSuppressedByDeviceIdConfig() { | ||
273 | + | ||
274 | + /// When Device is configured without suppression:OFF, | ||
275 | + /// Port should be included for discovery | ||
276 | + | ||
277 | + // add device in stub DeviceService without suppression configured | ||
278 | + deviceService.putDevice(device(DID3)); | ||
279 | + deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); | ||
280 | + | ||
281 | + // non-suppressed port added to suppressed device | ||
282 | + final long portno3 = 3L; | ||
283 | + deviceService.putPorts(DID3, port(DID3, portno3, true)); | ||
284 | + deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true))); | ||
285 | + | ||
286 | + // discovery should succeed | ||
287 | + assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped()); | ||
288 | + assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3)); | ||
289 | + | ||
290 | + // add suppression rule for "deviceId: "of:0000000000000003"" | ||
291 | + provider.updateRules(new SuppressionRules(ImmutableSet.of(DID3), | ||
292 | + ImmutableSet.of(), | ||
293 | + ImmutableMap.of())); | ||
294 | + | ||
295 | + /// When Device is reconfigured with suppression:ON, Port also is same | ||
296 | + | ||
297 | + // update device in stub DeviceService with suppression configured | ||
298 | + deviceService.putDevice(device(DID3)); | ||
299 | + // update the Port in stub DeviceService. (Port has reference to Device) | ||
300 | + deviceService.putPorts(DID3, port(DID3, portno3, true)); | ||
301 | + deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3)); | ||
302 | + | ||
303 | + // discovery on device is expected to be stopped | ||
304 | + LinkDiscovery linkDiscovery = provider.discoverers.get(DID3); | ||
305 | + if (linkDiscovery != null) { | ||
306 | + assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped()); | ||
307 | + } | ||
308 | + } | ||
309 | + | ||
310 | + /** | ||
311 | + * Checks that discovery on reconfigured switch are properly restarted. | ||
312 | + */ | ||
313 | + @Test | ||
314 | + public void portSuppressedByDeviceTypeConfig() { | ||
315 | + | ||
316 | + /// When Device is configured without suppression:OFF, | ||
317 | + /// Port should be included for discovery | ||
318 | + | ||
319 | + // add device in stub DeviceService without suppression configured | ||
320 | + deviceService.putDevice(device(DID1, Device.Type.SWITCH)); | ||
321 | + deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); | ||
322 | + | ||
323 | + // non-suppressed port added to suppressed device | ||
324 | + final long portno3 = 3L; | ||
325 | + deviceService.putPorts(DID1, port(DID1, portno3, true)); | ||
326 | + deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, portno3, true))); | ||
327 | + | ||
328 | + // add device in stub DeviceService with suppression configured | ||
329 | + deviceService.putDevice(device(DID2, Device.Type.ROADM)); | ||
330 | + deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2)); | ||
331 | + | ||
332 | + // non-suppressed port added to suppressed device | ||
333 | + final long portno4 = 4L; | ||
334 | + deviceService.putPorts(DID2, port(DID2, portno4, true)); | ||
335 | + deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, portno4, true))); | ||
336 | + | ||
337 | + // discovery should succeed for this device | ||
338 | + assertFalse("Discoverer is expected to start", provider.discoverers.get(DID1).isStopped()); | ||
339 | + assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID1).containsPort(portno3)); | ||
340 | + | ||
341 | + // discovery on device is expected to be stopped for this device | ||
342 | + LinkDiscovery linkDiscovery = provider.discoverers.get(DID2); | ||
343 | + if (linkDiscovery != null) { | ||
344 | + assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped()); | ||
345 | + } | ||
346 | + } | ||
347 | + | ||
348 | + /** | ||
240 | * Checks that discovery on reconfigured port are properly restarted. | 349 | * Checks that discovery on reconfigured port are properly restarted. |
241 | */ | 350 | */ |
242 | @Test | 351 | @Test |
243 | public void portSuppressedByPortConfig() { | 352 | public void portSuppressedByPortConfig() { |
353 | + | ||
244 | // add device in stub DeviceService without suppression configured | 354 | // add device in stub DeviceService without suppression configured |
245 | deviceService.putDevice(device(DID3)); | 355 | deviceService.putDevice(device(DID3)); |
246 | deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); | 356 | deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); |
... | @@ -314,6 +424,11 @@ public class LldpLinkProviderTest { | ... | @@ -314,6 +424,11 @@ public class LldpLinkProviderTest { |
314 | "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId()); | 424 | "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId()); |
315 | } | 425 | } |
316 | 426 | ||
427 | + private DefaultDevice device(DeviceId did, Device.Type type) { | ||
428 | + return new DefaultDevice(ProviderId.NONE, did, type, | ||
429 | + "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId()); | ||
430 | + } | ||
431 | + | ||
317 | private DefaultDevice device(DeviceId did, Annotations annotations) { | 432 | private DefaultDevice device(DeviceId did, Annotations annotations) { |
318 | return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH, | 433 | return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH, |
319 | "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations); | 434 | "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations); |
... | @@ -367,6 +482,127 @@ public class LldpLinkProviderTest { | ... | @@ -367,6 +482,127 @@ public class LldpLinkProviderTest { |
367 | } | 482 | } |
368 | 483 | ||
369 | 484 | ||
485 | + @Test | ||
486 | + public void addDeviceIdRule() { | ||
487 | + DeviceId deviceId1 = DeviceId.deviceId("of:0000000000000001"); | ||
488 | + DeviceId deviceId2 = DeviceId.deviceId("of:0000000000000002"); | ||
489 | + Set<DeviceId> deviceIds = new HashSet<>(); | ||
490 | + | ||
491 | + deviceIds.add(deviceId1); | ||
492 | + cfg.deviceIds(deviceIds); | ||
493 | + | ||
494 | + configEvent(NetworkConfigEvent.Type.CONFIG_ADDED); | ||
495 | + | ||
496 | + assertTrue(provider.rules().getSuppressedDevice().contains(deviceId1)); | ||
497 | + assertFalse(provider.rules().getSuppressedDevice().contains(deviceId2)); | ||
498 | + } | ||
499 | + | ||
500 | + @Test | ||
501 | + public void updateDeviceIdRule() { | ||
502 | + DeviceId deviceId1 = DeviceId.deviceId("of:0000000000000001"); | ||
503 | + DeviceId deviceId2 = DeviceId.deviceId("of:0000000000000002"); | ||
504 | + Set<DeviceId> deviceIds = new HashSet<>(); | ||
505 | + | ||
506 | + deviceIds.add(deviceId1); | ||
507 | + cfg.deviceIds(deviceIds); | ||
508 | + | ||
509 | + configEvent(NetworkConfigEvent.Type.CONFIG_ADDED); | ||
510 | + | ||
511 | + deviceIds.add(deviceId2); | ||
512 | + cfg.deviceIds(deviceIds); | ||
513 | + | ||
514 | + configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED); | ||
515 | + | ||
516 | + assertTrue(provider.rules().getSuppressedDevice().contains(deviceId1)); | ||
517 | + assertTrue(provider.rules().getSuppressedDevice().contains(deviceId2)); | ||
518 | + } | ||
519 | + | ||
520 | + @Test | ||
521 | + public void addDeviceTypeRule() { | ||
522 | + Device.Type deviceType1 = Device.Type.ROADM; | ||
523 | + Device.Type deviceType2 = Device.Type.SWITCH; | ||
524 | + | ||
525 | + Set<Device.Type> deviceTypes = new HashSet<>(); | ||
526 | + deviceTypes.add(deviceType1); | ||
527 | + | ||
528 | + cfg.deviceTypes(deviceTypes); | ||
529 | + | ||
530 | + configEvent(NetworkConfigEvent.Type.CONFIG_ADDED); | ||
531 | + | ||
532 | + assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1)); | ||
533 | + assertFalse(provider.rules().getSuppressedDeviceType().contains(deviceType2)); | ||
534 | + } | ||
535 | + | ||
536 | + @Test | ||
537 | + public void updateDeviceTypeRule() { | ||
538 | + Device.Type deviceType1 = Device.Type.ROADM; | ||
539 | + Device.Type deviceType2 = Device.Type.SWITCH; | ||
540 | + Set<Device.Type> deviceTypes = new HashSet<>(); | ||
541 | + | ||
542 | + deviceTypes.add(deviceType1); | ||
543 | + cfg.deviceTypes(deviceTypes); | ||
544 | + | ||
545 | + configEvent(NetworkConfigEvent.Type.CONFIG_ADDED); | ||
546 | + | ||
547 | + deviceTypes.add(deviceType2); | ||
548 | + cfg.deviceTypes(deviceTypes); | ||
549 | + | ||
550 | + configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED); | ||
551 | + | ||
552 | + assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1)); | ||
553 | + assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType2)); | ||
554 | + } | ||
555 | + | ||
556 | + @Test | ||
557 | + public void addAnnotationRule() { | ||
558 | + final String key1 = "key1", key2 = "key2"; | ||
559 | + final String value1 = "value1"; | ||
560 | + | ||
561 | + Map<String, String> annotation = new HashMap<>(); | ||
562 | + annotation.put(key1, value1); | ||
563 | + | ||
564 | + cfg.annotation(annotation); | ||
565 | + | ||
566 | + configEvent(NetworkConfigEvent.Type.CONFIG_ADDED); | ||
567 | + | ||
568 | + assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1)); | ||
569 | + assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1)); | ||
570 | + assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2)); | ||
571 | + } | ||
572 | + | ||
573 | + @Test | ||
574 | + public void updateAnnotationRule() { | ||
575 | + final String key1 = "key1", key2 = "key2"; | ||
576 | + final String value1 = "value1", value2 = "value2"; | ||
577 | + Map<String, String> annotation = new HashMap<>(); | ||
578 | + | ||
579 | + annotation.put(key1, value1); | ||
580 | + cfg.annotation(annotation); | ||
581 | + | ||
582 | + configEvent(NetworkConfigEvent.Type.CONFIG_ADDED); | ||
583 | + | ||
584 | + assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1)); | ||
585 | + assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1)); | ||
586 | + assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2)); | ||
587 | + | ||
588 | + annotation.put(key2, value2); | ||
589 | + cfg.annotation(annotation); | ||
590 | + | ||
591 | + configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED); | ||
592 | + | ||
593 | + assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1)); | ||
594 | + assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1)); | ||
595 | + assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key2)); | ||
596 | + assertEquals(value2, provider.rules().getSuppressedAnnotation().get(key2)); | ||
597 | + } | ||
598 | + | ||
599 | + private void configEvent(NetworkConfigEvent.Type evType) { | ||
600 | + configListener.event(new NetworkConfigEvent(evType, | ||
601 | + appId, | ||
602 | + SuppressionConfig.class)); | ||
603 | + } | ||
604 | + | ||
605 | + | ||
370 | private class TestLinkRegistry implements LinkProviderRegistry { | 606 | private class TestLinkRegistry implements LinkProviderRegistry { |
371 | 607 | ||
372 | @Override | 608 | @Override |
... | @@ -627,4 +863,58 @@ public class LldpLinkProviderTest { | ... | @@ -627,4 +863,58 @@ public class LldpLinkProviderTest { |
627 | 863 | ||
628 | private class TestLinkService extends LinkServiceAdapter { | 864 | private class TestLinkService extends LinkServiceAdapter { |
629 | } | 865 | } |
866 | + | ||
867 | + private final class TestNetworkConfigRegistry | ||
868 | + extends NetworkConfigRegistryAdapter { | ||
869 | + @Override | ||
870 | + public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) { | ||
871 | + ConfigApplyDelegate delegate = config -> { }; | ||
872 | + ObjectMapper mapper = new ObjectMapper(); | ||
873 | + return (C) cfg; | ||
874 | + } | ||
875 | + | ||
876 | + @Override | ||
877 | + public void addListener(NetworkConfigListener listener) { | ||
878 | + configListener = listener; | ||
879 | + } | ||
880 | + } | ||
881 | + | ||
882 | + private final class TestSuppressionConfig extends SuppressionConfig { | ||
883 | + private Set<DeviceId> deviceIds = new HashSet<>(DEFAULT_RULES.getSuppressedDevice()); | ||
884 | + private Set<Device.Type> deviceTypes = new HashSet<>(DEFAULT_RULES.getSuppressedDeviceType()); | ||
885 | + private Map<String, String> annotation = new HashMap<>(DEFAULT_RULES.getSuppressedAnnotation()); | ||
886 | + | ||
887 | + @Override | ||
888 | + public Set<DeviceId> deviceIds() { | ||
889 | + return ImmutableSet.copyOf(deviceIds); | ||
890 | + } | ||
891 | + | ||
892 | + @Override | ||
893 | + public SuppressionConfig deviceIds(Set<DeviceId> deviceIds) { | ||
894 | + this.deviceIds = ImmutableSet.copyOf(deviceIds); | ||
895 | + return this; | ||
896 | + } | ||
897 | + | ||
898 | + @Override | ||
899 | + public Set<Device.Type> deviceTypes() { | ||
900 | + return ImmutableSet.copyOf(deviceTypes); | ||
901 | + } | ||
902 | + | ||
903 | + @Override | ||
904 | + public SuppressionConfig deviceTypes(Set<Device.Type> deviceTypes) { | ||
905 | + this.deviceTypes = ImmutableSet.copyOf(deviceTypes); | ||
906 | + return this; | ||
907 | + } | ||
908 | + | ||
909 | + @Override | ||
910 | + public Map<String, String> annotation() { | ||
911 | + return ImmutableMap.copyOf(annotation); | ||
912 | + } | ||
913 | + | ||
914 | + @Override | ||
915 | + public SuppressionConfig annotation(Map<String, String> annotation) { | ||
916 | + this.annotation = ImmutableMap.copyOf(annotation); | ||
917 | + return this; | ||
918 | + } | ||
919 | + } | ||
630 | } | 920 | } | ... | ... |
providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/SuppressionConfigTest.java
0 → 100644
1 | +package org.onosproject.provider.lldp.impl; | ||
2 | + | ||
3 | +import static org.junit.Assert.*; | ||
4 | + | ||
5 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
6 | +import com.fasterxml.jackson.databind.node.JsonNodeFactory; | ||
7 | +import org.junit.Before; | ||
8 | +import org.junit.Test; | ||
9 | +import org.onosproject.TestApplicationId; | ||
10 | +import org.onosproject.net.Device; | ||
11 | +import org.onosproject.net.DeviceId; | ||
12 | +import org.onosproject.net.config.ConfigApplyDelegate; | ||
13 | + | ||
14 | +import java.util.HashMap; | ||
15 | +import java.util.HashSet; | ||
16 | +import java.util.Map; | ||
17 | +import java.util.Set; | ||
18 | + | ||
19 | +public class SuppressionConfigTest { | ||
20 | + private static final String APP_NAME = "SuppressionConfigTest"; | ||
21 | + private static final TestApplicationId APP_ID = new TestApplicationId(APP_NAME); | ||
22 | + private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId("of:1111000000000000"); | ||
23 | + private static final DeviceId DEVICE_ID_2 = DeviceId.deviceId("of:2222000000000000"); | ||
24 | + private static final Device.Type DEVICE_TYPE_1 = Device.Type.ROADM; | ||
25 | + private static final Device.Type DEVICE_TYPE_2 = Device.Type.FIBER_SWITCH; | ||
26 | + private static final String ANNOTATION_KEY_1 = "no_lldp"; | ||
27 | + private static final String ANNOTATION_VALUE_1 = "true"; | ||
28 | + private static final String ANNOTATION_KEY_2 = "sendLLDP"; | ||
29 | + private static final String ANNOTATION_VALUE_2 = "false"; | ||
30 | + | ||
31 | + private SuppressionConfig cfg; | ||
32 | + | ||
33 | + @Before | ||
34 | + public void setUp() throws Exception { | ||
35 | + ConfigApplyDelegate delegate = config -> { }; | ||
36 | + ObjectMapper mapper = new ObjectMapper(); | ||
37 | + cfg = new SuppressionConfig(); | ||
38 | + cfg.init(APP_ID, LldpLinkProvider.CONFIG_KEY, JsonNodeFactory.instance.objectNode(), mapper, delegate); | ||
39 | + } | ||
40 | + | ||
41 | + @Test | ||
42 | + public void testDeviceIds() { | ||
43 | + Set<DeviceId> inputIds = new HashSet<DeviceId>() { { | ||
44 | + add(DEVICE_ID_1); | ||
45 | + add(DEVICE_ID_2); | ||
46 | + } }; | ||
47 | + | ||
48 | + assertNotNull(cfg.deviceIds(inputIds)); | ||
49 | + | ||
50 | + Set<DeviceId> outputIds = cfg.deviceIds(); | ||
51 | + assertTrue(outputIds.contains(DEVICE_ID_1)); | ||
52 | + assertTrue(outputIds.contains(DEVICE_ID_2)); | ||
53 | + assertEquals(outputIds.size(), 2); | ||
54 | + } | ||
55 | + | ||
56 | + @Test | ||
57 | + public void testDeviceTypes() { | ||
58 | + Set<Device.Type> inputTypes = new HashSet<Device.Type>() { { | ||
59 | + add(DEVICE_TYPE_1); | ||
60 | + add(DEVICE_TYPE_2); | ||
61 | + } }; | ||
62 | + | ||
63 | + assertNotNull(cfg.deviceTypes(inputTypes)); | ||
64 | + | ||
65 | + Set<Device.Type> outputTypes = cfg.deviceTypes(); | ||
66 | + assertTrue(outputTypes.contains(DEVICE_TYPE_1)); | ||
67 | + assertTrue(outputTypes.contains(DEVICE_TYPE_2)); | ||
68 | + assertEquals(outputTypes.size(), 2); | ||
69 | + } | ||
70 | + | ||
71 | + @Test | ||
72 | + public void testDeviceAnnotation() { | ||
73 | + Map<String, String> inputMap = new HashMap<String, String>() { { | ||
74 | + put(ANNOTATION_KEY_1, ANNOTATION_VALUE_1); | ||
75 | + put(ANNOTATION_KEY_2, ANNOTATION_VALUE_2); | ||
76 | + } }; | ||
77 | + | ||
78 | + assertNotNull(cfg.annotation(inputMap)); | ||
79 | + | ||
80 | + Map<String, String> outputMap = cfg.annotation(); | ||
81 | + assertEquals(outputMap.get(ANNOTATION_KEY_1), ANNOTATION_VALUE_1); | ||
82 | + assertEquals(outputMap.get(ANNOTATION_KEY_2), ANNOTATION_VALUE_2); | ||
83 | + assertEquals(outputMap.size(), 2); | ||
84 | + } | ||
85 | + | ||
86 | +} |
1 | -/* | ||
2 | - * Copyright 2014-2015 Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | - | ||
17 | -package org.onosproject.provider.lldp.impl; | ||
18 | - | ||
19 | -import static org.junit.Assert.*; | ||
20 | -import static org.onosproject.net.DeviceId.deviceId; | ||
21 | - | ||
22 | -import java.io.File; | ||
23 | -import java.io.IOException; | ||
24 | -import java.net.URISyntaxException; | ||
25 | -import java.nio.file.Path; | ||
26 | -import java.nio.file.Paths; | ||
27 | - | ||
28 | -import org.junit.Rule; | ||
29 | -import org.junit.Test; | ||
30 | -import org.junit.rules.TemporaryFolder; | ||
31 | -import org.onosproject.net.Device; | ||
32 | - | ||
33 | -import com.google.common.collect.ImmutableMap; | ||
34 | -import com.google.common.collect.ImmutableSet; | ||
35 | -import com.google.common.io.Resources; | ||
36 | - | ||
37 | -public class SuppressionRulesStoreTest { | ||
38 | - | ||
39 | - @Rule | ||
40 | - public TemporaryFolder tempFolder = new TemporaryFolder(); | ||
41 | - | ||
42 | - // "lldp_suppression.json" | ||
43 | - SuppressionRules testData | ||
44 | - = new SuppressionRules(ImmutableSet.of(deviceId("of:2222000000000000")), | ||
45 | - ImmutableSet.of(Device.Type.ROADM), | ||
46 | - ImmutableMap.of("no-lldp", SuppressionRules.ANY_VALUE, | ||
47 | - "sendLLDP", "false")); | ||
48 | - | ||
49 | - private static void assertRulesEqual(SuppressionRules expected, SuppressionRules actual) { | ||
50 | - assertEquals(expected.getSuppressedDevice(), | ||
51 | - actual.getSuppressedDevice()); | ||
52 | - assertEquals(expected.getSuppressedDeviceType(), | ||
53 | - actual.getSuppressedDeviceType()); | ||
54 | - assertEquals(expected.getSuppressedAnnotation(), | ||
55 | - actual.getSuppressedAnnotation()); | ||
56 | - } | ||
57 | - | ||
58 | - @Test | ||
59 | - public void testRead() throws URISyntaxException, IOException { | ||
60 | - Path path = Paths.get(Resources.getResource("lldp_suppression.json").toURI()); | ||
61 | - | ||
62 | - SuppressionRulesStore store = new SuppressionRulesStore(path.toString()); | ||
63 | - | ||
64 | - SuppressionRules rules = store.read(); | ||
65 | - | ||
66 | - assertRulesEqual(testData, rules); | ||
67 | - } | ||
68 | - | ||
69 | - @Test | ||
70 | - public void testWrite() throws IOException { | ||
71 | - File newFile = tempFolder.newFile(); | ||
72 | - SuppressionRulesStore store = new SuppressionRulesStore(newFile); | ||
73 | - store.write(testData); | ||
74 | - | ||
75 | - SuppressionRulesStore reload = new SuppressionRulesStore(newFile); | ||
76 | - SuppressionRules rules = reload.read(); | ||
77 | - | ||
78 | - assertRulesEqual(testData, rules); | ||
79 | - } | ||
80 | -} |
... | @@ -62,5 +62,12 @@ | ... | @@ -62,5 +62,12 @@ |
62 | ] | 62 | ] |
63 | } | 63 | } |
64 | } | 64 | } |
65 | + "org.onosproject.provider.lldp": { | ||
66 | + "suppression": { | ||
67 | + "deviceIds": [ "of:2222000000000000" ], | ||
68 | + "deviceTypes": [ "ROADM" ], | ||
69 | + "annotation": { "no-lldp": null, "sendLLDP" : "false" } | ||
70 | + } | ||
71 | + } | ||
65 | } | 72 | } |
66 | } | 73 | } | ... | ... |
-
Please register or login to post a comment