Thomas Vachuska
Committed by Gerrit Code Review

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

...@@ -15,14 +15,16 @@ ...@@ -15,14 +15,16 @@
15 */ 15 */
16 package org.onlab.onos.cli.net; 16 package org.onlab.onos.cli.net;
17 17
18 +import java.util.List;
19 +
18 import org.apache.karaf.shell.commands.Argument; 20 import org.apache.karaf.shell.commands.Argument;
19 import org.apache.karaf.shell.commands.Command; 21 import org.apache.karaf.shell.commands.Command;
20 -import org.onlab.onos.cli.AbstractShellCommand;
21 import org.onlab.onos.net.HostId; 22 import org.onlab.onos.net.HostId;
22 import org.onlab.onos.net.flow.DefaultTrafficSelector; 23 import org.onlab.onos.net.flow.DefaultTrafficSelector;
23 import org.onlab.onos.net.flow.DefaultTrafficTreatment; 24 import org.onlab.onos.net.flow.DefaultTrafficTreatment;
24 import org.onlab.onos.net.flow.TrafficSelector; 25 import org.onlab.onos.net.flow.TrafficSelector;
25 import org.onlab.onos.net.flow.TrafficTreatment; 26 import org.onlab.onos.net.flow.TrafficTreatment;
27 +import org.onlab.onos.net.intent.Constraint;
26 import org.onlab.onos.net.intent.HostToHostIntent; 28 import org.onlab.onos.net.intent.HostToHostIntent;
27 import org.onlab.onos.net.intent.IntentService; 29 import org.onlab.onos.net.intent.IntentService;
28 30
...@@ -31,7 +33,7 @@ import org.onlab.onos.net.intent.IntentService; ...@@ -31,7 +33,7 @@ import org.onlab.onos.net.intent.IntentService;
31 */ 33 */
32 @Command(scope = "onos", name = "add-host-intent", 34 @Command(scope = "onos", name = "add-host-intent",
33 description = "Installs host-to-host connectivity intent") 35 description = "Installs host-to-host connectivity intent")
34 -public class AddHostToHostIntentCommand extends AbstractShellCommand { 36 +public class AddHostToHostIntentCommand extends ConnectivityIntentCommand {
35 37
36 @Argument(index = 0, name = "one", description = "One host ID", 38 @Argument(index = 0, name = "one", description = "One host ID",
37 required = true, multiValued = false) 39 required = true, multiValued = false)
...@@ -50,9 +52,11 @@ public class AddHostToHostIntentCommand extends AbstractShellCommand { ...@@ -50,9 +52,11 @@ public class AddHostToHostIntentCommand extends AbstractShellCommand {
50 52
51 TrafficSelector selector = DefaultTrafficSelector.builder().build(); 53 TrafficSelector selector = DefaultTrafficSelector.builder().build();
52 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); 54 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
55 + List<Constraint> constraints = buildConstraints();
53 56
54 HostToHostIntent intent = new HostToHostIntent(appId(), oneId, twoId, 57 HostToHostIntent intent = new HostToHostIntent(appId(), oneId, twoId,
55 - selector, treatment); 58 + selector, treatment,
59 + constraints);
56 service.submit(intent); 60 service.submit(intent);
57 } 61 }
58 62
......
...@@ -23,11 +23,13 @@ import org.onlab.onos.net.PortNumber; ...@@ -23,11 +23,13 @@ import org.onlab.onos.net.PortNumber;
23 import org.onlab.onos.net.flow.DefaultTrafficTreatment; 23 import org.onlab.onos.net.flow.DefaultTrafficTreatment;
24 import org.onlab.onos.net.flow.TrafficSelector; 24 import org.onlab.onos.net.flow.TrafficSelector;
25 import org.onlab.onos.net.flow.TrafficTreatment; 25 import org.onlab.onos.net.flow.TrafficTreatment;
26 +import org.onlab.onos.net.intent.Constraint;
26 import org.onlab.onos.net.intent.Intent; 27 import org.onlab.onos.net.intent.Intent;
27 import org.onlab.onos.net.intent.IntentService; 28 import org.onlab.onos.net.intent.IntentService;
28 import org.onlab.onos.net.intent.MultiPointToSinglePointIntent; 29 import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
29 30
30 import java.util.HashSet; 31 import java.util.HashSet;
32 +import java.util.List;
31 import java.util.Set; 33 import java.util.Set;
32 34
33 import static org.onlab.onos.net.DeviceId.deviceId; 35 import static org.onlab.onos.net.DeviceId.deviceId;
...@@ -69,9 +71,11 @@ public class AddMultiPointToSinglePointIntentCommand extends ConnectivityIntentC ...@@ -69,9 +71,11 @@ public class AddMultiPointToSinglePointIntentCommand extends ConnectivityIntentC
69 71
70 TrafficSelector selector = buildTrafficSelector(); 72 TrafficSelector selector = buildTrafficSelector();
71 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); 73 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
74 + List<Constraint> constraints = buildConstraints();
72 75
73 Intent intent = new MultiPointToSinglePointIntent(appId(), selector, treatment, 76 Intent intent = new MultiPointToSinglePointIntent(appId(), selector, treatment,
74 - ingressPoints, egress); 77 + ingressPoints, egress,
78 + constraints);
75 service.submit(intent); 79 service.submit(intent);
76 } 80 }
77 81
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onlab.onos.cli.net; 16 package org.onlab.onos.cli.net;
17 17
18 +import java.util.List;
19 +
18 import org.apache.karaf.shell.commands.Argument; 20 import org.apache.karaf.shell.commands.Argument;
19 import org.apache.karaf.shell.commands.Command; 21 import org.apache.karaf.shell.commands.Command;
20 import org.onlab.onos.net.ConnectPoint; 22 import org.onlab.onos.net.ConnectPoint;
...@@ -22,6 +24,7 @@ import org.onlab.onos.net.DeviceId; ...@@ -22,6 +24,7 @@ import org.onlab.onos.net.DeviceId;
22 import org.onlab.onos.net.PortNumber; 24 import org.onlab.onos.net.PortNumber;
23 import org.onlab.onos.net.flow.TrafficSelector; 25 import org.onlab.onos.net.flow.TrafficSelector;
24 import org.onlab.onos.net.flow.TrafficTreatment; 26 import org.onlab.onos.net.flow.TrafficTreatment;
27 +import org.onlab.onos.net.intent.Constraint;
25 import org.onlab.onos.net.intent.Intent; 28 import org.onlab.onos.net.intent.Intent;
26 import org.onlab.onos.net.intent.IntentService; 29 import org.onlab.onos.net.intent.IntentService;
27 import org.onlab.onos.net.intent.PointToPointIntent; 30 import org.onlab.onos.net.intent.PointToPointIntent;
...@@ -63,8 +66,10 @@ public class AddPointToPointIntentCommand extends ConnectivityIntentCommand { ...@@ -63,8 +66,10 @@ public class AddPointToPointIntentCommand extends ConnectivityIntentCommand {
63 TrafficSelector selector = buildTrafficSelector(); 66 TrafficSelector selector = buildTrafficSelector();
64 TrafficTreatment treatment = builder().build(); 67 TrafficTreatment treatment = builder().build();
65 68
69 + List<Constraint> constraints = buildConstraints();
70 +
66 Intent intent = new PointToPointIntent(appId(), selector, treatment, 71 Intent intent = new PointToPointIntent(appId(), selector, treatment,
67 - ingress, egress); 72 + ingress, egress, constraints);
68 service.submit(intent); 73 service.submit(intent);
69 } 74 }
70 75
......
...@@ -15,14 +15,21 @@ ...@@ -15,14 +15,21 @@
15 */ 15 */
16 package org.onlab.onos.cli.net; 16 package org.onlab.onos.cli.net;
17 17
18 +import java.util.LinkedList;
19 +import java.util.List;
20 +
18 import org.apache.karaf.shell.commands.Option; 21 import org.apache.karaf.shell.commands.Option;
19 import org.onlab.onos.cli.AbstractShellCommand; 22 import org.onlab.onos.cli.AbstractShellCommand;
20 import org.onlab.onos.net.flow.DefaultTrafficSelector; 23 import org.onlab.onos.net.flow.DefaultTrafficSelector;
21 import org.onlab.onos.net.flow.TrafficSelector; 24 import org.onlab.onos.net.flow.TrafficSelector;
25 +import org.onlab.onos.net.intent.Constraint;
26 +import org.onlab.onos.net.intent.constraint.BandwidthConstraint;
27 +import org.onlab.onos.net.intent.constraint.LambdaConstraint;
28 +import org.onlab.onos.net.resource.Bandwidth;
22 import org.onlab.packet.Ethernet; 29 import org.onlab.packet.Ethernet;
23 import org.onlab.packet.MacAddress; 30 import org.onlab.packet.MacAddress;
24 31
25 -import com.google.common.base.Strings; 32 +import static com.google.common.base.Strings.isNullOrEmpty;
26 33
27 /** 34 /**
28 * Base class for command line operations for connectivity based intents. 35 * Base class for command line operations for connectivity based intents.
...@@ -41,6 +48,14 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { ...@@ -41,6 +48,14 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
41 required = false, multiValued = false) 48 required = false, multiValued = false)
42 private String ethTypeString = ""; 49 private String ethTypeString = "";
43 50
51 + @Option(name = "-b", aliases = "--bandwidth", description = "Bandwidth",
52 + required = false, multiValued = false)
53 + private String bandwidthString = "";
54 +
55 + @Option(name = "-l", aliases = "--lambda", description = "Lambda",
56 + required = false, multiValued = false)
57 + private boolean lambda = false;
58 +
44 /** 59 /**
45 * Constructs a traffic selector based on the command line arguments 60 * Constructs a traffic selector based on the command line arguments
46 * presented to the command. 61 * presented to the command.
...@@ -50,21 +65,43 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { ...@@ -50,21 +65,43 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
50 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); 65 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
51 Short ethType = Ethernet.TYPE_IPV4; 66 Short ethType = Ethernet.TYPE_IPV4;
52 67
53 - if (!Strings.isNullOrEmpty(ethTypeString)) { 68 + if (!isNullOrEmpty(ethTypeString)) {
54 EthType ethTypeParameter = EthType.valueOf(ethTypeString); 69 EthType ethTypeParameter = EthType.valueOf(ethTypeString);
55 ethType = ethTypeParameter.value(); 70 ethType = ethTypeParameter.value();
56 } 71 }
57 selectorBuilder.matchEthType(ethType); 72 selectorBuilder.matchEthType(ethType);
58 73
59 - if (!Strings.isNullOrEmpty(srcMacString)) { 74 + if (!isNullOrEmpty(srcMacString)) {
60 selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMacString)); 75 selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMacString));
61 } 76 }
62 77
63 - if (!Strings.isNullOrEmpty(dstMacString)) { 78 + if (!isNullOrEmpty(dstMacString)) {
64 selectorBuilder.matchEthDst(MacAddress.valueOf(dstMacString)); 79 selectorBuilder.matchEthDst(MacAddress.valueOf(dstMacString));
65 } 80 }
66 81
67 return selectorBuilder.build(); 82 return selectorBuilder.build();
68 } 83 }
69 84
85 + /**
86 + * Builds the constraint list for this command based on the command line
87 + * parameters.
88 + *
89 + * @return List of constraint objects describing the constraints requested
90 + */
91 + protected List<Constraint> buildConstraints() {
92 + final List<Constraint> constraints = new LinkedList<>();
93 +
94 + // Check for a bandwidth specification
95 + if (!isNullOrEmpty(bandwidthString)) {
96 + final double bandwidthValue = Double.parseDouble(bandwidthString);
97 + constraints.add(new BandwidthConstraint(Bandwidth.valueOf(bandwidthValue)));
98 + }
99 +
100 + // Check for a lambda specification
101 + if (lambda) {
102 + constraints.add(new LambdaConstraint(null));
103 + }
104 +
105 + return constraints;
106 + }
70 } 107 }
......
...@@ -105,6 +105,7 @@ public final class HostToHostIntent extends ConnectivityIntent { ...@@ -105,6 +105,7 @@ public final class HostToHostIntent extends ConnectivityIntent {
105 .add("appId", appId()) 105 .add("appId", appId())
106 .add("selector", selector()) 106 .add("selector", selector())
107 .add("treatment", treatment()) 107 .add("treatment", treatment())
108 + .add("constraints", constraints())
108 .add("one", one) 109 .add("one", one)
109 .add("two", two) 110 .add("two", two)
110 .toString(); 111 .toString();
......
...@@ -22,6 +22,7 @@ import org.onlab.onos.net.ConnectPoint; ...@@ -22,6 +22,7 @@ import org.onlab.onos.net.ConnectPoint;
22 import org.onlab.onos.net.flow.TrafficSelector; 22 import org.onlab.onos.net.flow.TrafficSelector;
23 import org.onlab.onos.net.flow.TrafficTreatment; 23 import org.onlab.onos.net.flow.TrafficTreatment;
24 24
25 +import java.util.List;
25 import java.util.Set; 26 import java.util.Set;
26 27
27 import static com.google.common.base.Preconditions.checkArgument; 28 import static com.google.common.base.Preconditions.checkArgument;
...@@ -65,6 +66,38 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -65,6 +66,38 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
65 } 66 }
66 67
67 /** 68 /**
69 + * Creates a new multi-to-single point connectivity intent for the specified
70 + * traffic selector and treatment.
71 + *
72 + * @param appId application identifier
73 + * @param selector traffic selector
74 + * @param treatment treatment
75 + * @param ingressPoints set of ports from which ingress traffic originates
76 + * @param egressPoint port to which traffic will egress
77 + * @param constraints constraints to apply to the intent
78 + * @throws NullPointerException if {@code ingressPoints} or
79 + * {@code egressPoint} is null.
80 + * @throws IllegalArgumentException if the size of {@code ingressPoints} is
81 + * not more than 1
82 + */
83 + public MultiPointToSinglePointIntent(ApplicationId appId,
84 + TrafficSelector selector,
85 + TrafficTreatment treatment,
86 + Set<ConnectPoint> ingressPoints,
87 + ConnectPoint egressPoint,
88 + List<Constraint> constraints) {
89 + super(id(MultiPointToSinglePointIntent.class, selector, treatment,
90 + ingressPoints, egressPoint), appId, null, selector, treatment,
91 + constraints);
92 +
93 + checkNotNull(ingressPoints);
94 + checkArgument(!ingressPoints.isEmpty(), "Ingress point set cannot be empty");
95 +
96 + this.ingressPoints = Sets.newHashSet(ingressPoints);
97 + this.egressPoint = checkNotNull(egressPoint);
98 + }
99 +
100 + /**
68 * Constructor for serializer. 101 * Constructor for serializer.
69 */ 102 */
70 protected MultiPointToSinglePointIntent() { 103 protected MultiPointToSinglePointIntent() {
...@@ -101,6 +134,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -101,6 +134,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
101 .add("treatment", treatment()) 134 .add("treatment", treatment())
102 .add("ingress", ingressPoints()) 135 .add("ingress", ingressPoints())
103 .add("egress", egressPoint()) 136 .add("egress", egressPoint())
137 + .add("constraints", constraints())
104 .toString(); 138 .toString();
105 } 139 }
106 } 140 }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onlab.onos.net.intent; 16 package org.onlab.onos.net.intent;
17 17
18 +import java.util.List;
19 +
18 import com.google.common.base.MoreObjects; 20 import com.google.common.base.MoreObjects;
19 import org.onlab.onos.core.ApplicationId; 21 import org.onlab.onos.core.ApplicationId;
20 import org.onlab.onos.net.Path; 22 import org.onlab.onos.net.Path;
...@@ -46,6 +48,24 @@ public class PathIntent extends ConnectivityIntent { ...@@ -46,6 +48,24 @@ public class PathIntent extends ConnectivityIntent {
46 } 48 }
47 49
48 /** 50 /**
51 + * Creates a new point-to-point intent with the supplied ingress/egress
52 + * ports and using the specified explicit path.
53 + *
54 + * @param appId application identifier
55 + * @param selector traffic selector
56 + * @param treatment treatment
57 + * @param path traversed links
58 + * @param constraints optional list of constraints
59 + * @throws NullPointerException {@code path} is null
60 + */
61 + public PathIntent(ApplicationId appId, TrafficSelector selector,
62 + TrafficTreatment treatment, Path path, List<Constraint> constraints) {
63 + super(id(PathIntent.class, selector, treatment, path, constraints), appId,
64 + resources(path.links()), selector, treatment, constraints);
65 + this.path = path;
66 + }
67 +
68 + /**
49 * Constructor for serializer. 69 * Constructor for serializer.
50 */ 70 */
51 protected PathIntent() { 71 protected PathIntent() {
...@@ -75,6 +95,7 @@ public class PathIntent extends ConnectivityIntent { ...@@ -75,6 +95,7 @@ public class PathIntent extends ConnectivityIntent {
75 .add("appId", appId()) 95 .add("appId", appId())
76 .add("selector", selector()) 96 .add("selector", selector())
77 .add("treatment", treatment()) 97 .add("treatment", treatment())
98 + .add("constraints", constraints())
78 .add("path", path) 99 .add("path", path)
79 .toString(); 100 .toString();
80 } 101 }
......
...@@ -118,13 +118,14 @@ public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent> ...@@ -118,13 +118,14 @@ public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
118 118
119 @Override 119 @Override
120 public double weight(TopologyEdge edge) { 120 public double weight(TopologyEdge edge) {
121 - if (constraints == null) { 121 + if (constraints == null || !constraints.iterator().hasNext()) {
122 return 1.0; 122 return 1.0;
123 } 123 }
124 124
125 // iterate over all constraints in order and return the weight of 125 // iterate over all constraints in order and return the weight of
126 // the first one with fast fail over the first failure 126 // the first one with fast fail over the first failure
127 Iterator<Constraint> it = constraints.iterator(); 127 Iterator<Constraint> it = constraints.iterator();
128 +
128 double cost = it.next().cost(edge.link(), resourceService); 129 double cost = it.next().cost(edge.link(), resourceService);
129 while (it.hasNext() && cost > 0) { 130 while (it.hasNext() && cost > 0) {
130 if (it.next().cost(edge.link(), resourceService) < 0) { 131 if (it.next().cost(edge.link(), resourceService) < 0) {
...@@ -132,6 +133,7 @@ public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent> ...@@ -132,6 +133,7 @@ public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
132 } 133 }
133 } 134 }
134 return cost; 135 return cost;
136 +
135 } 137 }
136 } 138 }
137 139
......
...@@ -70,7 +70,8 @@ public class HostToHostIntentCompiler ...@@ -70,7 +70,8 @@ public class HostToHostIntentCompiler
70 HostToHostIntent intent) { 70 HostToHostIntent intent) {
71 TrafficSelector selector = builder(intent.selector()) 71 TrafficSelector selector = builder(intent.selector())
72 .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build(); 72 .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build();
73 - return new PathIntent(intent.appId(), selector, intent.treatment(), path); 73 + return new PathIntent(intent.appId(), selector, intent.treatment(),
74 + path, intent.constraints());
74 } 75 }
75 76
76 } 77 }
......
...@@ -77,7 +77,8 @@ public class PointToPointIntentCompiler ...@@ -77,7 +77,8 @@ public class PointToPointIntentCompiler
77 private Intent createPathIntent(Path path, 77 private Intent createPathIntent(Path path,
78 PointToPointIntent intent) { 78 PointToPointIntent intent) {
79 return new PathIntent(intent.appId(), 79 return new PathIntent(intent.appId(),
80 - intent.selector(), intent.treatment(), path); 80 + intent.selector(), intent.treatment(), path,
81 + intent.constraints());
81 } 82 }
82 83
83 } 84 }
......