tom

Added bi-directional nature to HostToHost intent.

...@@ -8,49 +8,40 @@ import org.onlab.onos.net.flow.DefaultTrafficSelector; ...@@ -8,49 +8,40 @@ import org.onlab.onos.net.flow.DefaultTrafficSelector;
8 import org.onlab.onos.net.flow.DefaultTrafficTreatment; 8 import org.onlab.onos.net.flow.DefaultTrafficTreatment;
9 import org.onlab.onos.net.flow.TrafficSelector; 9 import org.onlab.onos.net.flow.TrafficSelector;
10 import org.onlab.onos.net.flow.TrafficTreatment; 10 import org.onlab.onos.net.flow.TrafficTreatment;
11 -import org.onlab.onos.net.host.HostService;
12 import org.onlab.onos.net.intent.HostToHostIntent; 11 import org.onlab.onos.net.intent.HostToHostIntent;
13 import org.onlab.onos.net.intent.IntentId; 12 import org.onlab.onos.net.intent.IntentId;
14 import org.onlab.onos.net.intent.IntentService; 13 import org.onlab.onos.net.intent.IntentService;
15 14
16 /** 15 /**
17 - * Lists all shortest-paths paths between the specified source and 16 + * Installs host-to-host connectivity intent.
18 - * destination devices.
19 */ 17 */
20 -@Command(scope = "onos", name = "add-intent", 18 +@Command(scope = "onos", name = "add-host-intent",
21 - description = "Installs HostToHostIntent between the specified source and destination devices") 19 + description = "Installs host-to-host connectivity intent")
22 -public class IntentInstallCommand extends AbstractShellCommand { 20 +public class AddHostToHostIntentCommand extends AbstractShellCommand {
23 21
24 - @Argument(index = 0, name = "src", description = "Source device ID", 22 + @Argument(index = 0, name = "one", description = "One host ID",
25 required = true, multiValued = false) 23 required = true, multiValued = false)
26 - String src = null; 24 + String one = null;
27 25
28 - @Argument(index = 1, name = "dst", description = "Destination device ID", 26 + @Argument(index = 1, name = "two", description = "Another host ID",
29 required = true, multiValued = false) 27 required = true, multiValued = false)
30 - String dst = null; 28 + String two = null;
31 29
32 private static long id = 1; 30 private static long id = 1;
33 31
34 @Override 32 @Override
35 protected void execute() { 33 protected void execute() {
36 IntentService service = get(IntentService.class); 34 IntentService service = get(IntentService.class);
37 - HostService hosts = get(HostService.class);
38 35
39 - HostId srcId = HostId.hostId(src); 36 + HostId oneId = HostId.hostId(one);
40 - HostId dstId = HostId.hostId(dst); 37 + HostId twoId = HostId.hostId(two);
41 38
42 - TrafficSelector.Builder builder = DefaultTrafficSelector.builder(); 39 + TrafficSelector selector = DefaultTrafficSelector.builder().build();
43 - builder.matchEthSrc(hosts.getHost(srcId).mac()) 40 + TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
44 - .matchEthDst(hosts.getHost(dstId).mac());
45 -
46 - TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
47 41
48 HostToHostIntent intent = 42 HostToHostIntent intent =
49 - new HostToHostIntent(new IntentId(id++), srcId, dstId, 43 + new HostToHostIntent(new IntentId(id++), oneId, twoId,
50 - builder.build(), treat.build()); 44 + selector, treatment);
51 -
52 - log.info("Adding intent {}", intent);
53 -
54 service.submit(intent); 45 service.submit(intent);
55 } 46 }
56 47
......
1 +package org.onlab.onos.cli.net;
2 +
3 +import org.apache.karaf.shell.commands.Command;
4 +import org.onlab.onos.cli.AbstractShellCommand;
5 +import org.onlab.onos.net.intent.Intent;
6 +import org.onlab.onos.net.intent.IntentService;
7 +
8 +/**
9 + * Lists the inventory of intents and their states.
10 + */
11 +@Command(scope = "onos", name = "intents",
12 + description = "Lists the inventory of intents and their states")
13 +public class IntentsListCommand extends AbstractShellCommand {
14 +
15 + @Override
16 + protected void execute() {
17 + IntentService service = get(IntentService.class);
18 + for (Intent intent : service.getIntents()) {
19 + print("%s", intent);
20 + }
21 + }
22 +
23 +}
...@@ -56,12 +56,16 @@ ...@@ -56,12 +56,16 @@
56 <ref component-id="deviceIdCompleter"/> 56 <ref component-id="deviceIdCompleter"/>
57 </completers> 57 </completers>
58 </command> 58 </command>
59 +
59 <command> 60 <command>
60 - <action class="org.onlab.onos.cli.net.IntentInstallCommand"/> 61 + <action class="org.onlab.onos.cli.net.AddHostToHostIntentCommand"/>
61 <completers> 62 <completers>
62 <ref component-id="hostIdCompleter"/> 63 <ref component-id="hostIdCompleter"/>
63 </completers> 64 </completers>
64 </command> 65 </command>
66 + <command>
67 + <action class="org.onlab.onos.cli.net.IntentsListCommand"/>
68 + </command>
65 69
66 <command> 70 <command>
67 <action class="org.onlab.onos.cli.net.ClustersListCommand"/> 71 <action class="org.onlab.onos.cli.net.ClustersListCommand"/>
......
...@@ -47,7 +47,23 @@ public class ConnectPoint { ...@@ -47,7 +47,23 @@ public class ConnectPoint {
47 return (DeviceId) elementId; 47 return (DeviceId) elementId;
48 } 48 }
49 throw new IllegalStateException("Connection point not associated " + 49 throw new IllegalStateException("Connection point not associated " +
50 - "with an infrastructure device"); 50 + "with an infrastructure device");
51 + }
52 +
53 + /**
54 + * Returns the identifier of the infrastructure device if the connection
55 + * point belongs to a network element which is indeed an end-station host.
56 + *
57 + * @return network element identifier as a host identifier
58 + * @throws java.lang.IllegalStateException if connection point is not
59 + * associated with a host
60 + */
61 + public HostId hostId() {
62 + if (elementId instanceof HostId) {
63 + return (HostId) elementId;
64 + }
65 + throw new IllegalStateException("Connection point not associated " +
66 + "with an end-station host");
51 } 67 }
52 68
53 /** 69 /**
......
...@@ -10,47 +10,49 @@ import java.util.Objects; ...@@ -10,47 +10,49 @@ import java.util.Objects;
10 import static com.google.common.base.Preconditions.checkNotNull; 10 import static com.google.common.base.Preconditions.checkNotNull;
11 11
12 /** 12 /**
13 - * Abstraction of end-station to end-station connectivity. 13 + * Abstraction of end-station to end-station bidirectional connectivity.
14 */ 14 */
15 public class HostToHostIntent extends ConnectivityIntent { 15 public class HostToHostIntent extends ConnectivityIntent {
16 16
17 - private final HostId src; 17 + private final HostId one;
18 - private final HostId dst; 18 + private final HostId two;
19 19
20 /** 20 /**
21 * Creates a new point-to-point intent with the supplied ingress/egress 21 * Creates a new point-to-point intent with the supplied ingress/egress
22 * ports. 22 * ports.
23 * 23 *
24 * @param intentId intent identifier 24 * @param intentId intent identifier
25 + * @param one first host
26 + * @param two second host
25 * @param selector action 27 * @param selector action
26 * @param treatment ingress port 28 * @param treatment ingress port
27 * @throws NullPointerException if {@code ingressPort} or {@code egressPort} 29 * @throws NullPointerException if {@code ingressPort} or {@code egressPort}
28 * is null. 30 * is null.
29 */ 31 */
30 - public HostToHostIntent(IntentId intentId, HostId src, HostId dst, 32 + public HostToHostIntent(IntentId intentId, HostId one, HostId two,
31 - TrafficSelector selector, TrafficTreatment treatment) { 33 + TrafficSelector selector,
34 + TrafficTreatment treatment) {
32 super(intentId, selector, treatment); 35 super(intentId, selector, treatment);
33 - this.src = checkNotNull(src); 36 + this.one = checkNotNull(one);
34 - this.dst = checkNotNull(dst); 37 + this.two = checkNotNull(two);
35 } 38 }
36 39
37 /** 40 /**
38 - * Returns the port on which the ingress traffic should be connected to the 41 + * Returns identifier of the first host.
39 - * egress.
40 * 42 *
41 - * @return ingress port 43 + * @return first host identifier
42 */ 44 */
43 - public HostId getSrc() { 45 + public HostId one() {
44 - return src; 46 + return one;
45 } 47 }
46 48
47 /** 49 /**
48 - * Returns the port on which the traffic should egress. 50 + * Returns identifier of the second host.
49 * 51 *
50 - * @return egress port 52 + * @return second host identifier
51 */ 53 */
52 - public HostId getDst() { 54 + public HostId two() {
53 - return dst; 55 + return two;
54 } 56 }
55 57
56 @Override 58 @Override
...@@ -66,13 +68,13 @@ public class HostToHostIntent extends ConnectivityIntent { ...@@ -66,13 +68,13 @@ public class HostToHostIntent extends ConnectivityIntent {
66 } 68 }
67 69
68 HostToHostIntent that = (HostToHostIntent) o; 70 HostToHostIntent that = (HostToHostIntent) o;
69 - return Objects.equals(this.src, that.src) 71 + return Objects.equals(this.one, that.one)
70 - && Objects.equals(this.dst, that.dst); 72 + && Objects.equals(this.two, that.two);
71 } 73 }
72 74
73 @Override 75 @Override
74 public int hashCode() { 76 public int hashCode() {
75 - return Objects.hash(super.hashCode(), src, dst); 77 + return Objects.hash(super.hashCode(), one, two);
76 } 78 }
77 79
78 @Override 80 @Override
...@@ -80,9 +82,9 @@ public class HostToHostIntent extends ConnectivityIntent { ...@@ -80,9 +82,9 @@ public class HostToHostIntent extends ConnectivityIntent {
80 return MoreObjects.toStringHelper(getClass()) 82 return MoreObjects.toStringHelper(getClass())
81 .add("id", getId()) 83 .add("id", getId())
82 .add("selector", getTrafficSelector()) 84 .add("selector", getTrafficSelector())
83 - .add("treatmetn", getTrafficTreatment()) 85 + .add("treatment", getTrafficTreatment())
84 - .add("src", src) 86 + .add("one", one)
85 - .add("dst", dst) 87 + .add("two", two)
86 .toString(); 88 .toString();
87 } 89 }
88 90
......
1 package org.onlab.onos.net.intent.impl; 1 package org.onlab.onos.net.intent.impl;
2 2
3 -import java.util.Arrays;
4 -import java.util.List;
5 -import java.util.Set;
6 -
7 import org.apache.felix.scr.annotations.Activate; 3 import org.apache.felix.scr.annotations.Activate;
8 import org.apache.felix.scr.annotations.Component; 4 import org.apache.felix.scr.annotations.Component;
9 import org.apache.felix.scr.annotations.Deactivate; 5 import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Reference; 6 import org.apache.felix.scr.annotations.Reference;
11 import org.apache.felix.scr.annotations.ReferenceCardinality; 7 import org.apache.felix.scr.annotations.ReferenceCardinality;
12 -import org.onlab.onos.net.ConnectPoint; 8 +import org.onlab.onos.net.Host;
9 +import org.onlab.onos.net.HostId;
13 import org.onlab.onos.net.Path; 10 import org.onlab.onos.net.Path;
14 -import org.onlab.onos.net.PortNumber; 11 +import org.onlab.onos.net.flow.TrafficSelector;
12 +import org.onlab.onos.net.host.HostService;
15 import org.onlab.onos.net.intent.HostToHostIntent; 13 import org.onlab.onos.net.intent.HostToHostIntent;
16 import org.onlab.onos.net.intent.IdGenerator; 14 import org.onlab.onos.net.intent.IdGenerator;
17 import org.onlab.onos.net.intent.Intent; 15 import org.onlab.onos.net.intent.Intent;
...@@ -21,6 +19,12 @@ import org.onlab.onos.net.intent.IntentId; ...@@ -21,6 +19,12 @@ import org.onlab.onos.net.intent.IntentId;
21 import org.onlab.onos.net.intent.PathIntent; 19 import org.onlab.onos.net.intent.PathIntent;
22 import org.onlab.onos.net.topology.PathService; 20 import org.onlab.onos.net.topology.PathService;
23 21
22 +import java.util.Arrays;
23 +import java.util.List;
24 +import java.util.Set;
25 +
26 +import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder;
27 +
24 /** 28 /**
25 * A intent compiler for {@link HostToHostIntent}. 29 * A intent compiler for {@link HostToHostIntent}.
26 */ 30 */
...@@ -34,6 +38,9 @@ public class HostToHostIntentCompiler ...@@ -34,6 +38,9 @@ public class HostToHostIntentCompiler
34 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 38 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
35 protected PathService pathService; 39 protected PathService pathService;
36 40
41 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
42 + protected HostService hostService;
43 +
37 private IdGenerator<IntentId> intentIdGenerator; 44 private IdGenerator<IntentId> intentIdGenerator;
38 45
39 @Activate 46 @Activate
...@@ -50,18 +57,34 @@ public class HostToHostIntentCompiler ...@@ -50,18 +57,34 @@ public class HostToHostIntentCompiler
50 57
51 @Override 58 @Override
52 public List<Intent> compile(HostToHostIntent intent) { 59 public List<Intent> compile(HostToHostIntent intent) {
53 - Set<Path> paths = pathService.getPaths(intent.getSrc(), intent.getDst()); 60 + Path pathOne = getPath(intent.one(), intent.two());
61 + Path pathTwo = getPath(intent.two(), intent.one());
62 +
63 + Host one = hostService.getHost(intent.one());
64 + Host two = hostService.getHost(intent.two());
65 +
66 + return Arrays.asList(createPathIntent(pathOne, one, two, intent),
67 + createPathIntent(pathTwo, two, one, intent));
68 + }
69 +
70 + // Creates a path intent from the specified path and original connectivity intent.
71 + private Intent createPathIntent(Path path, Host src, Host dst,
72 + HostToHostIntent intent) {
73 +
74 + TrafficSelector selector = builder(intent.getTrafficSelector())
75 + .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build();
76 +
77 + return new PathIntent(intentIdGenerator.getNewId(),
78 + selector, intent.getTrafficTreatment(),
79 + path.src(), path.dst(), path);
80 + }
81 +
82 + private Path getPath(HostId one, HostId two) {
83 + Set<Path> paths = pathService.getPaths(one, two);
54 if (paths.isEmpty()) { 84 if (paths.isEmpty()) {
55 - throw new PathNotFoundException(); 85 + throw new PathNotFoundException("No path from host " + one + " to " + two);
56 } 86 }
57 - Path path = paths.iterator().next(); 87 + // TODO: let's be more intelligent about this eventually
58 - 88 + return paths.iterator().next();
59 - return Arrays.asList((Intent) new PathIntent(
60 - intentIdGenerator.getNewId(),
61 - intent.getTrafficSelector(),
62 - intent.getTrafficTreatment(),
63 - new ConnectPoint(intent.getSrc(), PortNumber.ALL),
64 - new ConnectPoint(intent.getDst(), PortNumber.ALL),
65 - path));
66 } 89 }
67 } 90 }
......
...@@ -355,8 +355,8 @@ public class IntentManager ...@@ -355,8 +355,8 @@ public class IntentManager
355 private class InternalStoreDelegate implements IntentStoreDelegate { 355 private class InternalStoreDelegate implements IntentStoreDelegate {
356 @Override 356 @Override
357 public void notify(IntentEvent event) { 357 public void notify(IntentEvent event) {
358 - processStoreEvent(event);
359 eventDispatcher.post(event); 358 eventDispatcher.post(event);
359 + processStoreEvent(event);
360 } 360 }
361 } 361 }
362 362
......
1 package org.onlab.onos.net.intent.impl; 1 package org.onlab.onos.net.intent.impl;
2 2
3 -import java.util.Iterator;
4 -
5 import org.apache.felix.scr.annotations.Activate; 3 import org.apache.felix.scr.annotations.Activate;
6 import org.apache.felix.scr.annotations.Component; 4 import org.apache.felix.scr.annotations.Component;
7 import org.apache.felix.scr.annotations.Deactivate; 5 import org.apache.felix.scr.annotations.Deactivate;
...@@ -12,7 +10,6 @@ import org.onlab.onos.net.ConnectPoint; ...@@ -12,7 +10,6 @@ import org.onlab.onos.net.ConnectPoint;
12 import org.onlab.onos.net.Link; 10 import org.onlab.onos.net.Link;
13 import org.onlab.onos.net.flow.DefaultFlowRule; 11 import org.onlab.onos.net.flow.DefaultFlowRule;
14 import org.onlab.onos.net.flow.DefaultTrafficSelector; 12 import org.onlab.onos.net.flow.DefaultTrafficSelector;
15 -import org.onlab.onos.net.flow.DefaultTrafficTreatment;
16 import org.onlab.onos.net.flow.FlowRule; 13 import org.onlab.onos.net.flow.FlowRule;
17 import org.onlab.onos.net.flow.FlowRuleService; 14 import org.onlab.onos.net.flow.FlowRuleService;
18 import org.onlab.onos.net.flow.TrafficSelector; 15 import org.onlab.onos.net.flow.TrafficSelector;
...@@ -21,6 +18,10 @@ import org.onlab.onos.net.intent.IntentExtensionService; ...@@ -21,6 +18,10 @@ import org.onlab.onos.net.intent.IntentExtensionService;
21 import org.onlab.onos.net.intent.IntentInstaller; 18 import org.onlab.onos.net.intent.IntentInstaller;
22 import org.onlab.onos.net.intent.PathIntent; 19 import org.onlab.onos.net.intent.PathIntent;
23 20
21 +import java.util.Iterator;
22 +
23 +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
24 +
24 /** 25 /**
25 * Installer for {@link PathIntent path connectivity intents}. 26 * Installer for {@link PathIntent path connectivity intents}.
26 */ 27 */
...@@ -51,18 +52,16 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -51,18 +52,16 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
51 DefaultTrafficSelector.builder(intent.getTrafficSelector()); 52 DefaultTrafficSelector.builder(intent.getTrafficSelector());
52 Iterator<Link> links = intent.getPath().links().iterator(); 53 Iterator<Link> links = intent.getPath().links().iterator();
53 ConnectPoint prev = links.next().dst(); 54 ConnectPoint prev = links.next().dst();
55 +
54 while (links.hasNext()) { 56 while (links.hasNext()) {
55 builder.matchInport(prev.port()); 57 builder.matchInport(prev.port());
56 Link link = links.next(); 58 Link link = links.next();
57 - 59 + TrafficTreatment treatment = builder()
58 - TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); 60 + .setOutput(link.src().port()).build();
59 - treat.setOutput(link.src().port());
60 -
61 FlowRule rule = new DefaultFlowRule(link.src().deviceId(), 61 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
62 - builder.build(), treat.build(), 62 + builder.build(), treatment,
63 - 10, appId, 30); 63 + 123, appId, 600);
64 flowRuleService.applyFlowRules(rule); 64 flowRuleService.applyFlowRules(rule);
65 -
66 prev = link.dst(); 65 prev = link.dst();
67 } 66 }
68 67
......