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