Sahil Lele
Committed by Gerrit Code Review

Devices,hosts, and links can be blocked and kicked off with the network configuration api

Change-Id: I68d427f4886a7b63475df8d35383e2e347946946
...@@ -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 }
......
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;
......
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 }
......