Added bi-directional nature to HostToHost intent.
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/AddHostToHostIntentCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/AddHostToHostIntentCommand.java
new file mode 100644
index 0000000..be2e964
--- /dev/null
+++ b/cli/src/main/java/org/onlab/onos/cli/net/AddHostToHostIntentCommand.java
@@ -0,0 +1,48 @@
+package org.onlab.onos.cli.net;
+
+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.HostToHostIntent;
+import org.onlab.onos.net.intent.IntentId;
+import org.onlab.onos.net.intent.IntentService;
+
+/**
+ * Installs host-to-host connectivity intent.
+ */
+@Command(scope = "onos", name = "add-host-intent",
+ description = "Installs host-to-host connectivity intent")
+public class AddHostToHostIntentCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "one", description = "One host ID",
+ required = true, multiValued = false)
+ String one = null;
+
+ @Argument(index = 1, name = "two", description = "Another host ID",
+ required = true, multiValued = false)
+ String two = null;
+
+ private static long id = 1;
+
+ @Override
+ protected void execute() {
+ IntentService service = get(IntentService.class);
+
+ HostId oneId = HostId.hostId(one);
+ HostId twoId = HostId.hostId(two);
+
+ TrafficSelector selector = DefaultTrafficSelector.builder().build();
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+ HostToHostIntent intent =
+ new HostToHostIntent(new IntentId(id++), oneId, twoId,
+ selector, treatment);
+ service.submit(intent);
+ }
+
+}
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/IntentInstallCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/IntentInstallCommand.java
deleted file mode 100644
index 90b7311..0000000
--- a/cli/src/main/java/org/onlab/onos/cli/net/IntentInstallCommand.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.onlab.onos.cli.net;
-
-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.host.HostService;
-import org.onlab.onos.net.intent.HostToHostIntent;
-import org.onlab.onos.net.intent.IntentId;
-import org.onlab.onos.net.intent.IntentService;
-
-/**
- * Lists all shortest-paths paths between the specified source and
- * destination devices.
- */
-@Command(scope = "onos", name = "add-intent",
- description = "Installs HostToHostIntent between the specified source and destination devices")
-public class IntentInstallCommand extends AbstractShellCommand {
-
- @Argument(index = 0, name = "src", description = "Source device ID",
- required = true, multiValued = false)
- String src = null;
-
- @Argument(index = 1, name = "dst", description = "Destination device ID",
- required = true, multiValued = false)
- String dst = null;
-
- private static long id = 1;
-
- @Override
- protected void execute() {
- IntentService service = get(IntentService.class);
- HostService hosts = get(HostService.class);
-
- HostId srcId = HostId.hostId(src);
- HostId dstId = HostId.hostId(dst);
-
- TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
- builder.matchEthSrc(hosts.getHost(srcId).mac())
- .matchEthDst(hosts.getHost(dstId).mac());
-
- TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
-
- HostToHostIntent intent =
- new HostToHostIntent(new IntentId(id++), srcId, dstId,
- builder.build(), treat.build());
-
- log.info("Adding intent {}", intent);
-
- service.submit(intent);
- }
-
-}
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/IntentsListCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/IntentsListCommand.java
new file mode 100644
index 0000000..ad17290
--- /dev/null
+++ b/cli/src/main/java/org/onlab/onos/cli/net/IntentsListCommand.java
@@ -0,0 +1,23 @@
+package org.onlab.onos.cli.net;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.onos.cli.AbstractShellCommand;
+import org.onlab.onos.net.intent.Intent;
+import org.onlab.onos.net.intent.IntentService;
+
+/**
+ * Lists the inventory of intents and their states.
+ */
+@Command(scope = "onos", name = "intents",
+ description = "Lists the inventory of intents and their states")
+public class IntentsListCommand extends AbstractShellCommand {
+
+ @Override
+ protected void execute() {
+ IntentService service = get(IntentService.class);
+ for (Intent intent : service.getIntents()) {
+ print("%s", intent);
+ }
+ }
+
+}
diff --git a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index a096735..f0516f7 100644
--- a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -56,12 +56,16 @@
<ref component-id="deviceIdCompleter"/>
</completers>
</command>
+
<command>
- <action class="org.onlab.onos.cli.net.IntentInstallCommand"/>
+ <action class="org.onlab.onos.cli.net.AddHostToHostIntentCommand"/>
<completers>
<ref component-id="hostIdCompleter"/>
</completers>
</command>
+ <command>
+ <action class="org.onlab.onos.cli.net.IntentsListCommand"/>
+ </command>
<command>
<action class="org.onlab.onos.cli.net.ClustersListCommand"/>
diff --git a/core/api/src/main/java/org/onlab/onos/net/ConnectPoint.java b/core/api/src/main/java/org/onlab/onos/net/ConnectPoint.java
index 35adde9..17f9348 100644
--- a/core/api/src/main/java/org/onlab/onos/net/ConnectPoint.java
+++ b/core/api/src/main/java/org/onlab/onos/net/ConnectPoint.java
@@ -47,7 +47,23 @@
return (DeviceId) elementId;
}
throw new IllegalStateException("Connection point not associated " +
- "with an infrastructure device");
+ "with an infrastructure device");
+ }
+
+ /**
+ * Returns the identifier of the infrastructure device if the connection
+ * point belongs to a network element which is indeed an end-station host.
+ *
+ * @return network element identifier as a host identifier
+ * @throws java.lang.IllegalStateException if connection point is not
+ * associated with a host
+ */
+ public HostId hostId() {
+ if (elementId instanceof HostId) {
+ return (HostId) elementId;
+ }
+ throw new IllegalStateException("Connection point not associated " +
+ "with an end-station host");
}
/**
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java
index 08063f0..7cef3da 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java
@@ -10,47 +10,49 @@
import static com.google.common.base.Preconditions.checkNotNull;
/**
- * Abstraction of end-station to end-station connectivity.
+ * Abstraction of end-station to end-station bidirectional connectivity.
*/
public class HostToHostIntent extends ConnectivityIntent {
- private final HostId src;
- private final HostId dst;
+ private final HostId one;
+ private final HostId two;
/**
* Creates a new point-to-point intent with the supplied ingress/egress
* ports.
*
* @param intentId intent identifier
+ * @param one first host
+ * @param two second host
* @param selector action
* @param treatment ingress port
* @throws NullPointerException if {@code ingressPort} or {@code egressPort}
* is null.
*/
- public HostToHostIntent(IntentId intentId, HostId src, HostId dst,
- TrafficSelector selector, TrafficTreatment treatment) {
+ public HostToHostIntent(IntentId intentId, HostId one, HostId two,
+ TrafficSelector selector,
+ TrafficTreatment treatment) {
super(intentId, selector, treatment);
- this.src = checkNotNull(src);
- this.dst = checkNotNull(dst);
+ this.one = checkNotNull(one);
+ this.two = checkNotNull(two);
}
/**
- * Returns the port on which the ingress traffic should be connected to the
- * egress.
+ * Returns identifier of the first host.
*
- * @return ingress port
+ * @return first host identifier
*/
- public HostId getSrc() {
- return src;
+ public HostId one() {
+ return one;
}
/**
- * Returns the port on which the traffic should egress.
+ * Returns identifier of the second host.
*
- * @return egress port
+ * @return second host identifier
*/
- public HostId getDst() {
- return dst;
+ public HostId two() {
+ return two;
}
@Override
@@ -66,13 +68,13 @@
}
HostToHostIntent that = (HostToHostIntent) o;
- return Objects.equals(this.src, that.src)
- && Objects.equals(this.dst, that.dst);
+ return Objects.equals(this.one, that.one)
+ && Objects.equals(this.two, that.two);
}
@Override
public int hashCode() {
- return Objects.hash(super.hashCode(), src, dst);
+ return Objects.hash(super.hashCode(), one, two);
}
@Override
@@ -80,9 +82,9 @@
return MoreObjects.toStringHelper(getClass())
.add("id", getId())
.add("selector", getTrafficSelector())
- .add("treatmetn", getTrafficTreatment())
- .add("src", src)
- .add("dst", dst)
+ .add("treatment", getTrafficTreatment())
+ .add("one", one)
+ .add("two", two)
.toString();
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java
index a8bea2e..541a702 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java
@@ -1,17 +1,15 @@
package org.onlab.onos.net.intent.impl;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.Host;
+import org.onlab.onos.net.HostId;
import org.onlab.onos.net.Path;
-import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.intent.HostToHostIntent;
import org.onlab.onos.net.intent.IdGenerator;
import org.onlab.onos.net.intent.Intent;
@@ -21,6 +19,12 @@
import org.onlab.onos.net.intent.PathIntent;
import org.onlab.onos.net.topology.PathService;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder;
+
/**
* A intent compiler for {@link HostToHostIntent}.
*/
@@ -34,6 +38,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PathService pathService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected HostService hostService;
+
private IdGenerator<IntentId> intentIdGenerator;
@Activate
@@ -50,18 +57,34 @@
@Override
public List<Intent> compile(HostToHostIntent intent) {
- Set<Path> paths = pathService.getPaths(intent.getSrc(), intent.getDst());
- if (paths.isEmpty()) {
- throw new PathNotFoundException();
- }
- Path path = paths.iterator().next();
+ Path pathOne = getPath(intent.one(), intent.two());
+ Path pathTwo = getPath(intent.two(), intent.one());
- return Arrays.asList((Intent) new PathIntent(
- intentIdGenerator.getNewId(),
- intent.getTrafficSelector(),
- intent.getTrafficTreatment(),
- new ConnectPoint(intent.getSrc(), PortNumber.ALL),
- new ConnectPoint(intent.getDst(), PortNumber.ALL),
- path));
+ Host one = hostService.getHost(intent.one());
+ Host two = hostService.getHost(intent.two());
+
+ return Arrays.asList(createPathIntent(pathOne, one, two, intent),
+ createPathIntent(pathTwo, two, one, intent));
+ }
+
+ // Creates a path intent from the specified path and original connectivity intent.
+ private Intent createPathIntent(Path path, Host src, Host dst,
+ HostToHostIntent intent) {
+
+ TrafficSelector selector = builder(intent.getTrafficSelector())
+ .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build();
+
+ return new PathIntent(intentIdGenerator.getNewId(),
+ selector, intent.getTrafficTreatment(),
+ path.src(), path.dst(), path);
+ }
+
+ private Path getPath(HostId one, HostId two) {
+ Set<Path> paths = pathService.getPaths(one, two);
+ if (paths.isEmpty()) {
+ throw new PathNotFoundException("No path from host " + one + " to " + two);
+ }
+ // TODO: let's be more intelligent about this eventually
+ return paths.iterator().next();
}
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
index f1c9de3..769e4c7 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
@@ -355,8 +355,8 @@
private class InternalStoreDelegate implements IntentStoreDelegate {
@Override
public void notify(IntentEvent event) {
- processStoreEvent(event);
eventDispatcher.post(event);
+ processStoreEvent(event);
}
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
index 84e8c79..ec7841c 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
@@ -1,7 +1,5 @@
package org.onlab.onos.net.intent.impl;
-import java.util.Iterator;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -12,7 +10,6 @@
import org.onlab.onos.net.Link;
import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
-import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleService;
import org.onlab.onos.net.flow.TrafficSelector;
@@ -21,6 +18,10 @@
import org.onlab.onos.net.intent.IntentInstaller;
import org.onlab.onos.net.intent.PathIntent;
+import java.util.Iterator;
+
+import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
+
/**
* Installer for {@link PathIntent path connectivity intents}.
*/
@@ -51,18 +52,16 @@
DefaultTrafficSelector.builder(intent.getTrafficSelector());
Iterator<Link> links = intent.getPath().links().iterator();
ConnectPoint prev = links.next().dst();
+
while (links.hasNext()) {
builder.matchInport(prev.port());
Link link = links.next();
-
- TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
- treat.setOutput(link.src().port());
-
+ TrafficTreatment treatment = builder()
+ .setOutput(link.src().port()).build();
FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
- builder.build(), treat.build(),
- 10, appId, 30);
+ builder.build(), treatment,
+ 123, appId, 600);
flowRuleService.applyFlowRules(rule);
-
prev = link.dst();
}