tom

Added bi-directional nature to HostToHost intent.

......@@ -8,49 +8,40 @@ 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.
* Installs host-to-host connectivity intent.
*/
@Command(scope = "onos", name = "add-intent",
description = "Installs HostToHostIntent between the specified source and destination devices")
public class IntentInstallCommand extends AbstractShellCommand {
@Command(scope = "onos", name = "add-host-intent",
description = "Installs host-to-host connectivity intent")
public class AddHostToHostIntentCommand extends AbstractShellCommand {
@Argument(index = 0, name = "src", description = "Source device ID",
@Argument(index = 0, name = "one", description = "One host ID",
required = true, multiValued = false)
String src = null;
String one = null;
@Argument(index = 1, name = "dst", description = "Destination device ID",
@Argument(index = 1, name = "two", description = "Another host ID",
required = true, multiValued = false)
String dst = null;
String two = 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);
HostId oneId = HostId.hostId(one);
HostId twoId = HostId.hostId(two);
TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
builder.matchEthSrc(hosts.getHost(srcId).mac())
.matchEthDst(hosts.getHost(dstId).mac());
TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
TrafficSelector selector = DefaultTrafficSelector.builder().build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
HostToHostIntent intent =
new HostToHostIntent(new IntentId(id++), srcId, dstId,
builder.build(), treat.build());
log.info("Adding intent {}", intent);
new HostToHostIntent(new IntentId(id++), oneId, twoId,
selector, treatment);
service.submit(intent);
}
......
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);
}
}
}
......@@ -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"/>
......
......@@ -51,6 +51,22 @@ public class ConnectPoint {
}
/**
* 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");
}
/**
* Returns the connection port number.
*
* @return port number
......
......@@ -10,47 +10,49 @@ import java.util.Objects;
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 @@ public class HostToHostIntent extends ConnectivityIntent {
}
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 @@ public class HostToHostIntent extends ConnectivityIntent {
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();
}
......
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.IntentId;
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 @@ public class HostToHostIntentCompiler
@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 @@ public class HostToHostIntentCompiler
@Override
public List<Intent> compile(HostToHostIntent intent) {
Set<Path> paths = pathService.getPaths(intent.getSrc(), intent.getDst());
Path pathOne = getPath(intent.one(), intent.two());
Path pathTwo = getPath(intent.two(), intent.one());
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();
throw new PathNotFoundException("No path from host " + one + " to " + two);
}
Path path = paths.iterator().next();
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));
// TODO: let's be more intelligent about this eventually
return paths.iterator().next();
}
}
......
......@@ -355,8 +355,8 @@ public class IntentManager
private class InternalStoreDelegate implements IntentStoreDelegate {
@Override
public void notify(IntentEvent event) {
processStoreEvent(event);
eventDispatcher.post(event);
processStoreEvent(event);
}
}
......
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.ConnectPoint;
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.IntentExtensionService;
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 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
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();
}
......