Committed by
Gerrit Code Review
Devices,hosts, and links can be blocked and kicked off with the network configuration api
Change-Id: I68d427f4886a7b63475df8d35383e2e347946946
Showing
15 changed files
with
555 additions
and
38 deletions
... | @@ -76,6 +76,18 @@ public class DefaultDeviceDescription extends AbstractDescription | ... | @@ -76,6 +76,18 @@ public class DefaultDeviceDescription extends AbstractDescription |
76 | base.chassisId(), annotations); | 76 | base.chassisId(), annotations); |
77 | } | 77 | } |
78 | 78 | ||
79 | + /** | ||
80 | + * Creates a device description using the supplied information. | ||
81 | + * @param base DeviceDescription to basic information (except for type) | ||
82 | + * @param type device type | ||
83 | + * @param annotations Annotations to use. | ||
84 | + */ | ||
85 | + public DefaultDeviceDescription(DeviceDescription base, Type type, SparseAnnotations... annotations) { | ||
86 | + this(base.deviceURI(), type, base.manufacturer(), | ||
87 | + base.hwVersion(), base.swVersion(), base.serialNumber(), | ||
88 | + base.chassisId(), annotations); | ||
89 | + } | ||
90 | + | ||
79 | @Override | 91 | @Override |
80 | public URI deviceURI() { | 92 | public URI deviceURI() { |
81 | return uri; | 93 | return uri; | ... | ... |
... | @@ -39,4 +39,12 @@ public interface LinkAdminService extends LinkService { | ... | @@ -39,4 +39,12 @@ public interface LinkAdminService extends LinkService { |
39 | */ | 39 | */ |
40 | void removeLinks(DeviceId deviceId); | 40 | void removeLinks(DeviceId deviceId); |
41 | 41 | ||
42 | + /** | ||
43 | + * Removes all links between between the specified src and | ||
44 | + * dst connection points. | ||
45 | + * | ||
46 | + * @param src link source | ||
47 | + * @param dst link destination | ||
48 | + */ | ||
49 | + void removeLink(ConnectPoint src, ConnectPoint dst); | ||
42 | } | 50 | } | ... | ... |
... | @@ -59,12 +59,25 @@ | ... | @@ -59,12 +59,25 @@ |
59 | </dependency> | 59 | </dependency> |
60 | 60 | ||
61 | <dependency> | 61 | <dependency> |
62 | + <groupId>org.onosproject</groupId> | ||
63 | + <artifactId>onos-incubator-api</artifactId> | ||
64 | + <scope>test</scope> | ||
65 | + <classifier>tests</classifier> | ||
66 | + <version>${project.version}</version> | ||
67 | + </dependency> | ||
68 | + | ||
69 | + <dependency> | ||
62 | <groupId>org.easymock</groupId> | 70 | <groupId>org.easymock</groupId> |
63 | <artifactId>easymock</artifactId> | 71 | <artifactId>easymock</artifactId> |
64 | <scope>test</scope> | 72 | <scope>test</scope> |
65 | </dependency> | 73 | </dependency> |
66 | 74 | ||
67 | <dependency> | 75 | <dependency> |
76 | + <groupId>org.onosproject</groupId> | ||
77 | + <artifactId>onos-incubator-api</artifactId> | ||
78 | + </dependency> | ||
79 | + | ||
80 | + <dependency> | ||
68 | <groupId>org.apache.felix</groupId> | 81 | <groupId>org.apache.felix</groupId> |
69 | <artifactId>org.apache.felix.scr.annotations</artifactId> | 82 | <artifactId>org.apache.felix.scr.annotations</artifactId> |
70 | </dependency> | 83 | </dependency> | ... | ... |
... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
16 | package org.onosproject.net.device.impl; | 16 | package org.onosproject.net.device.impl; |
17 | 17 | ||
18 | import static com.google.common.base.Preconditions.checkNotNull; | 18 | import static com.google.common.base.Preconditions.checkNotNull; |
19 | +import static com.google.common.base.Preconditions.checkState; | ||
19 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | 20 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; |
20 | import static org.onlab.util.Tools.groupedThreads; | 21 | import static org.onlab.util.Tools.groupedThreads; |
21 | import static org.onosproject.net.MastershipRole.MASTER; | 22 | import static org.onosproject.net.MastershipRole.MASTER; |
... | @@ -45,17 +46,23 @@ import org.onosproject.cluster.NodeId; | ... | @@ -45,17 +46,23 @@ import org.onosproject.cluster.NodeId; |
45 | import org.onosproject.core.Permission; | 46 | import org.onosproject.core.Permission; |
46 | import org.onosproject.event.EventDeliveryService; | 47 | import org.onosproject.event.EventDeliveryService; |
47 | import org.onosproject.event.ListenerRegistry; | 48 | import org.onosproject.event.ListenerRegistry; |
49 | +import org.onosproject.incubator.net.config.NetworkConfigEvent; | ||
50 | +import org.onosproject.incubator.net.config.NetworkConfigListener; | ||
51 | +import org.onosproject.incubator.net.config.NetworkConfigService; | ||
52 | +import org.onosproject.incubator.net.config.basics.BasicDeviceConfig; | ||
48 | import org.onosproject.mastership.MastershipEvent; | 53 | import org.onosproject.mastership.MastershipEvent; |
49 | import org.onosproject.mastership.MastershipListener; | 54 | import org.onosproject.mastership.MastershipListener; |
50 | import org.onosproject.mastership.MastershipService; | 55 | import org.onosproject.mastership.MastershipService; |
51 | import org.onosproject.mastership.MastershipTerm; | 56 | import org.onosproject.mastership.MastershipTerm; |
52 | import org.onosproject.mastership.MastershipTermService; | 57 | import org.onosproject.mastership.MastershipTermService; |
58 | +import org.onosproject.net.DefaultAnnotations; | ||
53 | import org.onosproject.net.Device; | 59 | import org.onosproject.net.Device; |
54 | import org.onosproject.net.Device.Type; | 60 | import org.onosproject.net.Device.Type; |
55 | import org.onosproject.net.DeviceId; | 61 | import org.onosproject.net.DeviceId; |
56 | import org.onosproject.net.MastershipRole; | 62 | import org.onosproject.net.MastershipRole; |
57 | import org.onosproject.net.Port; | 63 | import org.onosproject.net.Port; |
58 | import org.onosproject.net.PortNumber; | 64 | import org.onosproject.net.PortNumber; |
65 | +import org.onosproject.net.SparseAnnotations; | ||
59 | import org.onosproject.net.device.DefaultDeviceDescription; | 66 | import org.onosproject.net.device.DefaultDeviceDescription; |
60 | import org.onosproject.net.device.DefaultPortDescription; | 67 | import org.onosproject.net.device.DefaultPortDescription; |
61 | import org.onosproject.net.device.DeviceAdminService; | 68 | import org.onosproject.net.device.DeviceAdminService; |
... | @@ -104,6 +111,8 @@ public class DeviceManager | ... | @@ -104,6 +111,8 @@ public class DeviceManager |
104 | 111 | ||
105 | private ScheduledExecutorService backgroundService; | 112 | private ScheduledExecutorService backgroundService; |
106 | 113 | ||
114 | + private final NetworkConfigListener networkConfigListener = new InternalNetworkConfigListener(); | ||
115 | + | ||
107 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 116 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
108 | protected DeviceStore store; | 117 | protected DeviceStore store; |
109 | 118 | ||
... | @@ -122,6 +131,11 @@ public class DeviceManager | ... | @@ -122,6 +131,11 @@ public class DeviceManager |
122 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 131 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
123 | protected DeviceClockProviderService deviceClockProviderService; | 132 | protected DeviceClockProviderService deviceClockProviderService; |
124 | 133 | ||
134 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
135 | + protected NetworkConfigService networkConfigService; | ||
136 | + | ||
137 | + | ||
138 | + | ||
125 | @Activate | 139 | @Activate |
126 | public void activate() { | 140 | public void activate() { |
127 | backgroundService = newSingleThreadScheduledExecutor(groupedThreads("onos/device", "manager-background")); | 141 | backgroundService = newSingleThreadScheduledExecutor(groupedThreads("onos/device", "manager-background")); |
... | @@ -130,6 +144,7 @@ public class DeviceManager | ... | @@ -130,6 +144,7 @@ public class DeviceManager |
130 | store.setDelegate(delegate); | 144 | store.setDelegate(delegate); |
131 | eventDispatcher.addSink(DeviceEvent.class, listenerRegistry); | 145 | eventDispatcher.addSink(DeviceEvent.class, listenerRegistry); |
132 | mastershipService.addListener(mastershipListener); | 146 | mastershipService.addListener(mastershipListener); |
147 | + networkConfigService.addListener(networkConfigListener); | ||
133 | 148 | ||
134 | backgroundService.scheduleWithFixedDelay(new Runnable() { | 149 | backgroundService.scheduleWithFixedDelay(new Runnable() { |
135 | 150 | ||
... | @@ -148,7 +163,7 @@ public class DeviceManager | ... | @@ -148,7 +163,7 @@ public class DeviceManager |
148 | @Deactivate | 163 | @Deactivate |
149 | public void deactivate() { | 164 | public void deactivate() { |
150 | backgroundService.shutdown(); | 165 | backgroundService.shutdown(); |
151 | - | 166 | + networkConfigService.removeListener(networkConfigListener); |
152 | store.unsetDelegate(delegate); | 167 | store.unsetDelegate(delegate); |
153 | mastershipService.removeListener(mastershipListener); | 168 | mastershipService.removeListener(mastershipListener); |
154 | eventDispatcher.removeSink(DeviceEvent.class); | 169 | eventDispatcher.removeSink(DeviceEvent.class); |
... | @@ -286,7 +301,8 @@ public class DeviceManager | ... | @@ -286,7 +301,8 @@ public class DeviceManager |
286 | continue; | 301 | continue; |
287 | } | 302 | } |
288 | 303 | ||
289 | - log.info("{} is reachable but did not have a valid role, reasserting", deviceId); | 304 | + log.info("{} is reachable but did not have a valid role, reasserting", |
305 | + deviceId); | ||
290 | 306 | ||
291 | // isReachable but was not MASTER or STANDBY, get a role and apply | 307 | // isReachable but was not MASTER or STANDBY, get a role and apply |
292 | // Note: NONE triggers request to MastershipService | 308 | // Note: NONE triggers request to MastershipService |
... | @@ -319,7 +335,8 @@ public class DeviceManager | ... | @@ -319,7 +335,8 @@ public class DeviceManager |
319 | 335 | ||
320 | DeviceProvider provider = provider(); | 336 | DeviceProvider provider = provider(); |
321 | if (provider == null) { | 337 | if (provider == null) { |
322 | - log.warn("Provider for {} was not found. Cannot apply role {}", deviceId, newRole); | 338 | + log.warn("Provider for {} was not found. Cannot apply role {}", |
339 | + deviceId, newRole); | ||
323 | return false; | 340 | return false; |
324 | } | 341 | } |
325 | provider.roleChanged(deviceId, newRole); | 342 | provider.roleChanged(deviceId, newRole); |
... | @@ -335,8 +352,8 @@ public class DeviceManager | ... | @@ -335,8 +352,8 @@ public class DeviceManager |
335 | checkNotNull(deviceId, DEVICE_ID_NULL); | 352 | checkNotNull(deviceId, DEVICE_ID_NULL); |
336 | checkNotNull(deviceDescription, DEVICE_DESCRIPTION_NULL); | 353 | checkNotNull(deviceDescription, DEVICE_DESCRIPTION_NULL); |
337 | checkValidity(); | 354 | checkValidity(); |
355 | + deviceDescription = validateDevice(deviceDescription, deviceId); | ||
338 | 356 | ||
339 | - log.info("Device {} connected", deviceId); | ||
340 | // check my Role | 357 | // check my Role |
341 | CompletableFuture<MastershipRole> role = mastershipService.requestRoleFor(deviceId); | 358 | CompletableFuture<MastershipRole> role = mastershipService.requestRoleFor(deviceId); |
342 | try { | 359 | try { |
... | @@ -362,16 +379,33 @@ public class DeviceManager | ... | @@ -362,16 +379,33 @@ public class DeviceManager |
362 | deviceClockProviderService.setMastershipTerm(deviceId, term); | 379 | deviceClockProviderService.setMastershipTerm(deviceId, term); |
363 | applyRole(deviceId, MastershipRole.MASTER); | 380 | applyRole(deviceId, MastershipRole.MASTER); |
364 | } | 381 | } |
365 | - | 382 | + DeviceEvent event = store.createOrUpdateDevice(provider().id(), deviceId, |
366 | - DeviceEvent event = store.createOrUpdateDevice(provider().id(), | 383 | + deviceDescription); |
367 | - deviceId, deviceDescription); | ||
368 | - | ||
369 | if (event != null) { | 384 | if (event != null) { |
370 | log.trace("event: {} {}", event.type(), event); | 385 | log.trace("event: {} {}", event.type(), event); |
371 | post(event); | 386 | post(event); |
372 | } | 387 | } |
373 | } | 388 | } |
374 | 389 | ||
390 | + // returns a DeviceDescription made from the union of the BasicDeviceConfig | ||
391 | + // annotations if it exists | ||
392 | + private DeviceDescription validateDevice(DeviceDescription deviceDescription, DeviceId deviceId) { | ||
393 | + BasicDeviceConfig cfg = networkConfigService.getConfig(deviceId, BasicDeviceConfig.class); | ||
394 | + checkState(cfg == null || cfg.isAllowed(), "Device " + deviceId + " is not allowed"); | ||
395 | + log.info("Device {} connected", deviceId); | ||
396 | + if (cfg != null) { | ||
397 | + SparseAnnotations finalSparse = processAnnotations(cfg, deviceDescription, deviceId); | ||
398 | + if (cfg.type() != Type.SWITCH) { | ||
399 | + deviceDescription = new DefaultDeviceDescription(deviceDescription, | ||
400 | + cfg.type(), finalSparse); | ||
401 | + } else { | ||
402 | + deviceDescription = new DefaultDeviceDescription(deviceDescription, | ||
403 | + deviceDescription.type(), finalSparse); | ||
404 | + } | ||
405 | + } | ||
406 | + return deviceDescription; | ||
407 | + } | ||
408 | + | ||
375 | @Override | 409 | @Override |
376 | public void deviceDisconnected(DeviceId deviceId) { | 410 | public void deviceDisconnected(DeviceId deviceId) { |
377 | checkNotNull(deviceId, DEVICE_ID_NULL); | 411 | checkNotNull(deviceId, DEVICE_ID_NULL); |
... | @@ -433,7 +467,7 @@ public class DeviceManager | ... | @@ -433,7 +467,7 @@ public class DeviceManager |
433 | List<PortDescription> portDescriptions) { | 467 | List<PortDescription> portDescriptions) { |
434 | checkNotNull(deviceId, DEVICE_ID_NULL); | 468 | checkNotNull(deviceId, DEVICE_ID_NULL); |
435 | checkNotNull(portDescriptions, | 469 | checkNotNull(portDescriptions, |
436 | - "Port descriptions list cannot be null"); | 470 | + "Port descriptions list cannot be null"); |
437 | checkValidity(); | 471 | checkValidity(); |
438 | if (!deviceClockProviderService.isTimestampAvailable(deviceId)) { | 472 | if (!deviceClockProviderService.isTimestampAvailable(deviceId)) { |
439 | // Never been a master for this device | 473 | // Never been a master for this device |
... | @@ -459,7 +493,8 @@ public class DeviceManager | ... | @@ -459,7 +493,8 @@ public class DeviceManager |
459 | if (!deviceClockProviderService.isTimestampAvailable(deviceId)) { | 493 | if (!deviceClockProviderService.isTimestampAvailable(deviceId)) { |
460 | // Never been a master for this device | 494 | // Never been a master for this device |
461 | // any update will be ignored. | 495 | // any update will be ignored. |
462 | - log.trace("Ignoring {} port update on standby node. {}", deviceId, portDescription); | 496 | + log.trace("Ignoring {} port update on standby node. {}", deviceId, |
497 | + portDescription); | ||
463 | return; | 498 | return; |
464 | } | 499 | } |
465 | 500 | ||
... | @@ -486,7 +521,7 @@ public class DeviceManager | ... | @@ -486,7 +521,7 @@ public class DeviceManager |
486 | // FIXME: implement response to this notification | 521 | // FIXME: implement response to this notification |
487 | 522 | ||
488 | log.debug("got reply to a role request for {}: asked for {}, and got {}", | 523 | log.debug("got reply to a role request for {}: asked for {}, and got {}", |
489 | - deviceId, requested, response); | 524 | + deviceId, requested, response); |
490 | 525 | ||
491 | if (requested == null && response == null) { | 526 | if (requested == null && response == null) { |
492 | // something was off with DeviceProvider, maybe check channel too? | 527 | // something was off with DeviceProvider, maybe check channel too? |
... | @@ -525,6 +560,37 @@ public class DeviceManager | ... | @@ -525,6 +560,37 @@ public class DeviceManager |
525 | deviceId, portStatistics); | 560 | deviceId, portStatistics); |
526 | post(event); | 561 | post(event); |
527 | } | 562 | } |
563 | + | ||
564 | + // supplements or replaces deviceDescription annotations with | ||
565 | + // BasicDeviceConfig annotations | ||
566 | + private SparseAnnotations processAnnotations(BasicDeviceConfig cfg, DeviceDescription deviceDescription, | ||
567 | + DeviceId deviceId) { | ||
568 | + SparseAnnotations originalAnnotations = deviceDescription.annotations(); | ||
569 | + DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder(); | ||
570 | + if (cfg.driver() != deviceId.toString()) { | ||
571 | + newBuilder.set(cfg.DRIVER, cfg.driver()); | ||
572 | + } | ||
573 | + if (cfg.type() != Type.SWITCH) { | ||
574 | + newBuilder.set(cfg.TYPE, cfg.type().toString()); | ||
575 | + } | ||
576 | + if (cfg.name() != null) { | ||
577 | + newBuilder.set(cfg.NAME, cfg.name()); | ||
578 | + } | ||
579 | + if (cfg.latitude() != -1) { | ||
580 | + newBuilder.set(cfg.LATITUDE, Double.toString(cfg.latitude())); | ||
581 | + } | ||
582 | + if (cfg.longitude() != -1) { | ||
583 | + newBuilder.set(cfg.LONGITUDE, Double.toString(cfg.longitude())); | ||
584 | + } | ||
585 | + if (cfg.rackAddress() != null) { | ||
586 | + newBuilder.set(cfg.RACK_ADDRESS, cfg.rackAddress()); | ||
587 | + } | ||
588 | + if (cfg.owner() != null) { | ||
589 | + newBuilder.set(cfg.OWNER, cfg.owner()); | ||
590 | + } | ||
591 | + DefaultAnnotations newAnnotations = newBuilder.build(); | ||
592 | + return DefaultAnnotations.union(originalAnnotations, newAnnotations); | ||
593 | + } | ||
528 | } | 594 | } |
529 | 595 | ||
530 | // Posts the specified event to the local event dispatcher. | 596 | // Posts the specified event to the local event dispatcher. |
... | @@ -727,4 +793,30 @@ public class DeviceManager | ... | @@ -727,4 +793,30 @@ public class DeviceManager |
727 | } | 793 | } |
728 | return results; | 794 | return results; |
729 | } | 795 | } |
796 | + | ||
797 | + private class InternalNetworkConfigListener implements NetworkConfigListener { | ||
798 | + @Override | ||
799 | + public void event(NetworkConfigEvent event) { | ||
800 | + if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || | ||
801 | + event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) && | ||
802 | + event.configClass().equals(BasicDeviceConfig.class)) { | ||
803 | + log.info("Detected Device network config event {}", event.type()); | ||
804 | + kickOutBadDevice(((DeviceId) event.subject())); | ||
805 | + } | ||
806 | + } | ||
807 | + } | ||
808 | + | ||
809 | + // checks if the specified device is allowed by the BasicDeviceConfig | ||
810 | + // and if not, removes it | ||
811 | + private void kickOutBadDevice(DeviceId deviceId) { | ||
812 | + BasicDeviceConfig cfg = networkConfigService.getConfig(deviceId, BasicDeviceConfig.class); | ||
813 | + if (!cfg.isAllowed()) { | ||
814 | + Device badDevice = getDevice(deviceId); | ||
815 | + if (badDevice != null) { | ||
816 | + removeDevice(deviceId); | ||
817 | + } else { | ||
818 | + log.info("Failed removal: Device {} does not exist", deviceId); | ||
819 | + } | ||
820 | + } | ||
821 | + } | ||
730 | } | 822 | } | ... | ... |
... | @@ -27,11 +27,18 @@ import org.onlab.packet.VlanId; | ... | @@ -27,11 +27,18 @@ import org.onlab.packet.VlanId; |
27 | import org.onosproject.core.Permission; | 27 | import org.onosproject.core.Permission; |
28 | import org.onosproject.event.EventDeliveryService; | 28 | import org.onosproject.event.EventDeliveryService; |
29 | import org.onosproject.event.ListenerRegistry; | 29 | import org.onosproject.event.ListenerRegistry; |
30 | +import org.onosproject.incubator.net.config.NetworkConfigEvent; | ||
31 | +import org.onosproject.incubator.net.config.NetworkConfigListener; | ||
32 | +import org.onosproject.incubator.net.config.NetworkConfigService; | ||
33 | +import org.onosproject.incubator.net.config.basics.BasicHostConfig; | ||
30 | import org.onosproject.net.ConnectPoint; | 34 | import org.onosproject.net.ConnectPoint; |
35 | +import org.onosproject.net.DefaultAnnotations; | ||
31 | import org.onosproject.net.DeviceId; | 36 | import org.onosproject.net.DeviceId; |
32 | import org.onosproject.net.Host; | 37 | import org.onosproject.net.Host; |
33 | import org.onosproject.net.HostId; | 38 | import org.onosproject.net.HostId; |
39 | +import org.onosproject.net.SparseAnnotations; | ||
34 | import org.onosproject.net.device.DeviceService; | 40 | import org.onosproject.net.device.DeviceService; |
41 | +import org.onosproject.net.host.DefaultHostDescription; | ||
35 | import org.onosproject.net.host.HostAdminService; | 42 | import org.onosproject.net.host.HostAdminService; |
36 | import org.onosproject.net.host.HostDescription; | 43 | import org.onosproject.net.host.HostDescription; |
37 | import org.onosproject.net.host.HostEvent; | 44 | import org.onosproject.net.host.HostEvent; |
... | @@ -51,6 +58,7 @@ import org.slf4j.Logger; | ... | @@ -51,6 +58,7 @@ import org.slf4j.Logger; |
51 | import java.util.Set; | 58 | import java.util.Set; |
52 | 59 | ||
53 | import static com.google.common.base.Preconditions.checkNotNull; | 60 | import static com.google.common.base.Preconditions.checkNotNull; |
61 | +import static com.google.common.base.Preconditions.checkState; | ||
54 | import static org.slf4j.LoggerFactory.getLogger; | 62 | import static org.slf4j.LoggerFactory.getLogger; |
55 | import static org.onosproject.security.AppGuard.checkPermission; | 63 | import static org.onosproject.security.AppGuard.checkPermission; |
56 | 64 | ||
... | @@ -70,6 +78,8 @@ public class HostManager | ... | @@ -70,6 +78,8 @@ public class HostManager |
70 | private final ListenerRegistry<HostEvent, HostListener> | 78 | private final ListenerRegistry<HostEvent, HostListener> |
71 | listenerRegistry = new ListenerRegistry<>(); | 79 | listenerRegistry = new ListenerRegistry<>(); |
72 | 80 | ||
81 | + private final NetworkConfigListener networkConfigListener = new InternalNetworkConfigListener(); | ||
82 | + | ||
73 | private HostStoreDelegate delegate = new InternalStoreDelegate(); | 83 | private HostStoreDelegate delegate = new InternalStoreDelegate(); |
74 | 84 | ||
75 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 85 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
... | @@ -84,6 +94,9 @@ public class HostManager | ... | @@ -84,6 +94,9 @@ public class HostManager |
84 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 94 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
85 | protected PacketService packetService; | 95 | protected PacketService packetService; |
86 | 96 | ||
97 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
98 | + protected NetworkConfigService networkConfigService; | ||
99 | + | ||
87 | private HostMonitor monitor; | 100 | private HostMonitor monitor; |
88 | 101 | ||
89 | @Activate | 102 | @Activate |
... | @@ -91,7 +104,7 @@ public class HostManager | ... | @@ -91,7 +104,7 @@ public class HostManager |
91 | log.info("Started"); | 104 | log.info("Started"); |
92 | store.setDelegate(delegate); | 105 | store.setDelegate(delegate); |
93 | eventDispatcher.addSink(HostEvent.class, listenerRegistry); | 106 | eventDispatcher.addSink(HostEvent.class, listenerRegistry); |
94 | - | 107 | + networkConfigService.addListener(networkConfigListener); |
95 | monitor = new HostMonitor(deviceService, packetService, this); | 108 | monitor = new HostMonitor(deviceService, packetService, this); |
96 | monitor.start(); | 109 | monitor.start(); |
97 | } | 110 | } |
... | @@ -100,6 +113,7 @@ public class HostManager | ... | @@ -100,6 +113,7 @@ public class HostManager |
100 | public void deactivate() { | 113 | public void deactivate() { |
101 | store.unsetDelegate(delegate); | 114 | store.unsetDelegate(delegate); |
102 | eventDispatcher.removeSink(HostEvent.class); | 115 | eventDispatcher.removeSink(HostEvent.class); |
116 | + networkConfigService.removeListener(networkConfigListener); | ||
103 | log.info("Stopped"); | 117 | log.info("Stopped"); |
104 | } | 118 | } |
105 | 119 | ||
... | @@ -246,7 +260,6 @@ public class HostManager | ... | @@ -246,7 +260,6 @@ public class HostManager |
246 | private class InternalHostProviderService | 260 | private class InternalHostProviderService |
247 | extends AbstractProviderService<HostProvider> | 261 | extends AbstractProviderService<HostProvider> |
248 | implements HostProviderService { | 262 | implements HostProviderService { |
249 | - | ||
250 | InternalHostProviderService(HostProvider provider) { | 263 | InternalHostProviderService(HostProvider provider) { |
251 | super(provider); | 264 | super(provider); |
252 | } | 265 | } |
... | @@ -255,6 +268,7 @@ public class HostManager | ... | @@ -255,6 +268,7 @@ public class HostManager |
255 | public void hostDetected(HostId hostId, HostDescription hostDescription) { | 268 | public void hostDetected(HostId hostId, HostDescription hostDescription) { |
256 | checkNotNull(hostId, HOST_ID_NULL); | 269 | checkNotNull(hostId, HOST_ID_NULL); |
257 | checkValidity(); | 270 | checkValidity(); |
271 | + hostDescription = validateHost(hostDescription, hostId); | ||
258 | HostEvent event = store.createOrUpdateHost(provider().id(), hostId, | 272 | HostEvent event = store.createOrUpdateHost(provider().id(), hostId, |
259 | hostDescription); | 273 | hostDescription); |
260 | if (event != null) { | 274 | if (event != null) { |
... | @@ -262,6 +276,21 @@ public class HostManager | ... | @@ -262,6 +276,21 @@ public class HostManager |
262 | } | 276 | } |
263 | } | 277 | } |
264 | 278 | ||
279 | + // returns a HostDescription made from the union of the BasicHostConfig | ||
280 | + // annotations if it exists | ||
281 | + private HostDescription validateHost(HostDescription hostDescription, HostId hostId) { | ||
282 | + BasicHostConfig cfg = networkConfigService.getConfig(hostId, BasicHostConfig.class); | ||
283 | + checkState(cfg == null || cfg.isAllowed(), "Host {} is not allowed", hostId); | ||
284 | + if (cfg != null) { | ||
285 | + SparseAnnotations finalSparse = processAnnotations(cfg, hostDescription); | ||
286 | + hostDescription = new DefaultHostDescription(hostId.mac(), | ||
287 | + hostDescription.vlan(), | ||
288 | + hostDescription.location(), | ||
289 | + finalSparse); | ||
290 | + } | ||
291 | + return hostDescription; | ||
292 | + } | ||
293 | + | ||
265 | @Override | 294 | @Override |
266 | public void hostVanished(HostId hostId) { | 295 | public void hostVanished(HostId hostId) { |
267 | checkNotNull(hostId, HOST_ID_NULL); | 296 | checkNotNull(hostId, HOST_ID_NULL); |
... | @@ -273,6 +302,30 @@ public class HostManager | ... | @@ -273,6 +302,30 @@ public class HostManager |
273 | } | 302 | } |
274 | } | 303 | } |
275 | 304 | ||
305 | + // Supplements or replaces hostDescriptions's annotations with BasicHostConfig's | ||
306 | + // annotations | ||
307 | + private SparseAnnotations processAnnotations(BasicHostConfig cfg, HostDescription hostDescription) { | ||
308 | + SparseAnnotations originalAnnotations = hostDescription.annotations(); | ||
309 | + DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder(); | ||
310 | + if (cfg.name() != null) { | ||
311 | + newBuilder.set(cfg.NAME, cfg.name()); | ||
312 | + } | ||
313 | + if (cfg.latitude() != -1) { | ||
314 | + newBuilder.set(cfg.LATITUDE, Double.toString(cfg.latitude())); | ||
315 | + } | ||
316 | + if (cfg.longitude() != -1) { | ||
317 | + newBuilder.set(cfg.LONGITUDE, Double.toString(cfg.longitude())); | ||
318 | + } | ||
319 | + if (cfg.rackAddress() != null) { | ||
320 | + newBuilder.set(cfg.RACK_ADDRESS, cfg.rackAddress()); | ||
321 | + } | ||
322 | + if (cfg.owner() != null) { | ||
323 | + newBuilder.set(cfg.OWNER, cfg.owner()); | ||
324 | + } | ||
325 | + DefaultAnnotations newAnnotations = newBuilder.build(); | ||
326 | + return DefaultAnnotations.union(originalAnnotations, newAnnotations); | ||
327 | + } | ||
328 | + | ||
276 | // Posts the specified event to the local event dispatcher. | 329 | // Posts the specified event to the local event dispatcher. |
277 | private void post(HostEvent event) { | 330 | private void post(HostEvent event) { |
278 | if (event != null) { | 331 | if (event != null) { |
... | @@ -287,4 +340,32 @@ public class HostManager | ... | @@ -287,4 +340,32 @@ public class HostManager |
287 | post(event); | 340 | post(event); |
288 | } | 341 | } |
289 | } | 342 | } |
343 | + | ||
344 | + // listens for NetworkConfigEvents of type BasicHostConfig and removes | ||
345 | + // links that the config does not allow | ||
346 | + private class InternalNetworkConfigListener implements NetworkConfigListener { | ||
347 | + @Override | ||
348 | + public void event(NetworkConfigEvent event) { | ||
349 | + if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || | ||
350 | + event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) && | ||
351 | + event.configClass().equals(BasicHostConfig.class)) { | ||
352 | + log.info("Detected Host network config event {}", event.type()); | ||
353 | + kickOutBadHost(((HostId) event.subject())); | ||
354 | + } | ||
355 | + } | ||
356 | + } | ||
357 | + | ||
358 | + // checks if the specified host is allowed by the BasicHostConfig | ||
359 | + // and if not, removes it | ||
360 | + private void kickOutBadHost(HostId hostId) { | ||
361 | + BasicHostConfig cfg = networkConfigService.getConfig(hostId, BasicHostConfig.class); | ||
362 | + if (cfg != null && !cfg.isAllowed()) { | ||
363 | + Host badHost = getHost(hostId); | ||
364 | + if (badHost != null) { | ||
365 | + removeHost(hostId); | ||
366 | + } else { | ||
367 | + log.info("Failed removal: Host {} does not exist", hostId); | ||
368 | + } | ||
369 | + } | ||
370 | + } | ||
290 | } | 371 | } | ... | ... |
... | @@ -27,14 +27,22 @@ import org.apache.felix.scr.annotations.Service; | ... | @@ -27,14 +27,22 @@ import org.apache.felix.scr.annotations.Service; |
27 | import org.onosproject.core.Permission; | 27 | import org.onosproject.core.Permission; |
28 | import org.onosproject.event.EventDeliveryService; | 28 | import org.onosproject.event.EventDeliveryService; |
29 | import org.onosproject.event.ListenerRegistry; | 29 | import org.onosproject.event.ListenerRegistry; |
30 | +import org.onosproject.incubator.net.config.NetworkConfigEvent; | ||
31 | +import org.onosproject.incubator.net.config.NetworkConfigListener; | ||
32 | +import org.onosproject.incubator.net.config.NetworkConfigService; | ||
33 | +import org.onosproject.incubator.net.config.basics.BasicLinkConfig; | ||
30 | import org.onosproject.net.ConnectPoint; | 34 | import org.onosproject.net.ConnectPoint; |
35 | +import org.onosproject.net.DefaultAnnotations; | ||
31 | import org.onosproject.net.DeviceId; | 36 | import org.onosproject.net.DeviceId; |
32 | import org.onosproject.net.Link; | 37 | import org.onosproject.net.Link; |
33 | import org.onosproject.net.Link.State; | 38 | import org.onosproject.net.Link.State; |
39 | +import org.onosproject.net.LinkKey; | ||
34 | import org.onosproject.net.MastershipRole; | 40 | import org.onosproject.net.MastershipRole; |
41 | +import org.onosproject.net.SparseAnnotations; | ||
35 | import org.onosproject.net.device.DeviceEvent; | 42 | import org.onosproject.net.device.DeviceEvent; |
36 | import org.onosproject.net.device.DeviceListener; | 43 | import org.onosproject.net.device.DeviceListener; |
37 | import org.onosproject.net.device.DeviceService; | 44 | import org.onosproject.net.device.DeviceService; |
45 | +import org.onosproject.net.link.DefaultLinkDescription; | ||
38 | import org.onosproject.net.link.LinkAdminService; | 46 | import org.onosproject.net.link.LinkAdminService; |
39 | import org.onosproject.net.link.LinkDescription; | 47 | import org.onosproject.net.link.LinkDescription; |
40 | import org.onosproject.net.link.LinkEvent; | 48 | import org.onosproject.net.link.LinkEvent; |
... | @@ -49,9 +57,12 @@ import org.onosproject.net.provider.AbstractProviderRegistry; | ... | @@ -49,9 +57,12 @@ import org.onosproject.net.provider.AbstractProviderRegistry; |
49 | import org.onosproject.net.provider.AbstractProviderService; | 57 | import org.onosproject.net.provider.AbstractProviderService; |
50 | import org.slf4j.Logger; | 58 | import org.slf4j.Logger; |
51 | 59 | ||
60 | +import java.time.Duration; | ||
52 | import java.util.Set; | 61 | import java.util.Set; |
53 | 62 | ||
54 | import static com.google.common.base.Preconditions.checkNotNull; | 63 | import static com.google.common.base.Preconditions.checkNotNull; |
64 | +import static com.google.common.base.Preconditions.checkState; | ||
65 | +import static org.onosproject.net.LinkKey.linkKey; | ||
55 | import static org.slf4j.LoggerFactory.getLogger; | 66 | import static org.slf4j.LoggerFactory.getLogger; |
56 | import static org.onosproject.security.AppGuard.checkPermission; | 67 | import static org.onosproject.security.AppGuard.checkPermission; |
57 | 68 | ||
... | @@ -78,6 +89,8 @@ public class LinkManager | ... | @@ -78,6 +89,8 @@ public class LinkManager |
78 | 89 | ||
79 | private final DeviceListener deviceListener = new InternalDeviceListener(); | 90 | private final DeviceListener deviceListener = new InternalDeviceListener(); |
80 | 91 | ||
92 | + private final NetworkConfigListener networkConfigListener = new InternalNetworkConfigListener(); | ||
93 | + | ||
81 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 94 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
82 | protected LinkStore store; | 95 | protected LinkStore store; |
83 | 96 | ||
... | @@ -87,11 +100,15 @@ public class LinkManager | ... | @@ -87,11 +100,15 @@ public class LinkManager |
87 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 100 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
88 | protected EventDeliveryService eventDispatcher; | 101 | protected EventDeliveryService eventDispatcher; |
89 | 102 | ||
103 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
104 | + protected NetworkConfigService networkConfigService; | ||
105 | + | ||
90 | @Activate | 106 | @Activate |
91 | public void activate() { | 107 | public void activate() { |
92 | store.setDelegate(delegate); | 108 | store.setDelegate(delegate); |
93 | eventDispatcher.addSink(LinkEvent.class, listenerRegistry); | 109 | eventDispatcher.addSink(LinkEvent.class, listenerRegistry); |
94 | deviceService.addListener(deviceListener); | 110 | deviceService.addListener(deviceListener); |
111 | + networkConfigService.addListener(networkConfigListener); | ||
95 | log.info("Started"); | 112 | log.info("Started"); |
96 | } | 113 | } |
97 | 114 | ||
... | @@ -100,6 +117,7 @@ public class LinkManager | ... | @@ -100,6 +117,7 @@ public class LinkManager |
100 | store.unsetDelegate(delegate); | 117 | store.unsetDelegate(delegate); |
101 | eventDispatcher.removeSink(LinkEvent.class); | 118 | eventDispatcher.removeSink(LinkEvent.class); |
102 | deviceService.removeListener(deviceListener); | 119 | deviceService.removeListener(deviceListener); |
120 | + networkConfigService.removeListener(networkConfigListener); | ||
103 | log.info("Stopped"); | 121 | log.info("Stopped"); |
104 | } | 122 | } |
105 | 123 | ||
... | @@ -206,17 +224,19 @@ public class LinkManager | ... | @@ -206,17 +224,19 @@ public class LinkManager |
206 | removeLinks(getDeviceLinks(deviceId), false); | 224 | removeLinks(getDeviceLinks(deviceId), false); |
207 | } | 225 | } |
208 | 226 | ||
227 | + public void removeLink(ConnectPoint src, ConnectPoint dst) { | ||
228 | + post(store.removeLink(src, dst)); | ||
229 | + } | ||
230 | + | ||
209 | @Override | 231 | @Override |
210 | public void addListener(LinkListener listener) { | 232 | public void addListener(LinkListener listener) { |
211 | checkPermission(Permission.LINK_EVENT); | 233 | checkPermission(Permission.LINK_EVENT); |
212 | - | ||
213 | listenerRegistry.addListener(listener); | 234 | listenerRegistry.addListener(listener); |
214 | } | 235 | } |
215 | 236 | ||
216 | @Override | 237 | @Override |
217 | public void removeListener(LinkListener listener) { | 238 | public void removeListener(LinkListener listener) { |
218 | checkPermission(Permission.LINK_EVENT); | 239 | checkPermission(Permission.LINK_EVENT); |
219 | - | ||
220 | listenerRegistry.removeListener(listener); | 240 | listenerRegistry.removeListener(listener); |
221 | } | 241 | } |
222 | 242 | ||
... | @@ -229,7 +249,7 @@ public class LinkManager | ... | @@ -229,7 +249,7 @@ public class LinkManager |
229 | removeLinks(event.subject().id()); | 249 | removeLinks(event.subject().id()); |
230 | } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) { | 250 | } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) { |
231 | removeLinks(new ConnectPoint(event.subject().id(), | 251 | removeLinks(new ConnectPoint(event.subject().id(), |
232 | - event.port().number())); | 252 | + event.port().number())); |
233 | } | 253 | } |
234 | } | 254 | } |
235 | } | 255 | } |
... | @@ -252,15 +272,62 @@ public class LinkManager | ... | @@ -252,15 +272,62 @@ public class LinkManager |
252 | public void linkDetected(LinkDescription linkDescription) { | 272 | public void linkDetected(LinkDescription linkDescription) { |
253 | checkNotNull(linkDescription, LINK_DESC_NULL); | 273 | checkNotNull(linkDescription, LINK_DESC_NULL); |
254 | checkValidity(); | 274 | checkValidity(); |
255 | - | 275 | + linkDescription = validateLink(linkDescription); |
256 | LinkEvent event = store.createOrUpdateLink(provider().id(), | 276 | LinkEvent event = store.createOrUpdateLink(provider().id(), |
257 | - linkDescription); | 277 | + linkDescription); |
258 | if (event != null) { | 278 | if (event != null) { |
259 | log.info("Link {} detected", linkDescription); | 279 | log.info("Link {} detected", linkDescription); |
260 | post(event); | 280 | post(event); |
261 | } | 281 | } |
262 | } | 282 | } |
263 | 283 | ||
284 | + // returns a LinkDescription made from the union of the BasicLinkConfig | ||
285 | + // annotations if it exists | ||
286 | + private LinkDescription validateLink(LinkDescription linkDescription) { | ||
287 | + // TODO Investigate whether this can be made more efficient | ||
288 | + BasicLinkConfig cfg = networkConfigService.getConfig(linkKey(linkDescription.src(), | ||
289 | + linkDescription.dst()), | ||
290 | + BasicLinkConfig.class); | ||
291 | + BasicLinkConfig cfgTwo = networkConfigService.getConfig(linkKey(linkDescription.dst(), | ||
292 | + linkDescription.src()), | ||
293 | + BasicLinkConfig.class); | ||
294 | + | ||
295 | + checkState(cfg == null || cfg.isAllowed(), "Link " + linkDescription.toString() + " is not allowed"); | ||
296 | + checkState(cfgTwo == null || cfgTwo.isAllowed(), "Link " + linkDescription.toString() + " is not allowed"); | ||
297 | + if (cfg != null) { | ||
298 | + SparseAnnotations finalSparse = processAnnotations(cfg, linkDescription); | ||
299 | + // check whether config has a specified type | ||
300 | + if (cfg.type() != Link.Type.DIRECT) { | ||
301 | + linkDescription = new DefaultLinkDescription(linkDescription.src(), | ||
302 | + linkDescription.dst(), | ||
303 | + cfg.type(), finalSparse); | ||
304 | + } else { | ||
305 | + linkDescription = new DefaultLinkDescription(linkDescription.src(), | ||
306 | + linkDescription.dst(), | ||
307 | + linkDescription.type(), finalSparse); | ||
308 | + } | ||
309 | + } | ||
310 | + return linkDescription; | ||
311 | + } | ||
312 | + | ||
313 | + // supplements or replaces linkDescriptions's annotations with BasicLinkConfig's | ||
314 | + // annotations | ||
315 | + private SparseAnnotations processAnnotations(BasicLinkConfig cfg, LinkDescription linkDescription) { | ||
316 | + SparseAnnotations originalAnnotations = linkDescription.annotations(); | ||
317 | + DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder(); | ||
318 | + if (cfg.type() != Link.Type.DIRECT) { | ||
319 | + newBuilder.set(cfg.TYPE, cfg.type().toString()); | ||
320 | + } | ||
321 | + if (cfg.latency() != Duration.ofNanos(-1)) { | ||
322 | + newBuilder.set(cfg.LATENCY, cfg.latency().toString()); | ||
323 | + } | ||
324 | + if (cfg.bandwidth() != -1) { | ||
325 | + newBuilder.set(cfg.BANDWIDTH, String.valueOf(cfg.bandwidth())); | ||
326 | + } | ||
327 | + DefaultAnnotations newAnnotations = newBuilder.build(); | ||
328 | + return DefaultAnnotations.union(originalAnnotations, newAnnotations); | ||
329 | + } | ||
330 | + | ||
264 | @Override | 331 | @Override |
265 | public void linkVanished(LinkDescription linkDescription) { | 332 | public void linkVanished(LinkDescription linkDescription) { |
266 | checkNotNull(linkDescription, LINK_DESC_NULL); | 333 | checkNotNull(linkDescription, LINK_DESC_NULL); |
... | @@ -297,7 +364,7 @@ public class LinkManager | ... | @@ -297,7 +364,7 @@ public class LinkManager |
297 | } | 364 | } |
298 | 365 | ||
299 | // Removes all links in the specified set and emits appropriate events. | 366 | // Removes all links in the specified set and emits appropriate events. |
300 | - private void removeLinks(Set<Link> links, boolean isSoftRemove) { | 367 | + private void removeLinks(Set<Link> links, boolean isSoftRemove) { |
301 | for (Link link : links) { | 368 | for (Link link : links) { |
302 | LinkEvent event = isSoftRemove ? | 369 | LinkEvent event = isSoftRemove ? |
303 | store.removeOrDownLink(link.src(), link.dst()) : | 370 | store.removeOrDownLink(link.src(), link.dst()) : |
... | @@ -323,4 +390,24 @@ public class LinkManager | ... | @@ -323,4 +390,24 @@ public class LinkManager |
323 | post(event); | 390 | post(event); |
324 | } | 391 | } |
325 | } | 392 | } |
393 | + | ||
394 | + // listens for NetworkConfigEvents of type BasicLinkConfig and removes | ||
395 | + // links that the config does not allow | ||
396 | + private class InternalNetworkConfigListener implements NetworkConfigListener { | ||
397 | + @Override | ||
398 | + public void event(NetworkConfigEvent event) { | ||
399 | + if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || | ||
400 | + event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) && | ||
401 | + event.configClass().equals(BasicLinkConfig.class)) { | ||
402 | + log.info("Detected Link network config event {}", event.type()); | ||
403 | + LinkKey lk = (LinkKey) event.subject(); | ||
404 | + BasicLinkConfig cfg = networkConfigService.getConfig(lk, BasicLinkConfig.class); | ||
405 | + if (cfg != null && !cfg.isAllowed()) { | ||
406 | + log.info("Kicking out links between {} and {}", lk.src(), lk.dst()); | ||
407 | + removeLink(lk.src(), lk.dst()); | ||
408 | + removeLink(lk.dst(), lk.src()); | ||
409 | + } | ||
410 | + } | ||
411 | + } | ||
412 | + } | ||
326 | } | 413 | } | ... | ... |
... | @@ -32,6 +32,7 @@ import org.onosproject.cluster.DefaultControllerNode; | ... | @@ -32,6 +32,7 @@ import org.onosproject.cluster.DefaultControllerNode; |
32 | import org.onosproject.cluster.NodeId; | 32 | import org.onosproject.cluster.NodeId; |
33 | import org.onosproject.event.Event; | 33 | import org.onosproject.event.Event; |
34 | import org.onosproject.common.event.impl.TestEventDispatcher; | 34 | import org.onosproject.common.event.impl.TestEventDispatcher; |
35 | +import org.onosproject.incubator.net.config.NetworkConfigServiceAdapter; | ||
35 | import org.onosproject.mastership.MastershipServiceAdapter; | 36 | import org.onosproject.mastership.MastershipServiceAdapter; |
36 | import org.onosproject.mastership.MastershipTerm; | 37 | import org.onosproject.mastership.MastershipTerm; |
37 | import org.onosproject.mastership.MastershipTermService; | 38 | import org.onosproject.mastership.MastershipTermService; |
... | @@ -115,8 +116,10 @@ public class DeviceManagerTest { | ... | @@ -115,8 +116,10 @@ public class DeviceManagerTest { |
115 | mgr.termService = mastershipManager; | 116 | mgr.termService = mastershipManager; |
116 | mgr.clusterService = new TestClusterService(); | 117 | mgr.clusterService = new TestClusterService(); |
117 | mgr.deviceClockProviderService = new TestClockProviderService(); | 118 | mgr.deviceClockProviderService = new TestClockProviderService(); |
119 | + mgr.networkConfigService = new TestNetworkConfigService(); | ||
118 | mgr.activate(); | 120 | mgr.activate(); |
119 | 121 | ||
122 | + | ||
120 | service.addListener(listener); | 123 | service.addListener(listener); |
121 | 124 | ||
122 | provider = new TestProvider(); | 125 | provider = new TestProvider(); |
... | @@ -349,4 +352,7 @@ public class DeviceManagerTest { | ... | @@ -349,4 +352,7 @@ public class DeviceManagerTest { |
349 | return registerdBefore.contains(deviceId); | 352 | return registerdBefore.contains(deviceId); |
350 | } | 353 | } |
351 | } | 354 | } |
355 | + | ||
356 | + private class TestNetworkConfigService extends NetworkConfigServiceAdapter { | ||
357 | + } | ||
352 | } | 358 | } | ... | ... |
... | @@ -37,6 +37,7 @@ import org.onlab.packet.MacAddress; | ... | @@ -37,6 +37,7 @@ import org.onlab.packet.MacAddress; |
37 | import org.onlab.packet.VlanId; | 37 | import org.onlab.packet.VlanId; |
38 | import org.onosproject.event.Event; | 38 | import org.onosproject.event.Event; |
39 | import org.onosproject.common.event.impl.TestEventDispatcher; | 39 | import org.onosproject.common.event.impl.TestEventDispatcher; |
40 | +import org.onosproject.incubator.net.config.NetworkConfigServiceAdapter; | ||
40 | import org.onosproject.net.ConnectPoint; | 41 | import org.onosproject.net.ConnectPoint; |
41 | import org.onosproject.net.DeviceId; | 42 | import org.onosproject.net.DeviceId; |
42 | import org.onosproject.net.Host; | 43 | import org.onosproject.net.Host; |
... | @@ -123,6 +124,7 @@ public class HostManagerTest { | ... | @@ -123,6 +124,7 @@ public class HostManagerTest { |
123 | mgr.store = new SimpleHostStore(); | 124 | mgr.store = new SimpleHostStore(); |
124 | mgr.eventDispatcher = new TestEventDispatcher(); | 125 | mgr.eventDispatcher = new TestEventDispatcher(); |
125 | registry = mgr; | 126 | registry = mgr; |
127 | + mgr.networkConfigService = new TestNetworkConfigService(); | ||
126 | mgr.activate(); | 128 | mgr.activate(); |
127 | 129 | ||
128 | mgr.addListener(listener); | 130 | mgr.addListener(listener); |
... | @@ -520,4 +522,7 @@ public class HostManagerTest { | ... | @@ -520,4 +522,7 @@ public class HostManagerTest { |
520 | assertTrue(storedAddresses.size() == 2); | 522 | assertTrue(storedAddresses.size() == 2); |
521 | assertTrue(storedAddresses.equals(Sets.newHashSet(add1, add2))); | 523 | assertTrue(storedAddresses.equals(Sets.newHashSet(add1, add2))); |
522 | } | 524 | } |
525 | + | ||
526 | + private class TestNetworkConfigService extends NetworkConfigServiceAdapter { | ||
527 | + } | ||
523 | } | 528 | } | ... | ... |
... | @@ -20,6 +20,7 @@ import org.junit.After; | ... | @@ -20,6 +20,7 @@ import org.junit.After; |
20 | import org.junit.Before; | 20 | import org.junit.Before; |
21 | import org.junit.Test; | 21 | import org.junit.Test; |
22 | import org.onosproject.event.Event; | 22 | import org.onosproject.event.Event; |
23 | +import org.onosproject.incubator.net.config.NetworkConfigServiceAdapter; | ||
23 | import org.onosproject.net.ConnectPoint; | 24 | import org.onosproject.net.ConnectPoint; |
24 | import org.onosproject.net.DefaultDevice; | 25 | import org.onosproject.net.DefaultDevice; |
25 | import org.onosproject.net.Device; | 26 | import org.onosproject.net.Device; |
... | @@ -86,6 +87,7 @@ public class LinkManagerTest { | ... | @@ -86,6 +87,7 @@ public class LinkManagerTest { |
86 | protected DeviceManager devmgr = new TestDeviceManager(); | 87 | protected DeviceManager devmgr = new TestDeviceManager(); |
87 | 88 | ||
88 | 89 | ||
90 | + | ||
89 | @Before | 91 | @Before |
90 | public void setUp() { | 92 | public void setUp() { |
91 | mgr = new LinkManager(); | 93 | mgr = new LinkManager(); |
... | @@ -95,6 +97,7 @@ public class LinkManagerTest { | ... | @@ -95,6 +97,7 @@ public class LinkManagerTest { |
95 | mgr.store = new SimpleLinkStore(); | 97 | mgr.store = new SimpleLinkStore(); |
96 | mgr.eventDispatcher = new TestEventDispatcher(); | 98 | mgr.eventDispatcher = new TestEventDispatcher(); |
97 | mgr.deviceService = devmgr; | 99 | mgr.deviceService = devmgr; |
100 | + mgr.networkConfigService = new TestNetworkConfigService(); | ||
98 | mgr.activate(); | 101 | mgr.activate(); |
99 | 102 | ||
100 | DEVICEIDMAP.put(DID1, DEV1); | 103 | DEVICEIDMAP.put(DID1, DEV1); |
... | @@ -302,5 +305,6 @@ public class LinkManagerTest { | ... | @@ -302,5 +305,6 @@ public class LinkManagerTest { |
302 | } | 305 | } |
303 | 306 | ||
304 | } | 307 | } |
305 | - | 308 | + private class TestNetworkConfigService extends NetworkConfigServiceAdapter { |
309 | + } | ||
306 | } | 310 | } | ... | ... |
incubator/api/src/test/java/org/onosproject/incubator/net/config/NetworkConfigServiceAdapter.java
0 → 100644
1 | +package org.onosproject.incubator.net.config; | ||
2 | + | ||
3 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
4 | + | ||
5 | +import java.util.Set; | ||
6 | + | ||
7 | +/** | ||
8 | + * Test adapter for network configuration service. | ||
9 | + */ | ||
10 | +public class NetworkConfigServiceAdapter implements NetworkConfigService { | ||
11 | + @Override | ||
12 | + public Set<Class> getSubjectClasses() { | ||
13 | + return null; | ||
14 | + } | ||
15 | + | ||
16 | + @Override | ||
17 | + public SubjectFactory getSubjectFactory(String subjectKey) { | ||
18 | + return null; | ||
19 | + } | ||
20 | + | ||
21 | + @Override | ||
22 | + public SubjectFactory getSubjectFactory(Class subjectClass) { | ||
23 | + return null; | ||
24 | + } | ||
25 | + | ||
26 | + @Override | ||
27 | + public Class<? extends Config> getConfigClass(String subjectKey, String configKey) { | ||
28 | + return null; | ||
29 | + } | ||
30 | + | ||
31 | + @Override | ||
32 | + public <S> Set<S> getSubjects(Class<S> subjectClass) { | ||
33 | + return null; | ||
34 | + } | ||
35 | + | ||
36 | + @Override | ||
37 | + public <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass) { | ||
38 | + return null; | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public <S> Set<? extends Config<S>> getConfigs(S subject) { | ||
43 | + return null; | ||
44 | + } | ||
45 | + | ||
46 | + @Override | ||
47 | + public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) { | ||
48 | + return null; | ||
49 | + } | ||
50 | + | ||
51 | + @Override | ||
52 | + public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) { | ||
53 | + return null; | ||
54 | + } | ||
55 | + | ||
56 | + @Override | ||
57 | + public <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, ObjectNode json) { | ||
58 | + return null; | ||
59 | + } | ||
60 | + | ||
61 | + @Override | ||
62 | + public <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass) { | ||
63 | + | ||
64 | + } | ||
65 | + | ||
66 | + @Override | ||
67 | + public void addListener(NetworkConfigListener listener) { | ||
68 | + | ||
69 | + } | ||
70 | + | ||
71 | + @Override | ||
72 | + public void removeListener(NetworkConfigListener listener) { | ||
73 | + | ||
74 | + } | ||
75 | +} |
... | @@ -270,7 +270,11 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -270,7 +270,11 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
270 | private void updateLocation(HostId hid, MacAddress mac, | 270 | private void updateLocation(HostId hid, MacAddress mac, |
271 | VlanId vlan, HostLocation hloc) { | 271 | VlanId vlan, HostLocation hloc) { |
272 | HostDescription desc = new DefaultHostDescription(mac, vlan, hloc); | 272 | HostDescription desc = new DefaultHostDescription(mac, vlan, hloc); |
273 | - providerService.hostDetected(hid, desc); | 273 | + try { |
274 | + providerService.hostDetected(hid, desc); | ||
275 | + } catch (IllegalStateException e) { | ||
276 | + log.debug("Host {} suppressed", hid); | ||
277 | + } | ||
274 | } | 278 | } |
275 | 279 | ||
276 | /** | 280 | /** |
... | @@ -286,7 +290,11 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -286,7 +290,11 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
286 | VlanId vlan, HostLocation hloc, | 290 | VlanId vlan, HostLocation hloc, |
287 | IpAddress ip) { | 291 | IpAddress ip) { |
288 | HostDescription desc = new DefaultHostDescription(mac, vlan, hloc, ip); | 292 | HostDescription desc = new DefaultHostDescription(mac, vlan, hloc, ip); |
289 | - providerService.hostDetected(hid, desc); | 293 | + try { |
294 | + providerService.hostDetected(hid, desc); | ||
295 | + } catch (IllegalStateException e) { | ||
296 | + log.debug("Host {} suppressed", hid); | ||
297 | + } | ||
290 | } | 298 | } |
291 | 299 | ||
292 | @Override | 300 | @Override | ... | ... |
... | @@ -229,7 +229,12 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -229,7 +229,12 @@ public class LinkDiscovery implements TimerTask { |
229 | } else { | 229 | } else { |
230 | ld = new DefaultLinkDescription(src, dst, Type.DIRECT); | 230 | ld = new DefaultLinkDescription(src, dst, Type.DIRECT); |
231 | } | 231 | } |
232 | - linkProvider.linkDetected(ld); | 232 | + |
233 | + try { | ||
234 | + linkProvider.linkDetected(ld); | ||
235 | + } catch (IllegalStateException e) { | ||
236 | + return true; | ||
237 | + } | ||
233 | return true; | 238 | return true; |
234 | } | 239 | } |
235 | return false; | 240 | return false; | ... | ... |
tools/test/configs/override-basic.json
0 → 100644
1 | +{ | ||
2 | + "devices": { | ||
3 | + "of:0000000000000009": { | ||
4 | + "basic": { | ||
5 | + "allowed": true, | ||
6 | + "owner": "Luigi" | ||
7 | + } | ||
8 | + }, | ||
9 | + "of:0000000000000008": { | ||
10 | + "basic": { | ||
11 | + "name": "NameChangeAgain", | ||
12 | + "allowed": true, | ||
13 | + "owner": "Mario" | ||
14 | + } | ||
15 | + }, | ||
16 | + "of:0000000000000007": { | ||
17 | + "basic": { | ||
18 | + "allowed": true, | ||
19 | + "owner": "Peach", | ||
20 | + "latitude": "25" | ||
21 | + } | ||
22 | + } | ||
23 | + }, | ||
24 | + "links": { | ||
25 | + "of:0000000000000006/2-of:0000000000000007/2": { | ||
26 | + "basic": { | ||
27 | + "allowed": true | ||
28 | + } | ||
29 | + } | ||
30 | + }, | ||
31 | + "hosts": { | ||
32 | + "00:00:00:00:00:03/-1": { | ||
33 | + "basic": { | ||
34 | + "allowed": true | ||
35 | + } | ||
36 | + } | ||
37 | + } | ||
38 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | { | 1 | { |
2 | "devices": { | 2 | "devices": { |
3 | - "of:001122334455667788" : { | 3 | + "of:0000000000000009": { |
4 | - "basic" : { | 4 | + "basic": { |
5 | - "allowed": false, | 5 | + "allowed": true, |
6 | - "name": "Bad Device", | ||
7 | "owner": "Luigi" | 6 | "owner": "Luigi" |
8 | } | 7 | } |
8 | + }, | ||
9 | + "of:0000000000000008": { | ||
10 | + "basic": { | ||
11 | + "name": "NameChange", | ||
12 | + "allowed": true, | ||
13 | + "owner": "Mario" | ||
14 | + } | ||
15 | + }, | ||
16 | + "of:0000000000000007": { | ||
17 | + "basic": { | ||
18 | + "allowed": true, | ||
19 | + "owner": "Peach", | ||
20 | + "latitude": "25" | ||
21 | + } | ||
22 | + }, | ||
23 | + "of:0000000000000003": { | ||
24 | + "basic": { | ||
25 | + "allowed": true, | ||
26 | + "owner": "Wario" | ||
27 | + } | ||
28 | + } | ||
29 | + }, | ||
30 | + "links": { | ||
31 | + "of:0000000000000006/2-of:0000000000000007/2": { | ||
32 | + "basic": { | ||
33 | + "allowed": true | ||
34 | + } | ||
9 | } | 35 | } |
10 | }, | 36 | }, |
11 | - "hosts": {}, | 37 | + "hosts": { |
12 | - "links": {} | 38 | + "00:00:00:00:00:03/-1": { |
39 | + "basic": { | ||
40 | + "allowed": false | ||
41 | + } | ||
42 | + }, | ||
43 | + "00:00:00:00:00:02/-1": { | ||
44 | + "basic": { | ||
45 | + "allowed": false | ||
46 | + } | ||
47 | + }, | ||
48 | + "00:00:00:00:00:01/-1": { | ||
49 | + "basic": { | ||
50 | + "allowed": false | ||
51 | + } | ||
52 | + } | ||
53 | + } | ||
13 | } | 54 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -87,7 +87,7 @@ public class NetworkConfigWebResource extends AbstractWebResource { | ... | @@ -87,7 +87,7 @@ public class NetworkConfigWebResource extends AbstractWebResource { |
87 | NetworkConfigService service = get(NetworkConfigService.class); | 87 | NetworkConfigService service = get(NetworkConfigService.class); |
88 | ObjectNode root = mapper().createObjectNode(); | 88 | ObjectNode root = mapper().createObjectNode(); |
89 | produceSubjectJson(service, root, | 89 | produceSubjectJson(service, root, |
90 | - service.getSubjectFactory(subjectKey).createSubject(subject)); | 90 | + service.getSubjectFactory(subjectKey).createSubject(subject)); |
91 | return ok(root).build(); | 91 | return ok(root).build(); |
92 | } | 92 | } |
93 | 93 | ||
... | @@ -140,7 +140,7 @@ public class NetworkConfigWebResource extends AbstractWebResource { | ... | @@ -140,7 +140,7 @@ public class NetworkConfigWebResource extends AbstractWebResource { |
140 | ObjectNode root = (ObjectNode) mapper().readTree(request); | 140 | ObjectNode root = (ObjectNode) mapper().readTree(request); |
141 | root.fieldNames() | 141 | root.fieldNames() |
142 | .forEachRemaining(sk -> consumeJson(service, (ObjectNode) root.path(sk), | 142 | .forEachRemaining(sk -> consumeJson(service, (ObjectNode) root.path(sk), |
143 | - service.getSubjectFactory(sk))); | 143 | + service.getSubjectFactory(sk))); |
144 | return Response.ok().build(); | 144 | return Response.ok().build(); |
145 | } | 145 | } |
146 | 146 | ||
... | @@ -183,8 +183,8 @@ public class NetworkConfigWebResource extends AbstractWebResource { | ... | @@ -183,8 +183,8 @@ public class NetworkConfigWebResource extends AbstractWebResource { |
183 | NetworkConfigService service = get(NetworkConfigService.class); | 183 | NetworkConfigService service = get(NetworkConfigService.class); |
184 | ObjectNode root = (ObjectNode) mapper().readTree(request); | 184 | ObjectNode root = (ObjectNode) mapper().readTree(request); |
185 | consumeSubjectJson(service, root, | 185 | consumeSubjectJson(service, root, |
186 | - service.getSubjectFactory(subjectKey).createSubject(subject), | 186 | + service.getSubjectFactory(subjectKey).createSubject(subject), |
187 | - subjectKey); | 187 | + subjectKey); |
188 | return Response.ok().build(); | 188 | return Response.ok().build(); |
189 | } | 189 | } |
190 | 190 | ||
... | @@ -210,16 +210,16 @@ public class NetworkConfigWebResource extends AbstractWebResource { | ... | @@ -210,16 +210,16 @@ public class NetworkConfigWebResource extends AbstractWebResource { |
210 | NetworkConfigService service = get(NetworkConfigService.class); | 210 | NetworkConfigService service = get(NetworkConfigService.class); |
211 | ObjectNode root = (ObjectNode) mapper().readTree(request); | 211 | ObjectNode root = (ObjectNode) mapper().readTree(request); |
212 | service.applyConfig(service.getSubjectFactory(subjectKey).createSubject(subject), | 212 | service.applyConfig(service.getSubjectFactory(subjectKey).createSubject(subject), |
213 | - service.getConfigClass(subjectKey, configKey), root); | 213 | + service.getConfigClass(subjectKey, configKey), root); |
214 | return Response.ok().build(); | 214 | return Response.ok().build(); |
215 | } | 215 | } |
216 | 216 | ||
217 | private void consumeJson(NetworkConfigService service, ObjectNode classNode, | 217 | private void consumeJson(NetworkConfigService service, ObjectNode classNode, |
218 | SubjectFactory subjectFactory) { | 218 | SubjectFactory subjectFactory) { |
219 | classNode.fieldNames().forEachRemaining(s -> | 219 | classNode.fieldNames().forEachRemaining(s -> |
220 | - consumeSubjectJson(service, (ObjectNode) classNode.path(s), | 220 | + consumeSubjectJson(service, (ObjectNode) classNode.path(s), |
221 | - subjectFactory.createSubject(s), | 221 | + subjectFactory.createSubject(s), |
222 | - subjectFactory.subjectKey())); | 222 | + subjectFactory.subjectKey())); |
223 | } | 223 | } |
224 | 224 | ||
225 | private void consumeSubjectJson(NetworkConfigService service, | 225 | private void consumeSubjectJson(NetworkConfigService service, |
... | @@ -227,7 +227,7 @@ public class NetworkConfigWebResource extends AbstractWebResource { | ... | @@ -227,7 +227,7 @@ public class NetworkConfigWebResource extends AbstractWebResource { |
227 | String subjectKey) { | 227 | String subjectKey) { |
228 | subjectNode.fieldNames().forEachRemaining(c -> | 228 | subjectNode.fieldNames().forEachRemaining(c -> |
229 | service.applyConfig(subject, service.getConfigClass(subjectKey, c), | 229 | service.applyConfig(subject, service.getConfigClass(subjectKey, c), |
230 | - (ObjectNode) subjectNode.path(c))); | 230 | + (ObjectNode) subjectNode.path(c))); |
231 | } | 231 | } |
232 | 232 | ||
233 | 233 | ||
... | @@ -272,4 +272,46 @@ public class NetworkConfigWebResource extends AbstractWebResource { | ... | @@ -272,4 +272,46 @@ public class NetworkConfigWebResource extends AbstractWebResource { |
272 | return Response.ok().build(); | 272 | return Response.ok().build(); |
273 | } | 273 | } |
274 | 274 | ||
275 | + | ||
276 | + /** | ||
277 | + * Clears all network configurations. | ||
278 | + * | ||
279 | + * @return empty response | ||
280 | + */ | ||
281 | + @DELETE | ||
282 | + @Consumes(MediaType.APPLICATION_JSON) | ||
283 | + @SuppressWarnings("unchecked") | ||
284 | + public Response upload() { | ||
285 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
286 | + service.getSubjectClasses().forEach(subjectClass -> { | ||
287 | + service.getSubjects(subjectClass).forEach(subject -> { | ||
288 | + service.getConfigs(subject).forEach(config -> { | ||
289 | + service.removeConfig(subject, config.getClass()); | ||
290 | + }); | ||
291 | + }); | ||
292 | + }); | ||
293 | + return Response.ok().build(); | ||
294 | + } | ||
295 | + | ||
296 | + | ||
297 | + // TODO: this one below doesn't work correctly | ||
298 | + /** | ||
299 | + * Clears network configuration for the specified subject class. | ||
300 | + * | ||
301 | + * @param subjectKey subject class key | ||
302 | + * @return empty response | ||
303 | + */ | ||
304 | + @DELETE | ||
305 | + @Path("{subjectKey}/") | ||
306 | + @Consumes(MediaType.APPLICATION_JSON) | ||
307 | + @SuppressWarnings("unchecked") | ||
308 | + public Response upload(@PathParam("subjectKey") String subjectKey) { | ||
309 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
310 | + service.getSubjects(service.getSubjectFactory(subjectKey).getClass()).forEach(subject -> { | ||
311 | + service.getConfigs(subject).forEach(config -> { | ||
312 | + service.removeConfig(subject, config.getClass()); | ||
313 | + }); | ||
314 | + }); | ||
315 | + return Response.ok().build(); | ||
316 | + } | ||
275 | } | 317 | } | ... | ... |
-
Please register or login to post a comment