Thomas Vachuska
Committed by Gerrit Code Review

Merge "ONOS-22 - Add Constraints to CLI Commands"

......@@ -15,14 +15,16 @@
*/
package org.onlab.onos.cli.net;
import java.util.List;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.HostId;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.intent.Constraint;
import org.onlab.onos.net.intent.HostToHostIntent;
import org.onlab.onos.net.intent.IntentService;
......@@ -31,7 +33,7 @@ import org.onlab.onos.net.intent.IntentService;
*/
@Command(scope = "onos", name = "add-host-intent",
description = "Installs host-to-host connectivity intent")
public class AddHostToHostIntentCommand extends AbstractShellCommand {
public class AddHostToHostIntentCommand extends ConnectivityIntentCommand {
@Argument(index = 0, name = "one", description = "One host ID",
required = true, multiValued = false)
......@@ -50,9 +52,11 @@ public class AddHostToHostIntentCommand extends AbstractShellCommand {
TrafficSelector selector = DefaultTrafficSelector.builder().build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
List<Constraint> constraints = buildConstraints();
HostToHostIntent intent = new HostToHostIntent(appId(), oneId, twoId,
selector, treatment);
selector, treatment,
constraints);
service.submit(intent);
}
......
......@@ -23,11 +23,13 @@ import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.intent.Constraint;
import org.onlab.onos.net.intent.Intent;
import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.onlab.onos.net.DeviceId.deviceId;
......@@ -69,9 +71,11 @@ public class AddMultiPointToSinglePointIntentCommand extends ConnectivityIntentC
TrafficSelector selector = buildTrafficSelector();
TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
List<Constraint> constraints = buildConstraints();
Intent intent = new MultiPointToSinglePointIntent(appId(), selector, treatment,
ingressPoints, egress);
ingressPoints, egress,
constraints);
service.submit(intent);
}
......
......@@ -15,6 +15,8 @@
*/
package org.onlab.onos.cli.net;
import java.util.List;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.net.ConnectPoint;
......@@ -22,6 +24,7 @@ import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.intent.Constraint;
import org.onlab.onos.net.intent.Intent;
import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.net.intent.PointToPointIntent;
......@@ -63,8 +66,10 @@ public class AddPointToPointIntentCommand extends ConnectivityIntentCommand {
TrafficSelector selector = buildTrafficSelector();
TrafficTreatment treatment = builder().build();
List<Constraint> constraints = buildConstraints();
Intent intent = new PointToPointIntent(appId(), selector, treatment,
ingress, egress);
ingress, egress, constraints);
service.submit(intent);
}
......
......@@ -15,14 +15,21 @@
*/
package org.onlab.onos.cli.net;
import java.util.LinkedList;
import java.util.List;
import org.apache.karaf.shell.commands.Option;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.intent.Constraint;
import org.onlab.onos.net.intent.constraint.BandwidthConstraint;
import org.onlab.onos.net.intent.constraint.LambdaConstraint;
import org.onlab.onos.net.resource.Bandwidth;
import org.onlab.packet.Ethernet;
import org.onlab.packet.MacAddress;
import com.google.common.base.Strings;
import static com.google.common.base.Strings.isNullOrEmpty;
/**
* Base class for command line operations for connectivity based intents.
......@@ -41,6 +48,14 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
required = false, multiValued = false)
private String ethTypeString = "";
@Option(name = "-b", aliases = "--bandwidth", description = "Bandwidth",
required = false, multiValued = false)
private String bandwidthString = "";
@Option(name = "-l", aliases = "--lambda", description = "Lambda",
required = false, multiValued = false)
private boolean lambda = false;
/**
* Constructs a traffic selector based on the command line arguments
* presented to the command.
......@@ -50,21 +65,43 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
Short ethType = Ethernet.TYPE_IPV4;
if (!Strings.isNullOrEmpty(ethTypeString)) {
if (!isNullOrEmpty(ethTypeString)) {
EthType ethTypeParameter = EthType.valueOf(ethTypeString);
ethType = ethTypeParameter.value();
}
selectorBuilder.matchEthType(ethType);
if (!Strings.isNullOrEmpty(srcMacString)) {
if (!isNullOrEmpty(srcMacString)) {
selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMacString));
}
if (!Strings.isNullOrEmpty(dstMacString)) {
if (!isNullOrEmpty(dstMacString)) {
selectorBuilder.matchEthDst(MacAddress.valueOf(dstMacString));
}
return selectorBuilder.build();
}
/**
* Builds the constraint list for this command based on the command line
* parameters.
*
* @return List of constraint objects describing the constraints requested
*/
protected List<Constraint> buildConstraints() {
final List<Constraint> constraints = new LinkedList<>();
// Check for a bandwidth specification
if (!isNullOrEmpty(bandwidthString)) {
final double bandwidthValue = Double.parseDouble(bandwidthString);
constraints.add(new BandwidthConstraint(Bandwidth.valueOf(bandwidthValue)));
}
// Check for a lambda specification
if (lambda) {
constraints.add(new LambdaConstraint(null));
}
return constraints;
}
}
......
......@@ -105,6 +105,7 @@ public final class HostToHostIntent extends ConnectivityIntent {
.add("appId", appId())
.add("selector", selector())
.add("treatment", treatment())
.add("constraints", constraints())
.add("one", one)
.add("two", two)
.toString();
......
......@@ -22,6 +22,7 @@ import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import java.util.List;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
......@@ -65,6 +66,38 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
}
/**
* Creates a new multi-to-single point connectivity intent for the specified
* traffic selector and treatment.
*
* @param appId application identifier
* @param selector traffic selector
* @param treatment treatment
* @param ingressPoints set of ports from which ingress traffic originates
* @param egressPoint port to which traffic will egress
* @param constraints constraints to apply to the intent
* @throws NullPointerException if {@code ingressPoints} or
* {@code egressPoint} is null.
* @throws IllegalArgumentException if the size of {@code ingressPoints} is
* not more than 1
*/
public MultiPointToSinglePointIntent(ApplicationId appId,
TrafficSelector selector,
TrafficTreatment treatment,
Set<ConnectPoint> ingressPoints,
ConnectPoint egressPoint,
List<Constraint> constraints) {
super(id(MultiPointToSinglePointIntent.class, selector, treatment,
ingressPoints, egressPoint), appId, null, selector, treatment,
constraints);
checkNotNull(ingressPoints);
checkArgument(!ingressPoints.isEmpty(), "Ingress point set cannot be empty");
this.ingressPoints = Sets.newHashSet(ingressPoints);
this.egressPoint = checkNotNull(egressPoint);
}
/**
* Constructor for serializer.
*/
protected MultiPointToSinglePointIntent() {
......@@ -101,6 +134,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
.add("treatment", treatment())
.add("ingress", ingressPoints())
.add("egress", egressPoint())
.add("constraints", constraints())
.toString();
}
}
......
......@@ -15,6 +15,8 @@
*/
package org.onlab.onos.net.intent;
import java.util.List;
import com.google.common.base.MoreObjects;
import org.onlab.onos.core.ApplicationId;
import org.onlab.onos.net.Path;
......@@ -46,6 +48,24 @@ public class PathIntent extends ConnectivityIntent {
}
/**
* Creates a new point-to-point intent with the supplied ingress/egress
* ports and using the specified explicit path.
*
* @param appId application identifier
* @param selector traffic selector
* @param treatment treatment
* @param path traversed links
* @param constraints optional list of constraints
* @throws NullPointerException {@code path} is null
*/
public PathIntent(ApplicationId appId, TrafficSelector selector,
TrafficTreatment treatment, Path path, List<Constraint> constraints) {
super(id(PathIntent.class, selector, treatment, path, constraints), appId,
resources(path.links()), selector, treatment, constraints);
this.path = path;
}
/**
* Constructor for serializer.
*/
protected PathIntent() {
......@@ -75,6 +95,7 @@ public class PathIntent extends ConnectivityIntent {
.add("appId", appId())
.add("selector", selector())
.add("treatment", treatment())
.add("constraints", constraints())
.add("path", path)
.toString();
}
......
......@@ -118,13 +118,14 @@ public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
@Override
public double weight(TopologyEdge edge) {
if (constraints == null) {
if (constraints == null || !constraints.iterator().hasNext()) {
return 1.0;
}
// iterate over all constraints in order and return the weight of
// the first one with fast fail over the first failure
Iterator<Constraint> it = constraints.iterator();
double cost = it.next().cost(edge.link(), resourceService);
while (it.hasNext() && cost > 0) {
if (it.next().cost(edge.link(), resourceService) < 0) {
......@@ -132,6 +133,7 @@ public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
}
}
return cost;
}
}
......
......@@ -70,7 +70,8 @@ public class HostToHostIntentCompiler
HostToHostIntent intent) {
TrafficSelector selector = builder(intent.selector())
.matchEthSrc(src.mac()).matchEthDst(dst.mac()).build();
return new PathIntent(intent.appId(), selector, intent.treatment(), path);
return new PathIntent(intent.appId(), selector, intent.treatment(),
path, intent.constraints());
}
}
......
......@@ -77,7 +77,8 @@ public class PointToPointIntentCompiler
private Intent createPathIntent(Path path,
PointToPointIntent intent) {
return new PathIntent(intent.appId(),
intent.selector(), intent.treatment(), path);
intent.selector(), intent.treatment(), path,
intent.constraints());
}
}
......