Committed by
Gerrit Code Review
ONOS-2184 - initial impl. of virtual network path service; move path related me…
…thods from PathManager to AbstractPathService (since they are reused for VirtualNetworkPathService). Change-Id: Ib4211d69a15c23a50de420b771877bb659539c22
Showing
6 changed files
with
583 additions
and
215 deletions
1 | +/* | ||
2 | + * | ||
3 | + * * Copyright 2016-present Open Networking Laboratory | ||
4 | + * * | ||
5 | + * * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * * you may not use this file except in compliance with the License. | ||
7 | + * * You may obtain a copy of the License at | ||
8 | + * * | ||
9 | + * * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * * | ||
11 | + * * Unless required by applicable law or agreed to in writing, software | ||
12 | + * * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * * See the License for the specific language governing permissions and | ||
15 | + * * limitations under the License. | ||
16 | + * | ||
17 | + */ | ||
18 | + | ||
19 | +package org.onosproject.net.topology; | ||
20 | + | ||
21 | +import com.google.common.collect.ImmutableSet; | ||
22 | +import com.google.common.collect.Lists; | ||
23 | +import com.google.common.collect.Sets; | ||
24 | +import org.apache.felix.scr.annotations.Reference; | ||
25 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
26 | +import org.onosproject.net.ConnectPoint; | ||
27 | +import org.onosproject.net.DefaultDisjointPath; | ||
28 | +import org.onosproject.net.DefaultEdgeLink; | ||
29 | +import org.onosproject.net.DefaultPath; | ||
30 | +import org.onosproject.net.DeviceId; | ||
31 | +import org.onosproject.net.DisjointPath; | ||
32 | +import org.onosproject.net.EdgeLink; | ||
33 | +import org.onosproject.net.ElementId; | ||
34 | +import org.onosproject.net.Host; | ||
35 | +import org.onosproject.net.HostId; | ||
36 | +import org.onosproject.net.HostLocation; | ||
37 | +import org.onosproject.net.Link; | ||
38 | +import org.onosproject.net.Path; | ||
39 | +import org.onosproject.net.PortNumber; | ||
40 | +import org.onosproject.net.host.HostService; | ||
41 | +import org.onosproject.net.provider.ProviderId; | ||
42 | + | ||
43 | +import java.util.List; | ||
44 | +import java.util.Map; | ||
45 | +import java.util.Set; | ||
46 | + | ||
47 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
48 | + | ||
49 | +/** | ||
50 | + * Helper class for path service. | ||
51 | + */ | ||
52 | +public abstract class AbstractPathService { | ||
53 | + | ||
54 | + private static final String ELEMENT_ID_NULL = "Element ID cannot be null"; | ||
55 | + private static final EdgeLink NOT_HOST = new NotHost(); | ||
56 | + | ||
57 | + private static final ProviderId PID = new ProviderId("core", "org.onosproject.core"); | ||
58 | + private static final PortNumber P0 = PortNumber.portNumber(0); | ||
59 | + | ||
60 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
61 | + protected TopologyService topologyService; | ||
62 | + | ||
63 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
64 | + protected HostService hostService; | ||
65 | + | ||
66 | + public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) { | ||
67 | + checkNotNull(src, ELEMENT_ID_NULL); | ||
68 | + checkNotNull(dst, ELEMENT_ID_NULL); | ||
69 | + | ||
70 | + // Get the source and destination edge locations | ||
71 | + EdgeLink srcEdge = getEdgeLink(src, true); | ||
72 | + EdgeLink dstEdge = getEdgeLink(dst, false); | ||
73 | + | ||
74 | + // If either edge is null, bail with no paths. | ||
75 | + if (srcEdge == null || dstEdge == null) { | ||
76 | + return ImmutableSet.of(); | ||
77 | + } | ||
78 | + | ||
79 | + DeviceId srcDevice = srcEdge != NOT_HOST ? srcEdge.dst().deviceId() : (DeviceId) src; | ||
80 | + DeviceId dstDevice = dstEdge != NOT_HOST ? dstEdge.src().deviceId() : (DeviceId) dst; | ||
81 | + | ||
82 | + // If the source and destination are on the same edge device, there | ||
83 | + // is just one path, so build it and return it. | ||
84 | + if (srcDevice.equals(dstDevice)) { | ||
85 | + return edgeToEdgePaths(srcEdge, dstEdge); | ||
86 | + } | ||
87 | + | ||
88 | + // Otherwise get all paths between the source and destination edge | ||
89 | + // devices. | ||
90 | + Topology topology = topologyService.currentTopology(); | ||
91 | + Set<Path> paths = weight == null ? | ||
92 | + topologyService.getPaths(topology, srcDevice, dstDevice) : | ||
93 | + topologyService.getPaths(topology, srcDevice, dstDevice, weight); | ||
94 | + | ||
95 | + return edgeToEdgePaths(srcEdge, dstEdge, paths); | ||
96 | + } | ||
97 | + | ||
98 | + public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight) { | ||
99 | + checkNotNull(src, ELEMENT_ID_NULL); | ||
100 | + checkNotNull(dst, ELEMENT_ID_NULL); | ||
101 | + | ||
102 | + // Get the source and destination edge locations | ||
103 | + EdgeLink srcEdge = getEdgeLink(src, true); | ||
104 | + EdgeLink dstEdge = getEdgeLink(dst, false); | ||
105 | + | ||
106 | + // If either edge is null, bail with no paths. | ||
107 | + if (srcEdge == null || dstEdge == null) { | ||
108 | + return ImmutableSet.of(); | ||
109 | + } | ||
110 | + | ||
111 | + DeviceId srcDevice = srcEdge != NOT_HOST ? srcEdge.dst().deviceId() : (DeviceId) src; | ||
112 | + DeviceId dstDevice = dstEdge != NOT_HOST ? dstEdge.src().deviceId() : (DeviceId) dst; | ||
113 | + | ||
114 | + // If the source and destination are on the same edge device, there | ||
115 | + // is just one path, so build it and return it. | ||
116 | + if (srcDevice.equals(dstDevice)) { | ||
117 | + return edgeToEdgePathsDisjoint(srcEdge, dstEdge); | ||
118 | + } | ||
119 | + | ||
120 | + // Otherwise get all paths between the source and destination edge | ||
121 | + // devices. | ||
122 | + Topology topology = topologyService.currentTopology(); | ||
123 | + Set<DisjointPath> paths = weight == null ? | ||
124 | + topologyService.getDisjointPaths(topology, srcDevice, dstDevice) : | ||
125 | + topologyService.getDisjointPaths(topology, srcDevice, dstDevice, weight); | ||
126 | + | ||
127 | + return edgeToEdgePathsDisjoint(srcEdge, dstEdge, paths); | ||
128 | + } | ||
129 | + | ||
130 | + public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight, | ||
131 | + Map<Link, Object> riskProfile) { | ||
132 | + checkNotNull(src, ELEMENT_ID_NULL); | ||
133 | + checkNotNull(dst, ELEMENT_ID_NULL); | ||
134 | + | ||
135 | + // Get the source and destination edge locations | ||
136 | + EdgeLink srcEdge = getEdgeLink(src, true); | ||
137 | + EdgeLink dstEdge = getEdgeLink(dst, false); | ||
138 | + | ||
139 | + // If either edge is null, bail with no paths. | ||
140 | + if (srcEdge == null || dstEdge == null) { | ||
141 | + return ImmutableSet.of(); | ||
142 | + } | ||
143 | + | ||
144 | + DeviceId srcDevice = srcEdge != NOT_HOST ? srcEdge.dst().deviceId() : (DeviceId) src; | ||
145 | + DeviceId dstDevice = dstEdge != NOT_HOST ? dstEdge.src().deviceId() : (DeviceId) dst; | ||
146 | + | ||
147 | + // If the source and destination are on the same edge device, there | ||
148 | + // is just one path, so build it and return it. | ||
149 | + if (srcDevice.equals(dstDevice)) { | ||
150 | + return edgeToEdgePathsDisjoint(srcEdge, dstEdge); | ||
151 | + } | ||
152 | + | ||
153 | + // Otherwise get all paths between the source and destination edge | ||
154 | + // devices. | ||
155 | + Topology topology = topologyService.currentTopology(); | ||
156 | + Set<DisjointPath> paths = weight == null ? | ||
157 | + topologyService.getDisjointPaths(topology, srcDevice, dstDevice, riskProfile) : | ||
158 | + topologyService.getDisjointPaths(topology, srcDevice, dstDevice, weight, riskProfile); | ||
159 | + | ||
160 | + return edgeToEdgePathsDisjoint(srcEdge, dstEdge, paths); | ||
161 | + } | ||
162 | + | ||
163 | + // Finds the host edge link if the element ID is a host id of an existing | ||
164 | + // host. Otherwise, if the host does not exist, it returns null and if | ||
165 | + // the element ID is not a host ID, returns NOT_HOST edge link. | ||
166 | + private EdgeLink getEdgeLink(ElementId elementId, boolean isIngress) { | ||
167 | + if (elementId instanceof HostId) { | ||
168 | + // Resolve the host, return null. | ||
169 | + Host host = hostService.getHost((HostId) elementId); | ||
170 | + if (host == null) { | ||
171 | + return null; | ||
172 | + } | ||
173 | + return new DefaultEdgeLink(PID, new ConnectPoint(elementId, P0), | ||
174 | + host.location(), isIngress); | ||
175 | + } | ||
176 | + return NOT_HOST; | ||
177 | + } | ||
178 | + | ||
179 | + // Produces a set of edge-to-edge paths using the set of infrastructure | ||
180 | + // paths and the given edge links. | ||
181 | + private Set<Path> edgeToEdgePaths(EdgeLink srcLink, EdgeLink dstLink) { | ||
182 | + Set<Path> endToEndPaths = Sets.newHashSetWithExpectedSize(1); | ||
183 | + endToEndPaths.add(edgeToEdgePath(srcLink, dstLink, null)); | ||
184 | + return endToEndPaths; | ||
185 | + } | ||
186 | + | ||
187 | + // Produces a set of edge-to-edge paths using the set of infrastructure | ||
188 | + // paths and the given edge links. | ||
189 | + private Set<Path> edgeToEdgePaths(EdgeLink srcLink, EdgeLink dstLink, Set<Path> paths) { | ||
190 | + Set<Path> endToEndPaths = Sets.newHashSetWithExpectedSize(paths.size()); | ||
191 | + for (Path path : paths) { | ||
192 | + endToEndPaths.add(edgeToEdgePath(srcLink, dstLink, path)); | ||
193 | + } | ||
194 | + return endToEndPaths; | ||
195 | + } | ||
196 | + | ||
197 | + private Set<DisjointPath> edgeToEdgePathsDisjoint(EdgeLink srcLink, EdgeLink dstLink) { | ||
198 | + Set<DisjointPath> endToEndPaths = Sets.newHashSetWithExpectedSize(1); | ||
199 | + endToEndPaths.add(edgeToEdgePathD(srcLink, dstLink, null)); | ||
200 | + return endToEndPaths; | ||
201 | + } | ||
202 | + | ||
203 | + private Set<DisjointPath> edgeToEdgePathsDisjoint(EdgeLink srcLink, EdgeLink dstLink, | ||
204 | + Set<DisjointPath> paths) { | ||
205 | + Set<DisjointPath> endToEndPaths = Sets.newHashSetWithExpectedSize(paths.size()); | ||
206 | + for (DisjointPath path : paths) { | ||
207 | + endToEndPaths.add(edgeToEdgePathD(srcLink, dstLink, path)); | ||
208 | + } | ||
209 | + return endToEndPaths; | ||
210 | + } | ||
211 | + | ||
212 | + // Produces a direct edge-to-edge path. | ||
213 | + private Path edgeToEdgePath(EdgeLink srcLink, EdgeLink dstLink, Path path) { | ||
214 | + List<Link> links = Lists.newArrayListWithCapacity(2); | ||
215 | + double cost = 0; | ||
216 | + | ||
217 | + // Add source and destination edge links only if they are real and | ||
218 | + // add the infrastructure path only if it is not null. | ||
219 | + if (srcLink != NOT_HOST) { | ||
220 | + links.add(srcLink); | ||
221 | + cost++; | ||
222 | + } | ||
223 | + if (path != null) { | ||
224 | + links.addAll(path.links()); | ||
225 | + cost += path.cost(); | ||
226 | + } | ||
227 | + if (dstLink != NOT_HOST) { | ||
228 | + links.add(dstLink); | ||
229 | + cost++; | ||
230 | + } | ||
231 | + return new DefaultPath(PID, links, cost); | ||
232 | + } | ||
233 | + | ||
234 | + // Produces a direct edge-to-edge path. | ||
235 | + private DisjointPath edgeToEdgePathD(EdgeLink srcLink, EdgeLink dstLink, DisjointPath path) { | ||
236 | + Path primary = null; | ||
237 | + Path backup = null; | ||
238 | + if (path != null) { | ||
239 | + primary = path.primary(); | ||
240 | + backup = path.backup(); | ||
241 | + } | ||
242 | + return new DefaultDisjointPath(PID, (DefaultPath) edgeToEdgePath(srcLink, dstLink, primary), | ||
243 | + (DefaultPath) edgeToEdgePath(srcLink, dstLink, backup)); | ||
244 | + } | ||
245 | + | ||
246 | + | ||
247 | + // Special value for edge link to represent that this is really not an | ||
248 | + // edge link since the src or dst are really an infrastructure device. | ||
249 | + private static class NotHost extends DefaultEdgeLink implements EdgeLink { | ||
250 | + NotHost() { | ||
251 | + super(PID, new ConnectPoint(HostId.NONE, P0), | ||
252 | + new HostLocation(DeviceId.NONE, P0, 0L), false); | ||
253 | + } | ||
254 | + } | ||
255 | +} |
... | @@ -15,43 +15,23 @@ | ... | @@ -15,43 +15,23 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.topology.impl; | 16 | package org.onosproject.net.topology.impl; |
17 | 17 | ||
18 | -import com.google.common.collect.ImmutableSet; | ||
19 | -import com.google.common.collect.Lists; | ||
20 | -import com.google.common.collect.Sets; | ||
21 | import org.apache.felix.scr.annotations.Activate; | 18 | import org.apache.felix.scr.annotations.Activate; |
22 | import org.apache.felix.scr.annotations.Component; | 19 | import org.apache.felix.scr.annotations.Component; |
23 | import org.apache.felix.scr.annotations.Deactivate; | 20 | import org.apache.felix.scr.annotations.Deactivate; |
24 | -import org.apache.felix.scr.annotations.Reference; | ||
25 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
26 | import org.apache.felix.scr.annotations.Service; | 21 | import org.apache.felix.scr.annotations.Service; |
27 | -import org.onosproject.net.ConnectPoint; | ||
28 | -import org.onosproject.net.DefaultEdgeLink; | ||
29 | -import org.onosproject.net.DefaultPath; | ||
30 | import org.onosproject.net.DisjointPath; | 22 | import org.onosproject.net.DisjointPath; |
31 | -import org.onosproject.net.DefaultDisjointPath; | ||
32 | -import org.onosproject.net.DeviceId; | ||
33 | -import org.onosproject.net.EdgeLink; | ||
34 | import org.onosproject.net.ElementId; | 23 | import org.onosproject.net.ElementId; |
35 | -import org.onosproject.net.Host; | ||
36 | -import org.onosproject.net.HostId; | ||
37 | -import org.onosproject.net.HostLocation; | ||
38 | import org.onosproject.net.Link; | 24 | import org.onosproject.net.Link; |
39 | import org.onosproject.net.Path; | 25 | import org.onosproject.net.Path; |
40 | -import org.onosproject.net.PortNumber; | ||
41 | -import org.onosproject.net.host.HostService; | ||
42 | -import org.onosproject.net.provider.ProviderId; | ||
43 | import org.onosproject.net.topology.LinkWeight; | 26 | import org.onosproject.net.topology.LinkWeight; |
44 | import org.onosproject.net.topology.PathService; | 27 | import org.onosproject.net.topology.PathService; |
45 | -import org.onosproject.net.topology.Topology; | 28 | +import org.onosproject.net.topology.AbstractPathService; |
46 | -import org.onosproject.net.topology.TopologyService; | ||
47 | import org.slf4j.Logger; | 29 | import org.slf4j.Logger; |
48 | 30 | ||
49 | -import java.util.List; | ||
50 | import java.util.Set; | 31 | import java.util.Set; |
51 | import java.util.Map; | 32 | import java.util.Map; |
52 | 33 | ||
53 | 34 | ||
54 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
55 | import static org.slf4j.LoggerFactory.getLogger; | 35 | import static org.slf4j.LoggerFactory.getLogger; |
56 | import static org.onosproject.security.AppGuard.checkPermission; | 36 | import static org.onosproject.security.AppGuard.checkPermission; |
57 | import static org.onosproject.security.AppPermission.Type.*; | 37 | import static org.onosproject.security.AppPermission.Type.*; |
... | @@ -63,23 +43,11 @@ import static org.onosproject.security.AppPermission.Type.*; | ... | @@ -63,23 +43,11 @@ import static org.onosproject.security.AppPermission.Type.*; |
63 | */ | 43 | */ |
64 | @Component(immediate = true) | 44 | @Component(immediate = true) |
65 | @Service | 45 | @Service |
66 | -public class PathManager implements PathService { | 46 | +public class PathManager extends AbstractPathService implements PathService { |
67 | 47 | ||
68 | - private static final String ELEMENT_ID_NULL = "Element ID cannot be null"; | ||
69 | - | ||
70 | - private static final ProviderId PID = new ProviderId("core", "org.onosproject.core"); | ||
71 | - private static final PortNumber P0 = PortNumber.portNumber(0); | ||
72 | - | ||
73 | - private static final EdgeLink NOT_HOST = new NotHost(); | ||
74 | 48 | ||
75 | private final Logger log = getLogger(getClass()); | 49 | private final Logger log = getLogger(getClass()); |
76 | 50 | ||
77 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
78 | - protected TopologyService topologyService; | ||
79 | - | ||
80 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
81 | - protected HostService hostService; | ||
82 | - | ||
83 | @Activate | 51 | @Activate |
84 | public void activate() { | 52 | public void activate() { |
85 | log.info("Started"); | 53 | log.info("Started"); |
... | @@ -100,37 +68,9 @@ public class PathManager implements PathService { | ... | @@ -100,37 +68,9 @@ public class PathManager implements PathService { |
100 | @Override | 68 | @Override |
101 | public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) { | 69 | public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) { |
102 | checkPermission(TOPOLOGY_READ); | 70 | checkPermission(TOPOLOGY_READ); |
103 | - | 71 | + return super.getPaths(src, dst, weight); |
104 | - checkNotNull(src, ELEMENT_ID_NULL); | ||
105 | - checkNotNull(dst, ELEMENT_ID_NULL); | ||
106 | - | ||
107 | - // Get the source and destination edge locations | ||
108 | - EdgeLink srcEdge = getEdgeLink(src, true); | ||
109 | - EdgeLink dstEdge = getEdgeLink(dst, false); | ||
110 | - | ||
111 | - // If either edge is null, bail with no paths. | ||
112 | - if (srcEdge == null || dstEdge == null) { | ||
113 | - return ImmutableSet.of(); | ||
114 | } | 72 | } |
115 | 73 | ||
116 | - DeviceId srcDevice = srcEdge != NOT_HOST ? srcEdge.dst().deviceId() : (DeviceId) src; | ||
117 | - DeviceId dstDevice = dstEdge != NOT_HOST ? dstEdge.src().deviceId() : (DeviceId) dst; | ||
118 | - | ||
119 | - // If the source and destination are on the same edge device, there | ||
120 | - // is just one path, so build it and return it. | ||
121 | - if (srcDevice.equals(dstDevice)) { | ||
122 | - return edgeToEdgePaths(srcEdge, dstEdge); | ||
123 | - } | ||
124 | - | ||
125 | - // Otherwise get all paths between the source and destination edge | ||
126 | - // devices. | ||
127 | - Topology topology = topologyService.currentTopology(); | ||
128 | - Set<Path> paths = weight == null ? | ||
129 | - topologyService.getPaths(topology, srcDevice, dstDevice) : | ||
130 | - topologyService.getPaths(topology, srcDevice, dstDevice, weight); | ||
131 | - | ||
132 | - return edgeToEdgePaths(srcEdge, dstEdge, paths); | ||
133 | - } | ||
134 | 74 | ||
135 | @Override | 75 | @Override |
136 | public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst) { | 76 | public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst) { |
... | @@ -141,35 +81,7 @@ public class PathManager implements PathService { | ... | @@ -141,35 +81,7 @@ public class PathManager implements PathService { |
141 | @Override | 81 | @Override |
142 | public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight) { | 82 | public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight) { |
143 | checkPermission(TOPOLOGY_READ); | 83 | checkPermission(TOPOLOGY_READ); |
144 | - checkNotNull(src, ELEMENT_ID_NULL); | 84 | + return super.getDisjointPaths(src, dst, weight); |
145 | - checkNotNull(dst, ELEMENT_ID_NULL); | ||
146 | - | ||
147 | - // Get the source and destination edge locations | ||
148 | - EdgeLink srcEdge = getEdgeLink(src, true); | ||
149 | - EdgeLink dstEdge = getEdgeLink(dst, false); | ||
150 | - | ||
151 | - // If either edge is null, bail with no paths. | ||
152 | - if (srcEdge == null || dstEdge == null) { | ||
153 | - return ImmutableSet.of(); | ||
154 | - } | ||
155 | - | ||
156 | - DeviceId srcDevice = srcEdge != NOT_HOST ? srcEdge.dst().deviceId() : (DeviceId) src; | ||
157 | - DeviceId dstDevice = dstEdge != NOT_HOST ? dstEdge.src().deviceId() : (DeviceId) dst; | ||
158 | - | ||
159 | - // If the source and destination are on the same edge device, there | ||
160 | - // is just one path, so build it and return it. | ||
161 | - if (srcDevice.equals(dstDevice)) { | ||
162 | - return edgeToEdgePathsDisjoint(srcEdge, dstEdge); | ||
163 | - } | ||
164 | - | ||
165 | - // Otherwise get all paths between the source and destination edge | ||
166 | - // devices. | ||
167 | - Topology topology = topologyService.currentTopology(); | ||
168 | - Set<DisjointPath> paths = weight == null ? | ||
169 | - topologyService.getDisjointPaths(topology, srcDevice, dstDevice) : | ||
170 | - topologyService.getDisjointPaths(topology, srcDevice, dstDevice, weight); | ||
171 | - | ||
172 | - return edgeToEdgePathsDisjoint(srcEdge, dstEdge, paths); | ||
173 | } | 85 | } |
174 | 86 | ||
175 | @Override | 87 | @Override |
... | @@ -183,126 +95,7 @@ public class PathManager implements PathService { | ... | @@ -183,126 +95,7 @@ public class PathManager implements PathService { |
183 | public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight, | 95 | public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight, |
184 | Map<Link, Object> riskProfile) { | 96 | Map<Link, Object> riskProfile) { |
185 | checkPermission(TOPOLOGY_READ); | 97 | checkPermission(TOPOLOGY_READ); |
186 | - checkNotNull(src, ELEMENT_ID_NULL); | 98 | + return super.getDisjointPaths(src, dst, weight, riskProfile); |
187 | - checkNotNull(dst, ELEMENT_ID_NULL); | ||
188 | - | ||
189 | - // Get the source and destination edge locations | ||
190 | - EdgeLink srcEdge = getEdgeLink(src, true); | ||
191 | - EdgeLink dstEdge = getEdgeLink(dst, false); | ||
192 | - | ||
193 | - // If either edge is null, bail with no paths. | ||
194 | - if (srcEdge == null || dstEdge == null) { | ||
195 | - return ImmutableSet.of(); | ||
196 | - } | ||
197 | - | ||
198 | - DeviceId srcDevice = srcEdge != NOT_HOST ? srcEdge.dst().deviceId() : (DeviceId) src; | ||
199 | - DeviceId dstDevice = dstEdge != NOT_HOST ? dstEdge.src().deviceId() : (DeviceId) dst; | ||
200 | - | ||
201 | - // If the source and destination are on the same edge device, there | ||
202 | - // is just one path, so build it and return it. | ||
203 | - if (srcDevice.equals(dstDevice)) { | ||
204 | - return edgeToEdgePathsDisjoint(srcEdge, dstEdge); | ||
205 | - } | ||
206 | - | ||
207 | - // Otherwise get all paths between the source and destination edge | ||
208 | - // devices. | ||
209 | - Topology topology = topologyService.currentTopology(); | ||
210 | - Set<DisjointPath> paths = weight == null ? | ||
211 | - topologyService.getDisjointPaths(topology, srcDevice, dstDevice, riskProfile) : | ||
212 | - topologyService.getDisjointPaths(topology, srcDevice, dstDevice, weight, riskProfile); | ||
213 | - | ||
214 | - return edgeToEdgePathsDisjoint(srcEdge, dstEdge, paths); | ||
215 | - } | ||
216 | - | ||
217 | - // Finds the host edge link if the element ID is a host id of an existing | ||
218 | - // host. Otherwise, if the host does not exist, it returns null and if | ||
219 | - // the element ID is not a host ID, returns NOT_HOST edge link. | ||
220 | - private EdgeLink getEdgeLink(ElementId elementId, boolean isIngress) { | ||
221 | - if (elementId instanceof HostId) { | ||
222 | - // Resolve the host, return null. | ||
223 | - Host host = hostService.getHost((HostId) elementId); | ||
224 | - if (host == null) { | ||
225 | - return null; | ||
226 | - } | ||
227 | - return new DefaultEdgeLink(PID, new ConnectPoint(elementId, P0), | ||
228 | - host.location(), isIngress); | ||
229 | - } | ||
230 | - return NOT_HOST; | ||
231 | - } | ||
232 | - | ||
233 | - // Produces a set of edge-to-edge paths using the set of infrastructure | ||
234 | - // paths and the given edge links. | ||
235 | - private Set<Path> edgeToEdgePaths(EdgeLink srcLink, EdgeLink dstLink) { | ||
236 | - Set<Path> endToEndPaths = Sets.newHashSetWithExpectedSize(1); | ||
237 | - endToEndPaths.add(edgeToEdgePath(srcLink, dstLink, null)); | ||
238 | - return endToEndPaths; | ||
239 | } | 99 | } |
240 | 100 | ||
241 | - // Produces a set of edge-to-edge paths using the set of infrastructure | ||
242 | - // paths and the given edge links. | ||
243 | - private Set<Path> edgeToEdgePaths(EdgeLink srcLink, EdgeLink dstLink, Set<Path> paths) { | ||
244 | - Set<Path> endToEndPaths = Sets.newHashSetWithExpectedSize(paths.size()); | ||
245 | - for (Path path : paths) { | ||
246 | - endToEndPaths.add(edgeToEdgePath(srcLink, dstLink, path)); | ||
247 | - } | ||
248 | - return endToEndPaths; | ||
249 | - } | ||
250 | - | ||
251 | - private Set<DisjointPath> edgeToEdgePathsDisjoint(EdgeLink srcLink, EdgeLink dstLink) { | ||
252 | - Set<DisjointPath> endToEndPaths = Sets.newHashSetWithExpectedSize(1); | ||
253 | - endToEndPaths.add(edgeToEdgePathD(srcLink, dstLink, null)); | ||
254 | - return endToEndPaths; | ||
255 | - } | ||
256 | - | ||
257 | - private Set<DisjointPath> edgeToEdgePathsDisjoint(EdgeLink srcLink, EdgeLink dstLink, Set<DisjointPath> paths) { | ||
258 | - Set<DisjointPath> endToEndPaths = Sets.newHashSetWithExpectedSize(paths.size()); | ||
259 | - for (DisjointPath path : paths) { | ||
260 | - endToEndPaths.add(edgeToEdgePathD(srcLink, dstLink, path)); | ||
261 | - } | ||
262 | - return endToEndPaths; | ||
263 | - } | ||
264 | - | ||
265 | - // Produces a direct edge-to-edge path. | ||
266 | - private Path edgeToEdgePath(EdgeLink srcLink, EdgeLink dstLink, Path path) { | ||
267 | - List<Link> links = Lists.newArrayListWithCapacity(2); | ||
268 | - double cost = 0; | ||
269 | - | ||
270 | - // Add source and destination edge links only if they are real and | ||
271 | - // add the infrastructure path only if it is not null. | ||
272 | - if (srcLink != NOT_HOST) { | ||
273 | - links.add(srcLink); | ||
274 | - cost++; | ||
275 | - } | ||
276 | - if (path != null) { | ||
277 | - links.addAll(path.links()); | ||
278 | - cost += path.cost(); | ||
279 | - } | ||
280 | - if (dstLink != NOT_HOST) { | ||
281 | - links.add(dstLink); | ||
282 | - cost++; | ||
283 | - } | ||
284 | - return new DefaultPath(PID, links, cost); | ||
285 | - } | ||
286 | - | ||
287 | - // Produces a direct edge-to-edge path. | ||
288 | - private DisjointPath edgeToEdgePathD(EdgeLink srcLink, EdgeLink dstLink, DisjointPath path) { | ||
289 | - Path primary = null; | ||
290 | - Path backup = null; | ||
291 | - if (path != null) { | ||
292 | - primary = path.primary(); | ||
293 | - backup = path.backup(); | ||
294 | - } | ||
295 | - return new DefaultDisjointPath(PID, (DefaultPath) edgeToEdgePath(srcLink, dstLink, primary), | ||
296 | - (DefaultPath) edgeToEdgePath(srcLink, dstLink, backup)); | ||
297 | - } | ||
298 | - | ||
299 | - | ||
300 | - // Special value for edge link to represent that this is really not an | ||
301 | - // edge link since the src or dst are really an infrastructure device. | ||
302 | - private static class NotHost extends DefaultEdgeLink implements EdgeLink { | ||
303 | - NotHost() { | ||
304 | - super(PID, new ConnectPoint(HostId.NONE, P0), | ||
305 | - new HostLocation(DeviceId.NONE, P0, 0L), false); | ||
306 | - } | ||
307 | - } | ||
308 | } | 101 | } | ... | ... |
... | @@ -18,6 +18,7 @@ package org.onosproject.net.topology.impl; | ... | @@ -18,6 +18,7 @@ package org.onosproject.net.topology.impl; |
18 | import org.junit.After; | 18 | import org.junit.After; |
19 | import org.junit.Before; | 19 | import org.junit.Before; |
20 | import org.junit.Test; | 20 | import org.junit.Test; |
21 | +import org.onlab.junit.TestUtils; | ||
21 | import org.onosproject.net.DeviceId; | 22 | import org.onosproject.net.DeviceId; |
22 | import org.onosproject.net.ElementId; | 23 | import org.onosproject.net.ElementId; |
23 | import org.onosproject.net.Host; | 24 | import org.onosproject.net.Host; |
... | @@ -53,11 +54,11 @@ public class PathManagerTest { | ... | @@ -53,11 +54,11 @@ public class PathManagerTest { |
53 | private FakeHostMgr fakeHostMgr = new FakeHostMgr(); | 54 | private FakeHostMgr fakeHostMgr = new FakeHostMgr(); |
54 | 55 | ||
55 | @Before | 56 | @Before |
56 | - public void setUp() { | 57 | + public void setUp() throws Exception { |
57 | mgr = new PathManager(); | 58 | mgr = new PathManager(); |
58 | service = mgr; | 59 | service = mgr; |
59 | - mgr.topologyService = fakeTopoMgr; | 60 | + TestUtils.setField(mgr, "topologyService", fakeTopoMgr); |
60 | - mgr.hostService = fakeHostMgr; | 61 | + TestUtils.setField(mgr, "hostService", fakeHostMgr); |
61 | mgr.activate(); | 62 | mgr.activate(); |
62 | } | 63 | } |
63 | 64 | ... | ... |
... | @@ -61,6 +61,7 @@ import org.onosproject.net.intent.IntentState; | ... | @@ -61,6 +61,7 @@ import org.onosproject.net.intent.IntentState; |
61 | import org.onosproject.net.link.LinkService; | 61 | import org.onosproject.net.link.LinkService; |
62 | import org.onosproject.net.provider.AbstractListenerProviderRegistry; | 62 | import org.onosproject.net.provider.AbstractListenerProviderRegistry; |
63 | import org.onosproject.net.provider.AbstractProviderService; | 63 | import org.onosproject.net.provider.AbstractProviderService; |
64 | +import org.onosproject.net.topology.PathService; | ||
64 | import org.onosproject.net.topology.TopologyService; | 65 | import org.onosproject.net.topology.TopologyService; |
65 | import org.slf4j.Logger; | 66 | import org.slf4j.Logger; |
66 | import org.slf4j.LoggerFactory; | 67 | import org.slf4j.LoggerFactory; |
... | @@ -371,6 +372,8 @@ public class VirtualNetworkManager | ... | @@ -371,6 +372,8 @@ public class VirtualNetworkManager |
371 | service = new VirtualNetworkIntentService(this, network, new DefaultServiceDirectory()); | 372 | service = new VirtualNetworkIntentService(this, network, new DefaultServiceDirectory()); |
372 | } else if (serviceKey.serviceClass.equals(HostService.class)) { | 373 | } else if (serviceKey.serviceClass.equals(HostService.class)) { |
373 | service = new VirtualNetworkHostService(this, network); | 374 | service = new VirtualNetworkHostService(this, network); |
375 | + } else if (serviceKey.serviceClass.equals(PathService.class)) { | ||
376 | + service = new VirtualNetworkPathService(this, network); | ||
374 | } else { | 377 | } else { |
375 | return null; | 378 | return null; |
376 | } | 379 | } | ... | ... |
1 | +/* | ||
2 | + * | ||
3 | + * * Copyright 2016-present Open Networking Laboratory | ||
4 | + * * | ||
5 | + * * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * * you may not use this file except in compliance with the License. | ||
7 | + * * You may obtain a copy of the License at | ||
8 | + * * | ||
9 | + * * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * * | ||
11 | + * * Unless required by applicable law or agreed to in writing, software | ||
12 | + * * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * * See the License for the specific language governing permissions and | ||
15 | + * * limitations under the License. | ||
16 | + * | ||
17 | + */ | ||
18 | + | ||
19 | +package org.onosproject.incubator.net.virtual.impl; | ||
20 | + | ||
21 | +import org.onosproject.incubator.net.virtual.VirtualNetwork; | ||
22 | +import org.onosproject.incubator.net.virtual.VirtualNetworkService; | ||
23 | +import org.onosproject.net.DisjointPath; | ||
24 | +import org.onosproject.net.ElementId; | ||
25 | +import org.onosproject.net.Link; | ||
26 | +import org.onosproject.net.Path; | ||
27 | +import org.onosproject.net.host.HostService; | ||
28 | +import org.onosproject.net.topology.LinkWeight; | ||
29 | +import org.onosproject.net.topology.PathService; | ||
30 | +import org.onosproject.net.topology.AbstractPathService; | ||
31 | +import org.onosproject.net.topology.TopologyService; | ||
32 | + | ||
33 | +import java.util.Map; | ||
34 | +import java.util.Set; | ||
35 | + | ||
36 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
37 | + | ||
38 | +/** | ||
39 | + * Path service implementation built on the virtual network service. | ||
40 | + */ | ||
41 | +public class VirtualNetworkPathService extends AbstractPathService | ||
42 | + implements PathService, VnetService { | ||
43 | + | ||
44 | + private static final String NETWORK_NULL = "Network ID cannot be null"; | ||
45 | + | ||
46 | + private final VirtualNetwork network; | ||
47 | + | ||
48 | + /** | ||
49 | + * Creates a new virtual network path service object. | ||
50 | + * | ||
51 | + * @param virtualNetworkManager virtual network manager service | ||
52 | + * @param network virtual network | ||
53 | + */ | ||
54 | + | ||
55 | + public VirtualNetworkPathService(VirtualNetworkService virtualNetworkManager, VirtualNetwork network) { | ||
56 | + checkNotNull(network, NETWORK_NULL); | ||
57 | + this.network = network; | ||
58 | + topologyService = virtualNetworkManager.get(network.id(), TopologyService.class); | ||
59 | + hostService = virtualNetworkManager.get(network.id(), HostService.class); | ||
60 | + } | ||
61 | + | ||
62 | + @Override | ||
63 | + public Set<Path> getPaths(ElementId src, ElementId dst) { | ||
64 | + return getPaths(src, dst, null); | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst) { | ||
69 | + return getDisjointPaths(src, dst, (LinkWeight) null); | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, Map<Link, Object> riskProfile) { | ||
74 | + return getDisjointPaths(src, dst, null, riskProfile); | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public VirtualNetwork network() { | ||
79 | + return network; | ||
80 | + } | ||
81 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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 | + | ||
17 | +package org.onosproject.incubator.net.virtual.impl; | ||
18 | + | ||
19 | +import org.junit.After; | ||
20 | +import org.junit.Before; | ||
21 | +import org.junit.Test; | ||
22 | +import org.onlab.junit.TestUtils; | ||
23 | +import org.onosproject.common.event.impl.TestEventDispatcher; | ||
24 | +import org.onosproject.core.CoreService; | ||
25 | +import org.onosproject.incubator.net.virtual.TenantId; | ||
26 | +import org.onosproject.incubator.net.virtual.VirtualDevice; | ||
27 | +import org.onosproject.incubator.net.virtual.VirtualLink; | ||
28 | +import org.onosproject.incubator.net.virtual.VirtualNetwork; | ||
29 | +import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; | ||
30 | +import org.onosproject.net.ConnectPoint; | ||
31 | +import org.onosproject.net.DefaultPort; | ||
32 | +import org.onosproject.net.DeviceId; | ||
33 | +import org.onosproject.net.DisjointPath; | ||
34 | +import org.onosproject.net.ElementId; | ||
35 | +import org.onosproject.net.Link; | ||
36 | +import org.onosproject.net.NetTestTools; | ||
37 | +import org.onosproject.net.Path; | ||
38 | +import org.onosproject.net.PortNumber; | ||
39 | +import org.onosproject.net.TestDeviceParams; | ||
40 | +import org.onosproject.net.intent.FakeIntentManager; | ||
41 | +import org.onosproject.net.intent.TestableIntentService; | ||
42 | +import org.onosproject.net.topology.LinkWeight; | ||
43 | +import org.onosproject.net.topology.PathService; | ||
44 | +import org.onosproject.store.service.TestStorageService; | ||
45 | + | ||
46 | +import java.util.Set; | ||
47 | + | ||
48 | +import static org.junit.Assert.assertEquals; | ||
49 | + | ||
50 | +/** | ||
51 | + * Junit tests for VirtualNetworkPathService. | ||
52 | + */ | ||
53 | +public class VirtualNetworkPathServiceTest extends TestDeviceParams { | ||
54 | + private final String tenantIdValue1 = "TENANT_ID1"; | ||
55 | + | ||
56 | + private VirtualNetworkManager manager; | ||
57 | + private DistributedVirtualNetworkStore virtualNetworkManagerStore; | ||
58 | + private final TestableIntentService intentService = new FakeIntentManager(); | ||
59 | + | ||
60 | + @Before | ||
61 | + public void setUp() throws Exception { | ||
62 | + virtualNetworkManagerStore = new DistributedVirtualNetworkStore(); | ||
63 | + | ||
64 | + CoreService coreService = new TestCoreService(); | ||
65 | + virtualNetworkManagerStore.setCoreService(coreService); | ||
66 | + TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService()); | ||
67 | + virtualNetworkManagerStore.activate(); | ||
68 | + | ||
69 | + manager = new VirtualNetworkManager(); | ||
70 | + manager.store = virtualNetworkManagerStore; | ||
71 | + manager.intentService = intentService; | ||
72 | + NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); | ||
73 | + manager.activate(); | ||
74 | + } | ||
75 | + | ||
76 | + @After | ||
77 | + public void tearDown() { | ||
78 | + virtualNetworkManagerStore.deactivate(); | ||
79 | + manager.deactivate(); | ||
80 | + NetTestTools.injectEventDispatcher(manager, null); | ||
81 | + } | ||
82 | + | ||
83 | + /** | ||
84 | + * Sets up an empty virtual network (no devices, links). | ||
85 | + * | ||
86 | + * @return virtual network | ||
87 | + */ | ||
88 | + private VirtualNetwork setupEmptyVnet() { | ||
89 | + manager.registerTenantId(TenantId.tenantId(tenantIdValue1)); | ||
90 | + return manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1)); | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * Creates a virtual network for further testing. | ||
95 | + * | ||
96 | + * @return virtual network | ||
97 | + */ | ||
98 | + private VirtualNetwork setupVnet() { | ||
99 | + manager.registerTenantId(TenantId.tenantId(tenantIdValue1)); | ||
100 | + VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1)); | ||
101 | + VirtualDevice virtualDevice1 = | ||
102 | + manager.createVirtualDevice(virtualNetwork.id(), DID1); | ||
103 | + VirtualDevice virtualDevice2 = | ||
104 | + manager.createVirtualDevice(virtualNetwork.id(), DID2); | ||
105 | + VirtualDevice virtualDevice3 = | ||
106 | + manager.createVirtualDevice(virtualNetwork.id(), DID3); | ||
107 | + VirtualDevice virtualDevice4 = | ||
108 | + manager.createVirtualDevice(virtualNetwork.id(), DID4); | ||
109 | + | ||
110 | + ConnectPoint cp11 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice1, 1); | ||
111 | + ConnectPoint cp12 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice1, 2); | ||
112 | + ConnectPoint cp23 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice2, 3); | ||
113 | + ConnectPoint cp24 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice2, 4); | ||
114 | + ConnectPoint cp35 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice3, 5); | ||
115 | + ConnectPoint cp36 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice3, 6); | ||
116 | + VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp11, cp23); | ||
117 | + virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE); | ||
118 | + VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp23, cp11); | ||
119 | + virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE); | ||
120 | + VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp24, cp35); | ||
121 | + virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE); | ||
122 | + VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp35, cp24); | ||
123 | + virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE); | ||
124 | + VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp12, cp36); | ||
125 | + virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE); | ||
126 | + VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp36, cp12); | ||
127 | + virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE); | ||
128 | + | ||
129 | + return virtualNetwork; | ||
130 | + } | ||
131 | + | ||
132 | + /** | ||
133 | + * Creates a connect point and related virtual port. | ||
134 | + * | ||
135 | + * @param vnet virtual network | ||
136 | + * @param vDev virtual device | ||
137 | + * @param portNumber port number | ||
138 | + * @return connect point | ||
139 | + */ | ||
140 | + private ConnectPoint createConnectPointAndVirtualPort( | ||
141 | + VirtualNetwork vnet, VirtualDevice vDev, long portNumber) { | ||
142 | + ConnectPoint cp = new ConnectPoint(vDev.id(), PortNumber.portNumber(portNumber)); | ||
143 | + manager.createVirtualPort(vnet.id(), cp.deviceId(), cp.port(), | ||
144 | + new DefaultPort(vDev, cp.port(), true)); | ||
145 | + return cp; | ||
146 | + } | ||
147 | + | ||
148 | + /** | ||
149 | + * Tests getPaths(), getDisjointPaths() | ||
150 | + * on a non-empty virtual network. | ||
151 | + */ | ||
152 | + @Test | ||
153 | + public void testGetPathsOnNonEmptyVnet() { | ||
154 | + VirtualNetwork vnet = setupVnet(); | ||
155 | + PathService pathService = manager.get(vnet.id(), PathService.class); | ||
156 | + | ||
157 | + // src and dest are in vnet and are connected by a virtual link | ||
158 | + Set<Path> paths = pathService.getPaths(DID1, DID3); | ||
159 | + validatePaths(paths, 1, 1, DID1, DID3, 1.0); | ||
160 | + | ||
161 | + LinkWeight linkWeight = edge -> 2.0; | ||
162 | + paths = pathService.getPaths(DID1, DID3, linkWeight); | ||
163 | + validatePaths(paths, 1, 1, DID1, DID3, 2.0); | ||
164 | + | ||
165 | + Set<DisjointPath> disjointPaths = pathService.getDisjointPaths(DID1, DID3); | ||
166 | + validatePaths(disjointPaths, 1, 1, DID1, DID3, 1.0); | ||
167 | + | ||
168 | + disjointPaths = pathService.getDisjointPaths(DID1, DID3, linkWeight); | ||
169 | + validatePaths(disjointPaths, 1, 1, DID1, DID3, 2.0); | ||
170 | + | ||
171 | + // src and dest are in vnet but are not connected | ||
172 | + paths = pathService.getPaths(DID4, DID3); | ||
173 | + assertEquals("incorrect path count", 0, paths.size()); | ||
174 | + | ||
175 | + disjointPaths = pathService.getDisjointPaths(DID4, DID3); | ||
176 | + assertEquals("incorrect path count", 0, disjointPaths.size()); | ||
177 | + | ||
178 | + // src is in vnet, but dest is not in vnet. | ||
179 | + DeviceId nonExistentDeviceId = DeviceId.deviceId("nonExistentDevice"); | ||
180 | + paths = pathService.getPaths(DID2, nonExistentDeviceId); | ||
181 | + assertEquals("incorrect path count", 0, paths.size()); | ||
182 | + | ||
183 | + disjointPaths = pathService.getDisjointPaths(DID2, nonExistentDeviceId); | ||
184 | + assertEquals("incorrect path count", 0, disjointPaths.size()); | ||
185 | + } | ||
186 | + | ||
187 | + /** | ||
188 | + * Tests getPaths(), getDisjointPaths() | ||
189 | + * on an empty virtual network. | ||
190 | + */ | ||
191 | + @Test | ||
192 | + public void testGetPathsOnEmptyVnet() { | ||
193 | + VirtualNetwork vnet = setupEmptyVnet(); | ||
194 | + PathService pathService = manager.get(vnet.id(), PathService.class); | ||
195 | + | ||
196 | + Set<Path> paths = pathService.getPaths(DID1, DID3); | ||
197 | + assertEquals("incorrect path count", 0, paths.size()); | ||
198 | + | ||
199 | + Set<DisjointPath> disjointPaths = pathService.getDisjointPaths(DID1, DID3); | ||
200 | + assertEquals("incorrect path count", 0, disjointPaths.size()); | ||
201 | + } | ||
202 | + | ||
203 | + /** | ||
204 | + * Tests getPaths() using a null source device on an empty virtual network. | ||
205 | + */ | ||
206 | + @Test(expected = NullPointerException.class) | ||
207 | + public void testGetPathsWithNullSrc() { | ||
208 | + VirtualNetwork vnet = setupEmptyVnet(); | ||
209 | + PathService pathService = manager.get(vnet.id(), PathService.class); | ||
210 | + pathService.getPaths(null, DID3); | ||
211 | + } | ||
212 | + | ||
213 | + /** | ||
214 | + * Tests getPaths() using a null destination device on a non-empty virtual network. | ||
215 | + */ | ||
216 | + @Test(expected = NullPointerException.class) | ||
217 | + public void testGetPathsWithNullDest() { | ||
218 | + VirtualNetwork vnet = setupVnet(); | ||
219 | + PathService pathService = manager.get(vnet.id(), PathService.class); | ||
220 | + pathService.getPaths(DID1, null); | ||
221 | + } | ||
222 | + | ||
223 | + | ||
224 | + // Makes sure the set of paths meets basic expectations. | ||
225 | + private void validatePaths(Set<? extends Path> paths, int count, int length, | ||
226 | + ElementId src, ElementId dst, double cost) { | ||
227 | + assertEquals("incorrect path count", count, paths.size()); | ||
228 | + for (Path path : paths) { | ||
229 | + assertEquals("incorrect length", length, path.links().size()); | ||
230 | + assertEquals("incorrect source", src, path.src().elementId()); | ||
231 | + assertEquals("incorrect destination", dst, path.dst().elementId()); | ||
232 | + assertEquals("incorrect cost", cost, path.cost(), 0); | ||
233 | + } | ||
234 | + } | ||
235 | +} |
-
Please register or login to post a comment