blob: 2258f44a849a6baa6187555755299f4454737e3f [file] [log] [blame]
Thomas Vachuskac40d4632015-04-09 16:55:03 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thomas Vachuskac40d4632015-04-09 16:55:03 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.provider.nil;
17
Thomas Vachuskac40d4632015-04-09 16:55:03 -070018import org.onlab.osgi.DefaultServiceDirectory;
19import org.onosproject.cfg.ComponentConfigService;
20import org.onosproject.cluster.ClusterService;
21import org.onosproject.cluster.NodeId;
22import org.onosproject.mastership.MastershipAdminService;
23import org.onosproject.net.ConnectPoint;
24import org.onosproject.net.DeviceId;
25import org.onosproject.net.Host;
26import org.onosproject.net.MastershipRole;
Saurav Dasa2d37502016-03-25 17:50:40 -070027import org.onosproject.net.PortNumber;
Thomas Vachuskac40d4632015-04-09 16:55:03 -070028import org.onosproject.net.device.DeviceAdminService;
29import org.onosproject.net.device.DeviceProvider;
30import org.onosproject.net.device.DeviceProviderRegistry;
31import org.onosproject.net.device.DeviceProviderService;
32import org.onosproject.net.flow.FlowRuleProviderRegistry;
33import org.onosproject.net.flow.FlowRuleProviderService;
Yi Tseng3dca0f82018-04-03 14:33:03 +080034import org.onosproject.net.group.GroupProviderRegistry;
35import org.onosproject.net.group.GroupProviderService;
Thomas Vachuskac40d4632015-04-09 16:55:03 -070036import org.onosproject.net.host.HostProvider;
37import org.onosproject.net.host.HostProviderRegistry;
38import org.onosproject.net.host.HostProviderService;
39import org.onosproject.net.host.HostService;
40import org.onosproject.net.link.LinkProvider;
41import org.onosproject.net.link.LinkProviderRegistry;
42import org.onosproject.net.link.LinkProviderService;
43import org.onosproject.net.link.LinkService;
44import org.onosproject.net.packet.PacketProviderRegistry;
45import org.onosproject.net.packet.PacketProviderService;
46import org.onosproject.net.provider.AbstractProvider;
47import org.onosproject.net.provider.ProviderId;
48import org.osgi.service.component.ComponentContext;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070049import org.osgi.service.component.annotations.Activate;
50import org.osgi.service.component.annotations.Component;
51import org.osgi.service.component.annotations.Deactivate;
52import org.osgi.service.component.annotations.Modified;
53import org.osgi.service.component.annotations.Reference;
54import org.osgi.service.component.annotations.ReferenceCardinality;
Thomas Vachuskac40d4632015-04-09 16:55:03 -070055import org.slf4j.Logger;
56
57import java.util.Dictionary;
Thomas Vachuska8e038eb2016-02-23 23:28:23 -080058import java.util.Objects;
Thomas Vachuskac40d4632015-04-09 16:55:03 -070059import java.util.Properties;
60
61import static com.google.common.base.Strings.isNullOrEmpty;
62import static org.onlab.util.Tools.delay;
63import static org.onlab.util.Tools.get;
64import static org.onosproject.net.DeviceId.deviceId;
65import static org.onosproject.net.MastershipRole.MASTER;
66import static org.onosproject.net.MastershipRole.NONE;
67import static org.slf4j.LoggerFactory.getLogger;
68
69/**
70 * Provider of a fake network environment, i.e. devices, links, hosts, etc.
71 * To be used for benchmarking only.
72 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070073@Component(immediate = true, service = NullProviders.class)
Thomas Vachuskac40d4632015-04-09 16:55:03 -070074public class NullProviders {
75
76 private static final Logger log = getLogger(NullProviders.class);
77
78 static final String SCHEME = "null";
79 static final String PROVIDER_ID = "org.onosproject.provider.nil";
80
81 private static final String FORMAT =
82 "Settings: enabled={}, topoShape={}, deviceCount={}, " +
83 "hostCount={}, packetRate={}, mutationRate={}";
84
85
Ray Milkeyd84f89b2018-08-17 14:54:17 -070086 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -070087 protected ClusterService clusterService;
88
Ray Milkeyd84f89b2018-08-17 14:54:17 -070089 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -070090 protected MastershipAdminService mastershipService;
91
Ray Milkeyd84f89b2018-08-17 14:54:17 -070092 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -070093 protected ComponentConfigService cfgService;
94
Ray Milkeyd84f89b2018-08-17 14:54:17 -070095 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -070096 protected DeviceAdminService deviceService;
97
Ray Milkeyd84f89b2018-08-17 14:54:17 -070098 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -070099 protected HostService hostService;
100
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700101 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700102 protected LinkService linkService;
103
104
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700105 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700106 protected DeviceProviderRegistry deviceProviderRegistry;
107
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700108 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700109 protected HostProviderRegistry hostProviderRegistry;
110
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700111 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700112 protected LinkProviderRegistry linkProviderRegistry;
113
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700114 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700115 protected FlowRuleProviderRegistry flowRuleProviderRegistry;
116
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700117 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yi Tseng3dca0f82018-04-03 14:33:03 +0800118 protected GroupProviderRegistry groupProviderRegistry;
119
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700120 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700121 protected PacketProviderRegistry packetProviderRegistry;
122
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700123 private final NullDeviceProvider deviceProvider = new NullDeviceProvider();
124 private final NullLinkProvider linkProvider = new NullLinkProvider();
125 private final NullHostProvider hostProvider = new NullHostProvider();
126 private final NullFlowRuleProvider flowRuleProvider = new NullFlowRuleProvider();
Yi Tseng3dca0f82018-04-03 14:33:03 +0800127 private final NullGroupProvider groupProvider = new NullGroupProvider();
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700128 private final NullPacketProvider packetProvider = new NullPacketProvider();
129 private final TopologyMutationDriver topologyMutationDriver = new TopologyMutationDriver();
130
131 private DeviceProviderService deviceProviderService;
132 private HostProviderService hostProviderService;
133 private LinkProviderService linkProviderService;
134 private FlowRuleProviderService flowRuleProviderService;
Yi Tseng3dca0f82018-04-03 14:33:03 +0800135 private GroupProviderService groupProviderService;
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700136 private PacketProviderService packetProviderService;
137
138 private TopologySimulator simulator;
139
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700140 //@Property(name = "enabled", boolValue = false,
141 // label = "Enables or disables the provider")
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700142 private boolean enabled = false;
143
144 private static final String DEFAULT_TOPO_SHAPE = "configured";
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700145 //@Property(name = "topoShape", value = DEFAULT_TOPO_SHAPE,
146 // label = "Topology shape: configured, linear, reroute, tree, spineleaf, mesh, grid")
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700147 private String topoShape = DEFAULT_TOPO_SHAPE;
148
149 private static final int DEFAULT_DEVICE_COUNT = 10;
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700150 //@Property(name = "deviceCount", intValue = DEFAULT_DEVICE_COUNT,
151 // label = "Number of devices to generate")
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700152 private int deviceCount = DEFAULT_DEVICE_COUNT;
153
154 private static final int DEFAULT_HOST_COUNT = 5;
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700155 //@Property(name = "hostCount", intValue = DEFAULT_HOST_COUNT,
156 // label = "Number of host to generate per device")
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700157 private int hostCount = DEFAULT_HOST_COUNT;
158
Thomas Vachuskac3cdf902016-04-13 13:44:09 -0700159 private static final int DEFAULT_PACKET_RATE = 0;
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700160 //@Property(name = "packetRate", intValue = DEFAULT_PACKET_RATE,
161 // label = "Packet-in/s rate; 0 for no packets")
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700162 private int packetRate = DEFAULT_PACKET_RATE;
163
164 private static final double DEFAULT_MUTATION_RATE = 0;
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700165 //@Property(name = "mutationRate", doubleValue = DEFAULT_MUTATION_RATE,
166 // label = "Link event/s topology mutation rate; 0 for no mutations")
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700167 private double mutationRate = DEFAULT_MUTATION_RATE;
168
169 private static final String DEFAULT_MASTERSHIP = "random";
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700170 //@Property(name = "mastership", value = DEFAULT_MASTERSHIP,
171 // label = "Mastership given as 'random' or 'node1=dpid,dpid/node2=dpid,...'")
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700172 private String mastership = DEFAULT_MASTERSHIP;
173
174
175 @Activate
Thomas Vachuska41fe1ec2015-12-03 23:17:02 -0800176 public void activate() {
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700177 cfgService.registerProperties(getClass());
178
179 deviceProviderService = deviceProviderRegistry.register(deviceProvider);
180 hostProviderService = hostProviderRegistry.register(hostProvider);
181 linkProviderService = linkProviderRegistry.register(linkProvider);
182 flowRuleProviderService = flowRuleProviderRegistry.register(flowRuleProvider);
Yi Tseng3dca0f82018-04-03 14:33:03 +0800183 groupProviderService = groupProviderRegistry.register(groupProvider);
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700184 packetProviderService = packetProviderRegistry.register(packetProvider);
185 log.info("Started");
186 }
187
188 @Deactivate
Thomas Vachuska41fe1ec2015-12-03 23:17:02 -0800189 public void deactivate() {
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700190 cfgService.unregisterProperties(getClass(), false);
191 tearDown();
192
193 deviceProviderRegistry.unregister(deviceProvider);
194 hostProviderRegistry.unregister(hostProvider);
195 linkProviderRegistry.unregister(linkProvider);
196 flowRuleProviderRegistry.unregister(flowRuleProvider);
Yi Tseng3dca0f82018-04-03 14:33:03 +0800197 groupProviderRegistry.unregister(groupProvider);
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700198 packetProviderRegistry.unregister(packetProvider);
199
200 deviceProviderService = null;
201 hostProviderService = null;
202 linkProviderService = null;
203 flowRuleProviderService = null;
Yi Tseng3dca0f82018-04-03 14:33:03 +0800204 groupProviderService = null;
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700205 packetProviderService = null;
206
207 log.info("Stopped");
208 }
209
210 @Modified
211 public void modified(ComponentContext context) {
212 Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
213
214 boolean newEnabled;
215 int newDeviceCount, newHostCount, newPacketRate;
216 double newMutationRate;
217 String newTopoShape, newMastership;
218 try {
219 String s = get(properties, "enabled");
220 newEnabled = isNullOrEmpty(s) ? enabled : Boolean.parseBoolean(s.trim());
221
222 newTopoShape = get(properties, "topoShape");
223 newMastership = get(properties, "mastership");
224
225 s = get(properties, "deviceCount");
226 newDeviceCount = isNullOrEmpty(s) ? deviceCount : Integer.parseInt(s.trim());
227
228 s = get(properties, "hostCount");
229 newHostCount = isNullOrEmpty(s) ? hostCount : Integer.parseInt(s.trim());
230
231 s = get(properties, "packetRate");
232 newPacketRate = isNullOrEmpty(s) ? packetRate : Integer.parseInt(s.trim());
233
234 s = get(properties, "mutationRate");
235 newMutationRate = isNullOrEmpty(s) ? mutationRate : Double.parseDouble(s.trim());
236
237 } catch (NumberFormatException e) {
238 log.warn(e.getMessage());
239 newEnabled = enabled;
240 newTopoShape = topoShape;
241 newDeviceCount = deviceCount;
242 newHostCount = hostCount;
243 newPacketRate = packetRate;
244 newMutationRate = mutationRate;
245 newMastership = mastership;
246 }
247
248 // Any change in the following parameters implies hard restart
Thomas Vachuska8e038eb2016-02-23 23:28:23 -0800249 if (newEnabled != enabled || !Objects.equals(newTopoShape, topoShape) ||
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700250 newDeviceCount != deviceCount || newHostCount != hostCount) {
251 enabled = newEnabled;
252 topoShape = newTopoShape;
253 deviceCount = newDeviceCount;
254 hostCount = newHostCount;
255 packetRate = newPacketRate;
256 mutationRate = newMutationRate;
257 restartSimulation();
258 }
259
260 // Any change in the following parameters implies just a rate change
261 if (newPacketRate != packetRate || newMutationRate != mutationRate) {
262 packetRate = newPacketRate;
263 mutationRate = newMutationRate;
264 adjustRates();
265 }
266
267 // Any change in mastership implies just reassignments.
Thomas Vachuska8e038eb2016-02-23 23:28:23 -0800268 if (!Objects.equals(newMastership, mastership)) {
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700269 mastership = newMastership;
270 reassignMastership();
271 }
272
273 log.info(FORMAT, enabled, topoShape, deviceCount, hostCount,
274 packetRate, mutationRate);
275 }
276
277 /**
Thomas Vachuska5c6ed222016-06-29 11:02:22 +0200278 * Returns the currently active topology simulator.
279 *
280 * @return current simulator; null if none is active
281 */
282 public TopologySimulator currentSimulator() {
283 return simulator;
284 }
285
286 /**
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700287 * Severs the link between the specified end-points in both directions.
288 *
289 * @param one link endpoint
290 * @param two link endpoint
291 */
292 public void severLink(ConnectPoint one, ConnectPoint two) {
293 if (enabled) {
294 topologyMutationDriver.severLink(one, two);
295 }
296 }
297
298 /**
299 * Severs the link between the specified end-points in both directions.
300 *
301 * @param one link endpoint
302 * @param two link endpoint
303 */
304 public void repairLink(ConnectPoint one, ConnectPoint two) {
305 if (enabled) {
306 topologyMutationDriver.repairLink(one, two);
307 }
308 }
309
Thomas Vachuska8e038eb2016-02-23 23:28:23 -0800310 /**
311 * Fails the specified device.
312 *
313 * @param deviceId device identifier
314 */
315 public void failDevice(DeviceId deviceId) {
316 if (enabled) {
317 topologyMutationDriver.failDevice(deviceId);
318 }
319 }
320
321 /**
322 * Repairs the specified device.
323 *
324 * @param deviceId device identifier
325 */
326 public void repairDevice(DeviceId deviceId) {
327 if (enabled) {
328 topologyMutationDriver.repairDevice(deviceId);
329 }
330 }
331
332
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700333 // Resets simulation based on the current configuration parameters.
334 private void restartSimulation() {
335 tearDown();
336 if (enabled) {
337 setUp();
338 }
339 }
340
341 // Sets up the topology simulation and all providers.
342 private void setUp() {
343 simulator = selectSimulator(topoShape);
344 simulator.init(topoShape, deviceCount, hostCount,
345 new DefaultServiceDirectory(),
346 deviceProviderService, hostProviderService,
347 linkProviderService);
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700348 flowRuleProvider.start(flowRuleProviderService);
Yi Tseng3dca0f82018-04-03 14:33:03 +0800349 groupProvider.start(groupProviderService);
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700350 packetProvider.start(packetRate, hostService, deviceService,
351 packetProviderService);
Thomas Vachuska1cbd65e2016-06-25 16:27:57 +0200352 simulator.setUpTopology();
Yi Tseng3dca0f82018-04-03 14:33:03 +0800353 groupProvider.initDevicesGroupTable(simulator.deviceIds);
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700354 topologyMutationDriver.start(mutationRate, linkService, deviceService,
Thomas Vachuska8e038eb2016-02-23 23:28:23 -0800355 linkProviderService, deviceProviderService,
356 simulator);
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700357 }
358
359 // Selects the simulator based on the specified name.
360 private TopologySimulator selectSimulator(String topoShape) {
361 if (topoShape.matches("linear([,].*|$)")) {
362 return new LinearTopologySimulator();
363 } else if (topoShape.matches("centipede([,].*|$)")) {
364 return new CentipedeTopologySimulator();
365 } else if (topoShape.matches("reroute([,].*|$)")) {
366 return new RerouteTopologySimulator();
367 } else if (topoShape.matches("tree([,].*|$)")) {
368 return new TreeTopologySimulator();
Thomas Vachuska59da18d2015-07-07 17:44:21 -0700369 } else if (topoShape.matches("agglink([,].*|$)")) {
370 return new AggLinkTopologySimulator();
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700371 } else if (topoShape.matches("spineleaf([,].*|$)")) {
372 return new SpineLeafTopologySimulator();
373 } else if (topoShape.matches("mesh([,].*|$)")) {
374 return new MeshTopologySimulator();
Thomas Vachuska8e038eb2016-02-23 23:28:23 -0800375 } else if (topoShape.matches("grid([,].*|$)")) {
376 return new GridTopologySimulator();
Andreas Pantelopoulos620d3d72016-11-08 22:18:59 +0100377 } else if (topoShape.matches("fattree([,].*|$)")) {
378 return new FatTreeTopologySimulator();
hyunmin no97174182016-12-13 21:14:30 +0900379 } else if (topoShape.matches("chordal([,].*|$)")) {
380 return new ChordalTopologySimulator();
Thomas Vachuska5c6ed222016-06-29 11:02:22 +0200381 } else if (topoShape.matches("custom([,].*|$)")) {
382 return new CustomTopologySimulator();
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700383 } else {
384 return new ConfiguredTopologySimulator();
385 }
386 }
387
388 // Shuts down the topology simulator and all providers.
389 private void tearDown() {
390 if (simulator != null) {
391 topologyMutationDriver.stop();
392 packetProvider.stop();
393 flowRuleProvider.stop();
Yi Tseng3dca0f82018-04-03 14:33:03 +0800394 groupProvider.stop();
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700395 delay(500);
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700396 simulator.tearDownTopology();
397 simulator = null;
Thomas Vachuskacab29d22018-02-21 15:47:29 -0800398
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700399 }
400 }
401
402 // Changes packet and mutation rates.
403 private void adjustRates() {
404 packetProvider.adjustRate(packetRate);
405 topologyMutationDriver.adjustRate(mutationRate);
406 }
407
408 // Re-assigns mastership roles.
409 private void reassignMastership() {
410 if (mastership.equals(DEFAULT_MASTERSHIP)) {
411 mastershipService.balanceRoles();
412 } else {
413 NodeId localNode = clusterService.getLocalNode().id();
414 rejectMastership();
415 String[] nodeSpecs = mastership.split("/");
416 for (int i = 0; i < nodeSpecs.length; i++) {
417 String[] specs = nodeSpecs[i].split("=");
418 if (specs[0].equals(localNode.toString())) {
419 String[] ids = specs[1].split(",");
420 for (String id : ids) {
421 mastershipService.setRole(localNode, deviceId(id), MASTER);
422 }
423 break;
424 }
425 }
426 }
427 }
428
429 // Rejects mastership of all devices.
430 private void rejectMastership() {
431 NodeId localNode = clusterService.getLocalNode().id();
432 deviceService.getDevices()
433 .forEach(device -> mastershipService.setRole(localNode, device.id(),
434 NONE));
435 }
436
437 // Null provider base class.
438 abstract static class AbstractNullProvider extends AbstractProvider {
439 protected AbstractNullProvider() {
440 super(new ProviderId(SCHEME, PROVIDER_ID));
441 }
442 }
443
444 // Device provider facade.
445 private class NullDeviceProvider extends AbstractNullProvider implements DeviceProvider {
446 @Override
447 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
448 deviceProviderService.receivedRoleReply(deviceId, newRole, newRole);
449 }
450
451 @Override
452 public boolean isReachable(DeviceId deviceId) {
Thomas Vachuskab1906d22018-02-14 16:50:16 -0800453 return simulator != null &&
454 (simulator.contains(deviceId) || !deviceService.getPorts(deviceId).isEmpty()) &&
455 (simulator instanceof CustomTopologySimulator ||
Thomas Vachuska8e038eb2016-02-23 23:28:23 -0800456 topologyMutationDriver.isReachable(deviceId));
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700457 }
458
459 @Override
460 public void triggerProbe(DeviceId deviceId) {
461 }
Saurav Dasa2d37502016-03-25 17:50:40 -0700462
463 @Override
464 public void changePortState(DeviceId deviceId, PortNumber portNumber,
465 boolean enable) {
466 // TODO maybe required
467 }
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700468 }
469
470 // Host provider facade.
471 private class NullHostProvider extends AbstractNullProvider implements HostProvider {
472 @Override
473 public void triggerProbe(Host host) {
474 }
475 }
476
477 // Host provider facade.
478 private class NullLinkProvider extends AbstractNullProvider implements LinkProvider {
479 }
480
481}