Adding a grid topology simulator to the null provider.
Change-Id: Ie655840febc11d3986f1c8ec5c8ef2374014794c
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/CentipedeTopologySimulator.java b/providers/null/src/main/java/org/onosproject/provider/nil/CentipedeTopologySimulator.java
index 5234d44..877f7f6 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/CentipedeTopologySimulator.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/CentipedeTopologySimulator.java
@@ -20,9 +20,7 @@
*/
public class CentipedeTopologySimulator extends LinearTopologySimulator {
- /**
- * Creates simulated hosts.
- */
+ @Override
protected void createHosts() {
deviceIds.forEach(id -> createHosts(id, infrastructurePorts));
}
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/GridTopologySimulator.java b/providers/null/src/main/java/org/onosproject/provider/nil/GridTopologySimulator.java
new file mode 100644
index 0000000..2f9c644
--- /dev/null
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/GridTopologySimulator.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.nil;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Rectangular grid topology with hosts at each device.
+ */
+public class GridTopologySimulator extends TopologySimulator {
+
+ private int cols;
+ private int rows;
+
+ @Override
+ protected void processTopoShape(String shape) {
+ super.processTopoShape(shape);
+ rows = topoShape.length > 1 ? Integer.parseInt(topoShape[1]) : 10;
+ cols = topoShape.length > 2 ? Integer.parseInt(topoShape[2]) : rows;
+ hostCount = topoShape.length > 3 ? Integer.parseInt(topoShape[3]) : 1;
+ infrastructurePorts = 4;
+ deviceCount = rows * cols;
+ }
+
+ @Override
+ public void setUpTopology() {
+ checkArgument(rows > 1, "There must be at least 2 rows");
+ checkArgument(cols > 1, "There must be at least 2 columns");
+ super.setUpTopology();
+ }
+
+ @Override
+ protected void createLinks() {
+ for (int r = 0; r < rows; r++) {
+ for (int c = 0; c < cols; c++) {
+ int i = r * cols + c;
+ if (c < cols - 1) {
+ createLink(i, i + 1, 3, 1);
+ }
+ if (r < rows - 1) {
+ createLink(i, (r + 1) * cols + c, 4, 2);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void createHosts() {
+ deviceIds.forEach(id -> createHosts(id, infrastructurePorts));
+ }
+
+}
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java b/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java
index 68c536b..fb1823d 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java
@@ -54,6 +54,7 @@
import org.slf4j.Logger;
import java.util.Dictionary;
+import java.util.Objects;
import java.util.Properties;
import static com.google.common.base.Strings.isNullOrEmpty;
@@ -116,7 +117,6 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketProviderRegistry packetProviderRegistry;
-
private final NullDeviceProvider deviceProvider = new NullDeviceProvider();
private final NullLinkProvider linkProvider = new NullLinkProvider();
private final NullHostProvider hostProvider = new NullHostProvider();
@@ -138,7 +138,7 @@
private static final String DEFAULT_TOPO_SHAPE = "configured";
@Property(name = "topoShape", value = DEFAULT_TOPO_SHAPE,
- label = "Topology shape: configured, linear, reroute, tree, spineleaf, mesh")
+ label = "Topology shape: configured, linear, reroute, tree, spineleaf, mesh, grid")
private String topoShape = DEFAULT_TOPO_SHAPE;
private static final int DEFAULT_DEVICE_COUNT = 10;
@@ -238,7 +238,7 @@
}
// Any change in the following parameters implies hard restart
- if (newEnabled != enabled || !newTopoShape.equals(topoShape) ||
+ if (newEnabled != enabled || !Objects.equals(newTopoShape, topoShape) ||
newDeviceCount != deviceCount || newHostCount != hostCount) {
enabled = newEnabled;
topoShape = newTopoShape;
@@ -257,7 +257,7 @@
}
// Any change in mastership implies just reassignments.
- if (!newMastership.equals(mastership)) {
+ if (!Objects.equals(newMastership, mastership)) {
mastership = newMastership;
reassignMastership();
}
@@ -290,6 +290,29 @@
}
}
+ /**
+ * Fails the specified device.
+ *
+ * @param deviceId device identifier
+ */
+ public void failDevice(DeviceId deviceId) {
+ if (enabled) {
+ topologyMutationDriver.failDevice(deviceId);
+ }
+ }
+
+ /**
+ * Repairs the specified device.
+ *
+ * @param deviceId device identifier
+ */
+ public void repairDevice(DeviceId deviceId) {
+ if (enabled) {
+ topologyMutationDriver.repairDevice(deviceId);
+ }
+ }
+
+
// Resets simulation based on the current configuration parameters.
private void restartSimulation() {
tearDown();
@@ -310,7 +333,8 @@
packetProvider.start(packetRate, hostService, deviceService,
packetProviderService);
topologyMutationDriver.start(mutationRate, linkService, deviceService,
- linkProviderService);
+ linkProviderService, deviceProviderService,
+ simulator);
}
// Selects the simulator based on the specified name.
@@ -329,6 +353,8 @@
return new SpineLeafTopologySimulator();
} else if (topoShape.matches("mesh([,].*|$)")) {
return new MeshTopologySimulator();
+ } else if (topoShape.matches("grid([,].*|$)")) {
+ return new GridTopologySimulator();
} else {
return new ConfiguredTopologySimulator();
}
@@ -398,7 +424,8 @@
@Override
public boolean isReachable(DeviceId deviceId) {
return topoShape.equals("configured") ||
- (simulator != null && simulator.contains(deviceId));
+ (simulator != null && simulator.contains(deviceId) &&
+ topologyMutationDriver.isReachable(deviceId));
}
@Override
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/TopologyMutationDriver.java b/providers/null/src/main/java/org/onosproject/provider/nil/TopologyMutationDriver.java
index ccf7e08..032692d 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/TopologyMutationDriver.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/TopologyMutationDriver.java
@@ -16,7 +16,11 @@
package org.onosproject.provider.nil;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.link.DefaultLinkDescription;
import org.onosproject.net.link.LinkDescription;
@@ -26,7 +30,9 @@
import org.slf4j.LoggerFactory;
import java.util.List;
+import java.util.Map;
import java.util.Random;
+import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
@@ -57,6 +63,8 @@
private LinkService linkService;
private DeviceService deviceService;
private LinkProviderService linkProviderService;
+ private DeviceProviderService deviceProviderService;
+ private TopologySimulator simulator;
private List<LinkDescription> activeLinks;
private List<LinkDescription> inactiveLinks;
@@ -64,21 +72,30 @@
private final ExecutorService executor =
newSingleThreadScheduledExecutor(groupedThreads("onos/null", "topo-mutator"));
+ private Map<DeviceId, Set<Link>> savedLinks = Maps.newConcurrentMap();
+
/**
* Starts the mutation process.
*
- * @param mutationRate link events per second
- * @param linkService link service
- * @param deviceService device service
- * @param linkProviderService link provider service
+ * @param mutationRate link events per second
+ * @param linkService link service
+ * @param deviceService device service
+ * @param linkProviderService link provider service
+ * @param deviceProviderService device provider service
+ * @param simulator topology simulator
*/
void start(double mutationRate,
LinkService linkService, DeviceService deviceService,
- LinkProviderService linkProviderService) {
+ LinkProviderService linkProviderService,
+ DeviceProviderService deviceProviderService,
+ TopologySimulator simulator) {
+ savedLinks.clear();
stopped = false;
this.linkService = linkService;
this.deviceService = deviceService;
this.linkProviderService = linkProviderService;
+ this.deviceProviderService = deviceProviderService;
+ this.simulator = simulator;
activeLinks = reduceLinks();
inactiveLinks = Lists.newArrayList();
adjustRate(mutationRate);
@@ -134,6 +151,41 @@
linkProviderService.linkDetected(reverse(link));
}
+ /**
+ * Fails the specified device.
+ *
+ * @param deviceId device identifier
+ */
+ void failDevice(DeviceId deviceId) {
+ savedLinks.put(deviceId, linkService.getDeviceLinks(deviceId));
+ deviceProviderService.deviceDisconnected(deviceId);
+ }
+
+ /**
+ * Repairs the specified device.
+ *
+ * @param deviceId device identifier
+ */
+ void repairDevice(DeviceId deviceId) {
+ int chassisId = Integer.parseInt(deviceId.uri().getSchemeSpecificPart());
+ simulator.createDevice(deviceId, chassisId);
+ Set<Link> links = savedLinks.remove(deviceId);
+ if (links != null) {
+ links.forEach(l -> linkProviderService
+ .linkDetected(new DefaultLinkDescription(l.src(), l.dst(), DIRECT)));
+ }
+ }
+
+ /**
+ * Returns whether the given device is considered reachable or not.
+ *
+ * @param deviceId device identifier
+ * @return true if device is reachable
+ */
+ boolean isReachable(DeviceId deviceId) {
+ return !savedLinks.containsKey(deviceId);
+ }
+
@Override
public void run() {
delay(WAIT_DELAY);
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/TopologySimulator.java b/providers/null/src/main/java/org/onosproject/provider/nil/TopologySimulator.java
index a00456e..d0d238b 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/TopologySimulator.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/TopologySimulator.java
@@ -172,31 +172,31 @@
protected abstract void createHosts();
/**
- * Creates simulated device.
+ * Creates simulated device and adds its id to the list of devices ids.
*
* @param i index of the device id in the list.
*/
protected void createDevice(int i) {
DeviceId id = DeviceId.deviceId(SCHEME + ":" + toHex(i));
+ deviceIds.add(id);
+ createDevice(id, i);
+ }
+
+ /**
+ * Creates simulated device.
+ *
+ * @param id device identifier
+ * @param chassisId chassis identifier number
+ */
+ protected void createDevice(DeviceId id, int chassisId) {
DeviceDescription desc =
new DefaultDeviceDescription(id.uri(), Device.Type.SWITCH,
"ON.Lab", "0.1", "0.1", "1234",
- new ChassisId(i));
- deviceIds.add(id);
+ new ChassisId(chassisId));
deviceProviderService.deviceConnected(id, desc);
deviceProviderService.updatePorts(id, buildPorts(hostCount + infrastructurePorts));
}
-// /**
-// * Creates simulated link between two devices on port 1 and port 2.
-// *
-// * @param i index of one simulated device
-// * @param j index of another simulated device
-// */
-// protected void createLink(int i, int j) {
-// createLink(i, j, 1, 2);
-// }
-
/**
* Creates simulated link between two devices.
*
@@ -208,6 +208,16 @@
protected void createLink(int i, int j, int pi, int pj) {
ConnectPoint one = new ConnectPoint(deviceIds.get(i), PortNumber.portNumber(pi));
ConnectPoint two = new ConnectPoint(deviceIds.get(j), PortNumber.portNumber(pj));
+ createLink(one, two);
+ }
+
+ /**
+ * Creates simulated link between two connection points.
+ *
+ * @param one one connection point
+ * @param two another connection point
+ */
+ protected void createLink(ConnectPoint one, ConnectPoint two) {
linkProviderService.linkDetected(new DefaultLinkDescription(one, two, DIRECT));
linkProviderService.linkDetected(new DefaultLinkDescription(two, one, DIRECT));
}
@@ -359,7 +369,7 @@
}
/**
- * Indicates whether or not the simulation knows of this device.
+ * Indicates whether or not the simulation deeps the device as available.
*
* @param deviceId device identifier
* @return true if device is known
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/TreeTopologySimulator.java b/providers/null/src/main/java/org/onosproject/provider/nil/TreeTopologySimulator.java
index 2c04933..64aafa4 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/TreeTopologySimulator.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/TreeTopologySimulator.java
@@ -55,6 +55,7 @@
@Override
protected void createLinks() {
+
int portOffset = 1;
for (int t = 1; t < tierOffset.length; t++) {
int child = tierOffset[t];
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullDeviceCommand.java b/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullDeviceCommand.java
new file mode 100644
index 0000000..00bc5b9
--- /dev/null
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullDeviceCommand.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.nil.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.onosproject.provider.nil.NullProviders;
+
+import static org.onosproject.cli.UpDownCompleter.DOWN;
+import static org.onosproject.cli.UpDownCompleter.UP;
+
+/**
+ * Servers or repairs a simulated link.
+ */
+@Command(scope = "onos", name = "null-device",
+ description = "Severs or repairs a simulated link")
+public class NullDeviceCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "id", description = "Device identifier",
+ required = true, multiValued = false)
+ String id = null;
+
+ @Argument(index = 1, name = "cmd", description = "up/down",
+ required = true, multiValued = false)
+ String cmd = null;
+
+
+ @Override
+ protected void execute() {
+ NullProviders service = get(NullProviders.class);
+ DeviceId deviceId = DeviceId.deviceId(id);
+
+ if (cmd.equals(UP)) {
+ service.repairDevice(deviceId);
+ } else if (cmd.equals(DOWN)) {
+ service.failDevice(deviceId);
+ } else {
+ error("Illegal command %s; must be up or down", cmd);
+ }
+ }
+
+}
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullLinkCommand.java b/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullLinkCommand.java
index a76da3b..be7d375 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullLinkCommand.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullLinkCommand.java
@@ -50,7 +50,6 @@
try {
ConnectPoint onePoint = ConnectPoint.deviceConnectPoint(one);
-
ConnectPoint twoPoint = ConnectPoint.deviceConnectPoint(two);
if (cmd.equals(UP)) {
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/cli/TopologyShapeCompleter.java b/providers/null/src/main/java/org/onosproject/provider/nil/cli/TopologyShapeCompleter.java
index fad29b6..dbb386d 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/cli/TopologyShapeCompleter.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/cli/TopologyShapeCompleter.java
@@ -27,6 +27,6 @@
@Override
public List<String> choices() {
return ImmutableList.of("configured", "linear", "reroute", "centipede",
- "tree", "spineleaf", "mesh");
+ "tree", "spineleaf", "mesh", "grid");
}
}
diff --git a/providers/null/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/providers/null/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index f96f10c..1fc180a 100644
--- a/providers/null/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/providers/null/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -33,6 +33,14 @@
<null/>
</completers>
</command>
+ <command>
+ <action class="org.onosproject.provider.nil.cli.NullDeviceCommand"/>
+ <completers>
+ <ref component-id="deviceIdCompleter"/>
+ <ref component-id="upDownCompleter"/>
+ <null/>
+ </completers>
+ </command>
</command-bundle>
<bean id="startStopCompleter" class="org.onosproject.cli.StartStopCompleter"/>
@@ -40,5 +48,6 @@
<bean id="topoShapeCompleter" class="org.onosproject.provider.nil.cli.TopologyShapeCompleter"/>
<bean id="linkSrcCompleter" class="org.onosproject.cli.net.LinkSrcCompleter"/>
<bean id="linkDstCompleter" class="org.onosproject.cli.net.LinkDstCompleter"/>
+ <bean id="deviceIdCompleter" class="org.onosproject.cli.net.DeviceIdCompleter"/>
</blueprint>