Sho SHIMIZU
Committed by Gerrit Code Review

Fix ONOS-151 to support installation of PointToPointIntent

- Now support installation of PointToPointIntent that specifies the same
  switches as source element ID and destination element ID

Change-Id: If206f3fde77ca198fe1df078e7292a05e5bd7424
......@@ -19,11 +19,16 @@ import java.util.Collections;
import java.util.List;
import com.google.common.base.MoreObjects;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.onlab.onos.core.ApplicationId;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.Path;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import static com.google.common.base.Preconditions.checkArgument;
/**
* Abstraction of explicitly path specified connectivity intent.
*/
......@@ -61,6 +66,7 @@ public class PathIntent extends ConnectivityIntent {
TrafficTreatment treatment, Path path, List<Constraint> constraints) {
super(id(PathIntent.class, selector, treatment, path, constraints), appId,
resources(path.links()), selector, treatment, constraints);
PathIntent.validate(path.links());
this.path = path;
}
......@@ -72,6 +78,32 @@ public class PathIntent extends ConnectivityIntent {
this.path = null;
}
// NOTE: This methods takes linear time with the number of links.
/**
* Validates that source element ID and destination element ID of a link are
* different for the specified all links and that destination element ID of a link and source
* element ID of the next adjacent source element ID are same for the specified all links.
*
* @param links
*/
public static void validate(List<Link> links) {
checkArgument(Iterables.all(links, new Predicate<Link>() {
@Override
public boolean apply(Link link) {
return !link.src().elementId().equals(link.dst().elementId());
}
}), "element of src and dst in a link must be different: {}", links);
boolean adjacentSame = true;
for (int i = 0; i < links.size() - 1; i++) {
if (!links.get(i).dst().elementId().equals(links.get(i + 1).src().elementId())) {
adjacentSame = false;
break;
}
}
checkArgument(adjacentSame, "adjacent links must share the same element: {}", links);
}
/**
* Returns the links which the traffic goes along.
*
......
......@@ -16,10 +16,21 @@
package org.onlab.onos.net.intent;
import org.junit.Test;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultLink;
import org.onlab.onos.net.DefaultPath;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.NetTestTools;
import org.onlab.onos.net.Path;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.provider.ProviderId;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.Link.Type.DIRECT;
import static org.onlab.onos.net.PortNumber.portNumber;
public class PathIntentTest extends ConnectivityIntentTest {
// 111:11 --> 222:22
......@@ -28,6 +39,21 @@ public class PathIntentTest extends ConnectivityIntentTest {
// 111:11 --> 333:33
private static final Path PATH2 = NetTestTools.createPath("222", "333");
private final ProviderId provider1 = new ProviderId("of", "1");
private final DeviceId device1 = deviceId("1");
private final DeviceId device2 = deviceId("2");
private final PortNumber port1 = portNumber(1);
private final PortNumber port2 = portNumber(2);
private final PortNumber port3 = portNumber(3);
private final PortNumber port4 = portNumber(4);
private final ConnectPoint cp1 = new ConnectPoint(device1, port1);
private final ConnectPoint cp2 = new ConnectPoint(device1, port2);
private final ConnectPoint cp3 = new ConnectPoint(device2, port3);
private final ConnectPoint cp4 = new ConnectPoint(device2, port4);
private final DefaultLink link1 = new DefaultLink(provider1, cp1, cp2, DIRECT);
private final DefaultLink link2 = new DefaultLink(provider1, cp1, cp2, DIRECT);
private final double cost = 1;
@Test
public void basics() {
PathIntent intent = createOne();
......@@ -46,4 +72,23 @@ public class PathIntentTest extends ConnectivityIntentTest {
protected PathIntent createAnother() {
return new PathIntent(APPID, MATCH, NOP, PATH2);
}
/**
* Tests the constructor raises IllegalArgumentException when the same device is specified in
* source and destination of a link.
*/
@Test(expected = IllegalArgumentException.class)
public void testRaiseExceptionWhenSameDevices() {
new PathIntent(APPID, MATCH, NOP, new DefaultPath(provider1, Arrays.asList(link1), cost));
}
/**
* Tests the constructor raises IllegalArgumentException when the different elements are specified
* in source element of the first link and destination element of the second link.
*/
@Test(expected = IllegalArgumentException.class)
public void testRaiseExceptionWhenDifferentDevice() {
new PathIntent(APPID, MATCH, NOP, new DefaultPath(provider1, Arrays.asList(link1, link2), cost));
}
}
......
......@@ -19,8 +19,6 @@ import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultEdgeLink;
import org.onlab.onos.net.DefaultLink;
import org.onlab.onos.net.DefaultPath;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.Path;
......@@ -35,7 +33,7 @@ import java.util.List;
import java.util.Set;
import static java.util.Arrays.asList;
import static org.onlab.onos.net.Link.Type.DIRECT;
import static org.onlab.onos.net.DefaultEdgeLink.createEdgeLink;
/**
* An intent compiler for {@link org.onlab.onos.net.intent.PointToPointIntent}.
......@@ -47,6 +45,8 @@ public class PointToPointIntentCompiler
// TODO: use off-the-shell core provider ID
private static final ProviderId PID =
new ProviderId("core", "org.onlab.onos.core", true);
// TODO: consider whether the default cost is appropriate or not
public static final int DEFAULT_COST = 1;
@Activate
public void activate() {
......@@ -66,17 +66,17 @@ public class PointToPointIntentCompiler
ConnectPoint egressPoint = intent.egressPoint();
if (ingressPoint.deviceId().equals(egressPoint.deviceId())) {
List<Link> links = asList(new DefaultLink(PID, ingressPoint, egressPoint, DIRECT));
return asList(createPathIntent(new DefaultPath(PID, links, 1), intent));
List<Link> links = asList(createEdgeLink(ingressPoint, true), createEdgeLink(egressPoint, false));
return asList(createPathIntent(new DefaultPath(PID, links, DEFAULT_COST), intent));
}
List<Link> links = new ArrayList<>();
Path path = getPath(intent, ingressPoint.deviceId(),
egressPoint.deviceId());
links.add(DefaultEdgeLink.createEdgeLink(ingressPoint, true));
links.add(createEdgeLink(ingressPoint, true));
links.addAll(path.links());
links.add(DefaultEdgeLink.createEdgeLink(egressPoint, false));
links.add(createEdgeLink(egressPoint, false));
return asList(createPathIntent(new DefaultPath(PID, links, path.cost(),
path.annotations()), intent));
......
......@@ -36,6 +36,7 @@ import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.onlab.onos.net.DefaultEdgeLink.createEdgeLink;
import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.NetTestTools.APP_ID;
import static org.onlab.onos.net.NetTestTools.connectPoint;
......@@ -163,9 +164,10 @@ public class TestPointToPointIntentCompiler {
assertThat(compiled.get(0), is(instanceOf(PathIntent.class)));
Path path = ((PathIntent) compiled.get(0)).path();
assertThat(path.links(), hasSize(1));
Link link = path.links().get(0);
assertThat(link.src(), is(src));
assertThat(link.dst(), is(dst));
assertThat(path.links(), hasSize(2));
Link firstLink = path.links().get(0);
assertThat(firstLink, is(createEdgeLink(src, true)));
Link secondLink = path.links().get(1);
assertThat(secondLink, is(createEdgeLink(dst, false)));
}
}
......