Thomas Vachuska

Enhancing null providers for use in demos.

Change-Id: I079d19a98fba2312bd4b17d2e275b34f4dee6f19
/*
* 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 com.google.common.collect.Maps;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostId;
import java.util.Map;
import static org.onlab.util.Tools.toHex;
import static org.onosproject.provider.nil.NullProviders.SCHEME;
/**
* Custom topology defined by a concise language.
*/
public class CustomTopologySimulator extends TopologySimulator {
private int nextDeviceId = 0;
private int nextHostId = 0;
private Map<String, DeviceId> nameToId = Maps.newConcurrentMap();
/**
* Returns the next device id.
*
* @return the next device id
*/
public DeviceId nextDeviceId() {
return DeviceId.deviceId(SCHEME + ":" + toHex(++nextDeviceId));
}
/**
* Returns the next host id.
*
* @return the next host id
*/
public HostId nextHostId() {
return HostId.hostId(MacAddress.valueOf(nextHostId), VlanId.NONE);
}
/**
* Returns the identifier of the device with the specified alias.
*
* @param name device name
* @return device identifier
*/
public DeviceId deviceId(String name) {
return nameToId.get(name);
}
/**
* Creates simulated device.
*
* @param id device identifier
* @param name device name
* @param type device type
* @param portCount number of device ports
*/
public void createDevice(DeviceId id, String name, Device.Type type, int portCount) {
int chassisId = Integer.parseInt(id.uri().getSchemeSpecificPart());
createDevice(id, chassisId, type, portCount);
nameToId.put(name, id);
}
@Override
protected void createDevices() {
}
@Override
protected void createLinks() {
}
@Override
protected void createHosts() {
}
}
......@@ -268,6 +268,15 @@ public class NullProviders {
}
/**
* Returns the currently active topology simulator.
*
* @return current simulator; null if none is active
*/
public TopologySimulator currentSimulator() {
return simulator;
}
/**
* Severs the link between the specified end-points in both directions.
*
* @param one link endpoint
......@@ -356,6 +365,8 @@ public class NullProviders {
return new MeshTopologySimulator();
} else if (topoShape.matches("grid([,].*|$)")) {
return new GridTopologySimulator();
} else if (topoShape.matches("custom([,].*|$)")) {
return new CustomTopologySimulator();
} else {
return new ConfiguredTopologySimulator();
}
......@@ -424,7 +435,7 @@ public class NullProviders {
@Override
public boolean isReachable(DeviceId deviceId) {
return topoShape.equals("configured") ||
return topoShape.equals("custom") ||
(simulator != null && simulator.contains(deviceId) &&
topologyMutationDriver.isReachable(deviceId));
}
......
......@@ -185,16 +185,28 @@ public abstract class TopologySimulator {
/**
* Creates simulated device.
*
* @param id device identifier
* @param id device identifier
* @param chassisId chassis identifier number
*/
protected void createDevice(DeviceId id, int chassisId) {
public void createDevice(DeviceId id, int chassisId) {
createDevice(id, chassisId, Device.Type.SWITCH, hostCount + infrastructurePorts);
}
/**
* Creates simulated device.
*
* @param id device identifier
* @param chassisId chassis identifier number
* @param type device type
* @param portCount number of device ports
*/
public void createDevice(DeviceId id, int chassisId, Device.Type type, int portCount) {
DeviceDescription desc =
new DefaultDeviceDescription(id.uri(), Device.Type.SWITCH,
new DefaultDeviceDescription(id.uri(), type,
"ON.Lab", "0.1", "0.1", "1234",
new ChassisId(chassisId));
deviceProviderService.deviceConnected(id, desc);
deviceProviderService.updatePorts(id, buildPorts(hostCount + infrastructurePorts));
deviceProviderService.updatePorts(id, buildPorts(portCount));
}
/**
......@@ -205,7 +217,7 @@ public abstract class TopologySimulator {
* @param pi port number of i-th device
* @param pj port number of j-th device
*/
protected void createLink(int i, int j, int pi, int pj) {
public 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);
......@@ -214,12 +226,26 @@ public abstract class TopologySimulator {
/**
* Creates simulated link between two connection points.
*
* @param one one connection point
* @param two another connection point
* @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));
public void createLink(ConnectPoint one, ConnectPoint two) {
createLink(one, two, DIRECT, true);
}
/**
* Creates simulated link between two connection points.
*
* @param one one connection point
* @param two another connection point
* @param type link type
* @param isBidirectional true if link is bidirectional
*/
public void createLink(ConnectPoint one, ConnectPoint two, Link.Type type, boolean isBidirectional) {
linkProviderService.linkDetected(new DefaultLinkDescription(one, two, type));
if (isBidirectional) {
linkProviderService.linkDetected(new DefaultLinkDescription(two, one, type));
}
}
/**
......@@ -228,7 +254,7 @@ public abstract class TopologySimulator {
* @param deviceId device identifier
* @param portOffset port offset where to start attaching hosts
*/
protected void createHosts(DeviceId deviceId, int portOffset) {
public void createHosts(DeviceId deviceId, int portOffset) {
String s = deviceId.toString();
byte dByte = Byte.parseByte(s.substring(s.length() - 2), 16);
// TODO: this limits the simulation to 256 devices & 256 hosts/device.
......
/*
* 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.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.basics.BasicDeviceConfig;
import org.onosproject.provider.nil.CustomTopologySimulator;
import org.onosproject.provider.nil.NullProviders;
import org.onosproject.provider.nil.TopologySimulator;
/**
* Adds a simulated device to the custom topology simulation.
*/
@Command(scope = "onos", name = "null-create-device",
description = "Adds a simulated device to the custom topology simulation")
public class CreateNullDevice extends AbstractShellCommand {
@Argument(index = 0, name = "type", description = "Device type, e.g. switch, roadm",
required = true, multiValued = false)
String type = null;
@Argument(index = 1, name = "name", description = "Device name",
required = true, multiValued = false)
String name = null;
@Argument(index = 2, name = "portCount", description = "Port count",
required = true, multiValued = false)
Integer portCount = null;
@Argument(index = 3, name = "latitude", description = "Geo latitude",
required = true, multiValued = false)
Double latitude = null;
@Argument(index = 4, name = "longitude", description = "Geo longitude",
required = true, multiValued = false)
Double longitude = null;
@Override
protected void execute() {
NullProviders service = get(NullProviders.class);
NetworkConfigService cfgService = get(NetworkConfigService.class);
TopologySimulator simulator = service.currentSimulator();
if (!(simulator instanceof CustomTopologySimulator)) {
error("Custom topology simulator is not active.");
return;
}
CustomTopologySimulator sim = (CustomTopologySimulator) simulator;
DeviceId deviceId = sim.nextDeviceId();
BasicDeviceConfig cfg = cfgService.addConfig(deviceId, BasicDeviceConfig.class);
cfg.name(name);
cfg.latitude(latitude);
cfg.longitude(longitude);
cfg.apply();
sim.createDevice(deviceId, name, Device.Type.valueOf(type.toUpperCase()), portCount);
}
}
/*
* 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.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.edge.EdgePortService;
import org.onosproject.provider.nil.CustomTopologySimulator;
import org.onosproject.provider.nil.NullProviders;
import org.onosproject.provider.nil.TopologySimulator;
import java.util.Iterator;
/**
* Adds a simulated link to the custom topology simulation.
*/
@Command(scope = "onos", name = "null-create-link",
description = "Adds a simulated link to the custom topology simulation")
public class CreateNullLink extends AbstractShellCommand {
@Argument(index = 0, name = "type", description = "Link type, e.g. direct, indirect, optical",
required = true, multiValued = false)
String type = null;
@Argument(index = 1, name = "src", description = "Source device name",
required = true, multiValued = false)
String src = null;
@Argument(index = 2, name = "dst", description = "Destination device name",
required = true, multiValued = false)
String dst = null;
@Option(name = "-u", aliases = "--unidirectional", description = "Unidirectional link only",
required = false, multiValued = false)
private boolean unidirectional = false;
@Override
protected void execute() {
NullProviders service = get(NullProviders.class);
TopologySimulator simulator = service.currentSimulator();
if (!(simulator instanceof CustomTopologySimulator)) {
error("Custom topology simulator is not active.");
return;
}
CustomTopologySimulator sim = (CustomTopologySimulator) simulator;
ConnectPoint one = findAvailablePort(sim.deviceId(src));
ConnectPoint two = findAvailablePort(sim.deviceId(dst));
sim.createLink(one, two, Link.Type.valueOf(type.toUpperCase()), !unidirectional);
}
private ConnectPoint findAvailablePort(DeviceId deviceId) {
EdgePortService eps = get(EdgePortService.class);
Iterator<ConnectPoint> points = eps.getEdgePoints(deviceId).iterator();
return points.hasNext() ? points.next() : null;
}
}
......@@ -25,10 +25,10 @@ import static org.onosproject.cli.UpDownCompleter.DOWN;
import static org.onosproject.cli.UpDownCompleter.UP;
/**
* Servers or repairs a simulated link.
* Downs or repairs a simulated device.
*/
@Command(scope = "onos", name = "null-device",
description = "Severs or repairs a simulated link")
description = "Downs or repairs a simulated device")
public class NullDeviceCommand extends AbstractShellCommand {
@Argument(index = 0, name = "id", description = "Device identifier",
......
......@@ -25,7 +25,7 @@ import static org.onosproject.cli.UpDownCompleter.DOWN;
import static org.onosproject.cli.UpDownCompleter.UP;
/**
* Servers or repairs a simulated link.
* Severs or repairs a simulated link.
*/
@Command(scope = "onos", name = "null-link",
description = "Severs or repairs a simulated link")
......
......@@ -41,6 +41,12 @@
<null/>
</completers>
</command>
<command>
<action class="org.onosproject.provider.nil.cli.CreateNullDevice"/>
</command>
<command>
<action class="org.onosproject.provider.nil.cli.CreateNullLink"/>
</command>
</command-bundle>
<bean id="startStopCompleter" class="org.onosproject.cli.StartStopCompleter"/>
......