Sho SHIMIZU

Add constraint for waypoints

Change-Id: I8156920d4d3d85aee060b9d0fe925f43f9b15ff1
...@@ -40,6 +40,10 @@ ...@@ -40,6 +40,10 @@
40 <groupId>joda-time</groupId> 40 <groupId>joda-time</groupId>
41 <artifactId>joda-time</artifactId> 41 <artifactId>joda-time</artifactId>
42 </dependency> 42 </dependency>
43 + <dependency>
44 + <groupId>org.easymock</groupId>
45 + <artifactId>easymock</artifactId>
46 + </dependency>
43 </dependencies> 47 </dependencies>
44 48
45 </project> 49 </project>
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.net.intent.constraint;
17 +
18 +import com.google.common.base.MoreObjects;
19 +import com.google.common.collect.ImmutableList;
20 +import org.onlab.onos.net.ElementId;
21 +import org.onlab.onos.net.Link;
22 +import org.onlab.onos.net.Path;
23 +import org.onlab.onos.net.intent.Constraint;
24 +import org.onlab.onos.net.resource.LinkResourceService;
25 +
26 +import java.util.LinkedList;
27 +import java.util.List;
28 +import java.util.Objects;
29 +
30 +import static com.google.common.base.Preconditions.checkArgument;
31 +import static com.google.common.base.Preconditions.checkNotNull;
32 +
33 +/**
34 + * Constraint that evaluates elements passed through in order.
35 + */
36 +public class WaypointConstraint implements Constraint {
37 +
38 + private final List<ElementId> waypoints;
39 +
40 + /**
41 + * Creates a new waypoint constraint.
42 + *
43 + * @param waypoints waypoints
44 + */
45 + public WaypointConstraint(ElementId... waypoints) {
46 + checkNotNull(waypoints, "waypoints cannot be null");
47 + checkArgument(waypoints.length > 0, "length of waypoints should be more than 0");
48 + this.waypoints = ImmutableList.copyOf(waypoints);
49 + }
50 +
51 + @Override
52 + public double cost(Link link, LinkResourceService resourceService) {
53 + // Always consider the number of hops
54 + return 1;
55 + }
56 +
57 + @Override
58 + public boolean validate(Path path, LinkResourceService resourceService) {
59 + LinkedList<ElementId> waypoints = new LinkedList<>(this.waypoints);
60 + ElementId current = waypoints.poll();
61 + // This is safe because Path class ensures the number of links are more than 0
62 + Link firstLink = path.links().get(0);
63 + if (firstLink.src().elementId().equals(current)) {
64 + current = waypoints.poll();
65 + }
66 +
67 + for (Link link : path.links()) {
68 + if (link.dst().elementId().equals(current)) {
69 + current = waypoints.poll();
70 + // Empty waypoints means passing through all waypoints in the specified order
71 + if (current == null) {
72 + return true;
73 + }
74 + }
75 + }
76 +
77 + return false;
78 + }
79 +
80 + @Override
81 + public int hashCode() {
82 + return Objects.hash(waypoints);
83 + }
84 +
85 + @Override
86 + public boolean equals(Object obj) {
87 + if (this == obj) {
88 + return true;
89 + }
90 +
91 + if (!(obj instanceof WaypointConstraint)) {
92 + return false;
93 + }
94 +
95 + final WaypointConstraint that = (WaypointConstraint) obj;
96 + return Objects.equals(this.waypoints, that.waypoints);
97 + }
98 +
99 + @Override
100 + public String toString() {
101 + return MoreObjects.toStringHelper(this)
102 + .add("waypoints", waypoints)
103 + .toString();
104 + }
105 +}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.net.intent.constraint;
17 +
18 +import org.junit.Before;
19 +import org.junit.Test;
20 +import org.onlab.onos.net.DefaultLink;
21 +import org.onlab.onos.net.DefaultPath;
22 +import org.onlab.onos.net.DeviceId;
23 +import org.onlab.onos.net.Path;
24 +import org.onlab.onos.net.PortNumber;
25 +import org.onlab.onos.net.provider.ProviderId;
26 +import org.onlab.onos.net.resource.LinkResourceService;
27 +
28 +import java.util.Arrays;
29 +
30 +import static org.easymock.EasyMock.createMock;
31 +import static org.hamcrest.Matchers.is;
32 +import static org.junit.Assert.assertThat;
33 +import static org.onlab.onos.net.DefaultLinkTest.cp;
34 +import static org.onlab.onos.net.DeviceId.deviceId;
35 +import static org.onlab.onos.net.Link.Type.DIRECT;
36 +
37 +/**
38 + * Test for constraint of intermediate elements.
39 + */
40 +public class WaypointConstraintTest {
41 +
42 + public static final DeviceId DID1 = deviceId("of:1");
43 + public static final DeviceId DID2 = deviceId("of:2");
44 + public static final DeviceId DID3 = deviceId("of:3");
45 + public static final DeviceId DID4 = deviceId("of:4");
46 + public static final PortNumber PN1 = PortNumber.portNumber(1);
47 + public static final PortNumber PN2 = PortNumber.portNumber(2);
48 + public static final PortNumber PN3 = PortNumber.portNumber(3);
49 + public static final PortNumber PN4 = PortNumber.portNumber(4);
50 + public static final ProviderId PROVIDER_ID = new ProviderId("of", "foo");
51 +
52 + private WaypointConstraint sut;
53 + private LinkResourceService linkResourceService;
54 +
55 + private Path path;
56 + private DefaultLink link2;
57 + private DefaultLink link1;
58 +
59 + @Before
60 + public void setUp() {
61 + linkResourceService = createMock(LinkResourceService.class);
62 +
63 + link1 = new DefaultLink(PROVIDER_ID, cp(DID1, PN1), cp(DID2, PN2), DIRECT);
64 + link2 = new DefaultLink(PROVIDER_ID, cp(DID2, PN3), cp(DID3, PN4), DIRECT);
65 + path = new DefaultPath(PROVIDER_ID, Arrays.asList(link1, link2), 10);
66 + }
67 +
68 + /**
69 + * Tests that all of the specified waypoints are included in the specified path in order.
70 + */
71 + @Test
72 + public void testSatisfyWaypoints() {
73 + sut = new WaypointConstraint(DID1, DID2, DID3);
74 +
75 + assertThat(sut.validate(path, linkResourceService), is(true));
76 + }
77 +
78 + /**
79 + * Tests that the specified path does not includes the specified waypoint.
80 + */
81 + @Test
82 + public void testNotSatisfyWaypoint() {
83 + sut = new WaypointConstraint(DID4);
84 +
85 + assertThat(sut.validate(path, linkResourceService), is(false));
86 + }
87 +}