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; ...@@ -19,11 +19,16 @@ import java.util.Collections;
19 import java.util.List; 19 import java.util.List;
20 20
21 import com.google.common.base.MoreObjects; 21 import com.google.common.base.MoreObjects;
22 +import com.google.common.base.Predicate;
23 +import com.google.common.collect.Iterables;
22 import org.onlab.onos.core.ApplicationId; 24 import org.onlab.onos.core.ApplicationId;
25 +import org.onlab.onos.net.Link;
23 import org.onlab.onos.net.Path; 26 import org.onlab.onos.net.Path;
24 import org.onlab.onos.net.flow.TrafficSelector; 27 import org.onlab.onos.net.flow.TrafficSelector;
25 import org.onlab.onos.net.flow.TrafficTreatment; 28 import org.onlab.onos.net.flow.TrafficTreatment;
26 29
30 +import static com.google.common.base.Preconditions.checkArgument;
31 +
27 /** 32 /**
28 * Abstraction of explicitly path specified connectivity intent. 33 * Abstraction of explicitly path specified connectivity intent.
29 */ 34 */
...@@ -61,6 +66,7 @@ public class PathIntent extends ConnectivityIntent { ...@@ -61,6 +66,7 @@ public class PathIntent extends ConnectivityIntent {
61 TrafficTreatment treatment, Path path, List<Constraint> constraints) { 66 TrafficTreatment treatment, Path path, List<Constraint> constraints) {
62 super(id(PathIntent.class, selector, treatment, path, constraints), appId, 67 super(id(PathIntent.class, selector, treatment, path, constraints), appId,
63 resources(path.links()), selector, treatment, constraints); 68 resources(path.links()), selector, treatment, constraints);
69 + PathIntent.validate(path.links());
64 this.path = path; 70 this.path = path;
65 } 71 }
66 72
...@@ -72,6 +78,32 @@ public class PathIntent extends ConnectivityIntent { ...@@ -72,6 +78,32 @@ public class PathIntent extends ConnectivityIntent {
72 this.path = null; 78 this.path = null;
73 } 79 }
74 80
81 + // NOTE: This methods takes linear time with the number of links.
82 + /**
83 + * Validates that source element ID and destination element ID of a link are
84 + * different for the specified all links and that destination element ID of a link and source
85 + * element ID of the next adjacent source element ID are same for the specified all links.
86 + *
87 + * @param links
88 + */
89 + public static void validate(List<Link> links) {
90 + checkArgument(Iterables.all(links, new Predicate<Link>() {
91 + @Override
92 + public boolean apply(Link link) {
93 + return !link.src().elementId().equals(link.dst().elementId());
94 + }
95 + }), "element of src and dst in a link must be different: {}", links);
96 +
97 + boolean adjacentSame = true;
98 + for (int i = 0; i < links.size() - 1; i++) {
99 + if (!links.get(i).dst().elementId().equals(links.get(i + 1).src().elementId())) {
100 + adjacentSame = false;
101 + break;
102 + }
103 + }
104 + checkArgument(adjacentSame, "adjacent links must share the same element: {}", links);
105 + }
106 +
75 /** 107 /**
76 * Returns the links which the traffic goes along. 108 * Returns the links which the traffic goes along.
77 * 109 *
......
...@@ -16,10 +16,21 @@ ...@@ -16,10 +16,21 @@
16 package org.onlab.onos.net.intent; 16 package org.onlab.onos.net.intent;
17 17
18 import org.junit.Test; 18 import org.junit.Test;
19 +import org.onlab.onos.net.ConnectPoint;
20 +import org.onlab.onos.net.DefaultLink;
21 +import org.onlab.onos.net.DefaultPath;
22 +import org.onlab.onos.net.DeviceId;
19 import org.onlab.onos.net.NetTestTools; 23 import org.onlab.onos.net.NetTestTools;
20 import org.onlab.onos.net.Path; 24 import org.onlab.onos.net.Path;
25 +import org.onlab.onos.net.PortNumber;
26 +import org.onlab.onos.net.provider.ProviderId;
27 +
28 +import java.util.Arrays;
21 29
22 import static org.junit.Assert.assertEquals; 30 import static org.junit.Assert.assertEquals;
31 +import static org.onlab.onos.net.DeviceId.deviceId;
32 +import static org.onlab.onos.net.Link.Type.DIRECT;
33 +import static org.onlab.onos.net.PortNumber.portNumber;
23 34
24 public class PathIntentTest extends ConnectivityIntentTest { 35 public class PathIntentTest extends ConnectivityIntentTest {
25 // 111:11 --> 222:22 36 // 111:11 --> 222:22
...@@ -28,6 +39,21 @@ public class PathIntentTest extends ConnectivityIntentTest { ...@@ -28,6 +39,21 @@ public class PathIntentTest extends ConnectivityIntentTest {
28 // 111:11 --> 333:33 39 // 111:11 --> 333:33
29 private static final Path PATH2 = NetTestTools.createPath("222", "333"); 40 private static final Path PATH2 = NetTestTools.createPath("222", "333");
30 41
42 + private final ProviderId provider1 = new ProviderId("of", "1");
43 + private final DeviceId device1 = deviceId("1");
44 + private final DeviceId device2 = deviceId("2");
45 + private final PortNumber port1 = portNumber(1);
46 + private final PortNumber port2 = portNumber(2);
47 + private final PortNumber port3 = portNumber(3);
48 + private final PortNumber port4 = portNumber(4);
49 + private final ConnectPoint cp1 = new ConnectPoint(device1, port1);
50 + private final ConnectPoint cp2 = new ConnectPoint(device1, port2);
51 + private final ConnectPoint cp3 = new ConnectPoint(device2, port3);
52 + private final ConnectPoint cp4 = new ConnectPoint(device2, port4);
53 + private final DefaultLink link1 = new DefaultLink(provider1, cp1, cp2, DIRECT);
54 + private final DefaultLink link2 = new DefaultLink(provider1, cp1, cp2, DIRECT);
55 + private final double cost = 1;
56 +
31 @Test 57 @Test
32 public void basics() { 58 public void basics() {
33 PathIntent intent = createOne(); 59 PathIntent intent = createOne();
...@@ -46,4 +72,23 @@ public class PathIntentTest extends ConnectivityIntentTest { ...@@ -46,4 +72,23 @@ public class PathIntentTest extends ConnectivityIntentTest {
46 protected PathIntent createAnother() { 72 protected PathIntent createAnother() {
47 return new PathIntent(APPID, MATCH, NOP, PATH2); 73 return new PathIntent(APPID, MATCH, NOP, PATH2);
48 } 74 }
75 +
76 + /**
77 + * Tests the constructor raises IllegalArgumentException when the same device is specified in
78 + * source and destination of a link.
79 + */
80 + @Test(expected = IllegalArgumentException.class)
81 + public void testRaiseExceptionWhenSameDevices() {
82 + new PathIntent(APPID, MATCH, NOP, new DefaultPath(provider1, Arrays.asList(link1), cost));
83 + }
84 +
85 + /**
86 + * Tests the constructor raises IllegalArgumentException when the different elements are specified
87 + * in source element of the first link and destination element of the second link.
88 + */
89 + @Test(expected = IllegalArgumentException.class)
90 + public void testRaiseExceptionWhenDifferentDevice() {
91 + new PathIntent(APPID, MATCH, NOP, new DefaultPath(provider1, Arrays.asList(link1, link2), cost));
92 + }
93 +
49 } 94 }
......
...@@ -19,8 +19,6 @@ import org.apache.felix.scr.annotations.Activate; ...@@ -19,8 +19,6 @@ import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 19 import org.apache.felix.scr.annotations.Component;
20 import org.apache.felix.scr.annotations.Deactivate; 20 import org.apache.felix.scr.annotations.Deactivate;
21 import org.onlab.onos.net.ConnectPoint; 21 import org.onlab.onos.net.ConnectPoint;
22 -import org.onlab.onos.net.DefaultEdgeLink;
23 -import org.onlab.onos.net.DefaultLink;
24 import org.onlab.onos.net.DefaultPath; 22 import org.onlab.onos.net.DefaultPath;
25 import org.onlab.onos.net.Link; 23 import org.onlab.onos.net.Link;
26 import org.onlab.onos.net.Path; 24 import org.onlab.onos.net.Path;
...@@ -35,7 +33,7 @@ import java.util.List; ...@@ -35,7 +33,7 @@ import java.util.List;
35 import java.util.Set; 33 import java.util.Set;
36 34
37 import static java.util.Arrays.asList; 35 import static java.util.Arrays.asList;
38 -import static org.onlab.onos.net.Link.Type.DIRECT; 36 +import static org.onlab.onos.net.DefaultEdgeLink.createEdgeLink;
39 37
40 /** 38 /**
41 * An intent compiler for {@link org.onlab.onos.net.intent.PointToPointIntent}. 39 * An intent compiler for {@link org.onlab.onos.net.intent.PointToPointIntent}.
...@@ -47,6 +45,8 @@ public class PointToPointIntentCompiler ...@@ -47,6 +45,8 @@ public class PointToPointIntentCompiler
47 // TODO: use off-the-shell core provider ID 45 // TODO: use off-the-shell core provider ID
48 private static final ProviderId PID = 46 private static final ProviderId PID =
49 new ProviderId("core", "org.onlab.onos.core", true); 47 new ProviderId("core", "org.onlab.onos.core", true);
48 + // TODO: consider whether the default cost is appropriate or not
49 + public static final int DEFAULT_COST = 1;
50 50
51 @Activate 51 @Activate
52 public void activate() { 52 public void activate() {
...@@ -66,17 +66,17 @@ public class PointToPointIntentCompiler ...@@ -66,17 +66,17 @@ public class PointToPointIntentCompiler
66 ConnectPoint egressPoint = intent.egressPoint(); 66 ConnectPoint egressPoint = intent.egressPoint();
67 67
68 if (ingressPoint.deviceId().equals(egressPoint.deviceId())) { 68 if (ingressPoint.deviceId().equals(egressPoint.deviceId())) {
69 - List<Link> links = asList(new DefaultLink(PID, ingressPoint, egressPoint, DIRECT)); 69 + List<Link> links = asList(createEdgeLink(ingressPoint, true), createEdgeLink(egressPoint, false));
70 - return asList(createPathIntent(new DefaultPath(PID, links, 1), intent)); 70 + return asList(createPathIntent(new DefaultPath(PID, links, DEFAULT_COST), intent));
71 } 71 }
72 72
73 List<Link> links = new ArrayList<>(); 73 List<Link> links = new ArrayList<>();
74 Path path = getPath(intent, ingressPoint.deviceId(), 74 Path path = getPath(intent, ingressPoint.deviceId(),
75 egressPoint.deviceId()); 75 egressPoint.deviceId());
76 76
77 - links.add(DefaultEdgeLink.createEdgeLink(ingressPoint, true)); 77 + links.add(createEdgeLink(ingressPoint, true));
78 links.addAll(path.links()); 78 links.addAll(path.links());
79 - links.add(DefaultEdgeLink.createEdgeLink(egressPoint, false)); 79 + links.add(createEdgeLink(egressPoint, false));
80 80
81 return asList(createPathIntent(new DefaultPath(PID, links, path.cost(), 81 return asList(createPathIntent(new DefaultPath(PID, links, path.cost(),
82 path.annotations()), intent)); 82 path.annotations()), intent));
......
...@@ -36,6 +36,7 @@ import static org.hamcrest.CoreMatchers.notNullValue; ...@@ -36,6 +36,7 @@ import static org.hamcrest.CoreMatchers.notNullValue;
36 import static org.hamcrest.MatcherAssert.assertThat; 36 import static org.hamcrest.MatcherAssert.assertThat;
37 import static org.hamcrest.Matchers.hasSize; 37 import static org.hamcrest.Matchers.hasSize;
38 import static org.hamcrest.Matchers.is; 38 import static org.hamcrest.Matchers.is;
39 +import static org.onlab.onos.net.DefaultEdgeLink.createEdgeLink;
39 import static org.onlab.onos.net.DeviceId.deviceId; 40 import static org.onlab.onos.net.DeviceId.deviceId;
40 import static org.onlab.onos.net.NetTestTools.APP_ID; 41 import static org.onlab.onos.net.NetTestTools.APP_ID;
41 import static org.onlab.onos.net.NetTestTools.connectPoint; 42 import static org.onlab.onos.net.NetTestTools.connectPoint;
...@@ -163,9 +164,10 @@ public class TestPointToPointIntentCompiler { ...@@ -163,9 +164,10 @@ public class TestPointToPointIntentCompiler {
163 assertThat(compiled.get(0), is(instanceOf(PathIntent.class))); 164 assertThat(compiled.get(0), is(instanceOf(PathIntent.class)));
164 Path path = ((PathIntent) compiled.get(0)).path(); 165 Path path = ((PathIntent) compiled.get(0)).path();
165 166
166 - assertThat(path.links(), hasSize(1)); 167 + assertThat(path.links(), hasSize(2));
167 - Link link = path.links().get(0); 168 + Link firstLink = path.links().get(0);
168 - assertThat(link.src(), is(src)); 169 + assertThat(firstLink, is(createEdgeLink(src, true)));
169 - assertThat(link.dst(), is(dst)); 170 + Link secondLink = path.links().get(1);
171 + assertThat(secondLink, is(createEdgeLink(dst, false)));
170 } 172 }
171 } 173 }
......