Added PathService and initial implementation; tests coming soon.
Showing
2 changed files
with
222 additions
and
0 deletions
1 | +package org.onlab.onos.net.path; | ||
2 | + | ||
3 | +import org.onlab.onos.net.DeviceId; | ||
4 | +import org.onlab.onos.net.HostId; | ||
5 | +import org.onlab.onos.net.Path; | ||
6 | +import org.onlab.onos.net.topology.LinkWeight; | ||
7 | + | ||
8 | +import java.util.Set; | ||
9 | + | ||
10 | +/** | ||
11 | + * Service for obtaining pre-computed paths or for requesting computation of | ||
12 | + * paths using the current topology snapshot. | ||
13 | + */ | ||
14 | +public interface PathService { | ||
15 | + | ||
16 | + /** | ||
17 | + * Returns the set of all shortest paths, precomputed in terms of hop-count, | ||
18 | + * between the specified source and destination devices. | ||
19 | + * | ||
20 | + * @param src source device | ||
21 | + * @param dst destination device | ||
22 | + * @return set of all shortest paths between the two devices | ||
23 | + */ | ||
24 | + Set<Path> getPaths(DeviceId src, DeviceId dst); | ||
25 | + | ||
26 | + /** | ||
27 | + * Returns the set of all shortest paths, computed using the supplied | ||
28 | + * edge-weight entity, between the specified source and destination devices. | ||
29 | + * | ||
30 | + * @param src source device | ||
31 | + * @param dst destination device | ||
32 | + * @return set of all shortest paths between the two devices | ||
33 | + */ | ||
34 | + Set<Path> getPaths(DeviceId src, DeviceId dst, | ||
35 | + LinkWeight weight); | ||
36 | + | ||
37 | + | ||
38 | + /** | ||
39 | + * Returns the set of all shortest paths, precomputed in terms of hop-count, | ||
40 | + * between the specified source and destination end-stations. | ||
41 | + * | ||
42 | + * @param src source device | ||
43 | + * @param dst destination device | ||
44 | + * @return set of all shortest paths between the two end-stations hosts | ||
45 | + */ | ||
46 | + Set<Path> getPaths(HostId src, HostId dst); | ||
47 | + | ||
48 | + /** | ||
49 | + * Returns the set of all shortest paths, computed using the supplied | ||
50 | + * edge-weight entity, between the specified source and end-stations. | ||
51 | + * | ||
52 | + * @param src source host | ||
53 | + * @param dst destination host | ||
54 | + * @return set of all shortest paths between the two end-station hosts | ||
55 | + */ | ||
56 | + Set<Path> getPaths(HostId src, HostId dst, LinkWeight weight); | ||
57 | + | ||
58 | +} |
1 | +package org.onlab.onos.net.trivial.path; | ||
2 | + | ||
3 | +import com.google.common.collect.Lists; | ||
4 | +import com.google.common.collect.Sets; | ||
5 | +import org.apache.felix.scr.annotations.Activate; | ||
6 | +import org.apache.felix.scr.annotations.Component; | ||
7 | +import org.apache.felix.scr.annotations.Deactivate; | ||
8 | +import org.apache.felix.scr.annotations.Reference; | ||
9 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
10 | +import org.apache.felix.scr.annotations.Service; | ||
11 | +import org.onlab.onos.net.ConnectPoint; | ||
12 | +import org.onlab.onos.net.DefaultEdgeLink; | ||
13 | +import org.onlab.onos.net.DefaultPath; | ||
14 | +import org.onlab.onos.net.DeviceId; | ||
15 | +import org.onlab.onos.net.EdgeLink; | ||
16 | +import org.onlab.onos.net.Host; | ||
17 | +import org.onlab.onos.net.HostId; | ||
18 | +import org.onlab.onos.net.Link; | ||
19 | +import org.onlab.onos.net.Path; | ||
20 | +import org.onlab.onos.net.PortNumber; | ||
21 | +import org.onlab.onos.net.host.HostService; | ||
22 | +import org.onlab.onos.net.path.PathService; | ||
23 | +import org.onlab.onos.net.provider.ProviderId; | ||
24 | +import org.onlab.onos.net.topology.LinkWeight; | ||
25 | +import org.onlab.onos.net.topology.Topology; | ||
26 | +import org.onlab.onos.net.topology.TopologyService; | ||
27 | +import org.slf4j.Logger; | ||
28 | + | ||
29 | +import java.util.List; | ||
30 | +import java.util.Set; | ||
31 | + | ||
32 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
33 | +import static org.slf4j.LoggerFactory.getLogger; | ||
34 | + | ||
35 | +/** | ||
36 | + * Provides implementation of a path selection service atop the current | ||
37 | + * topology and host services. | ||
38 | + */ | ||
39 | +@Component(immediate = true) | ||
40 | +@Service | ||
41 | +public class PathManager implements PathService { | ||
42 | + | ||
43 | + private static final String DEVICE_ID_NULL = "Device ID cannot be null"; | ||
44 | + private static final String HOST_ID_NULL = "Host ID cannot be null"; | ||
45 | + | ||
46 | + private static final ProviderId PID = new ProviderId("org.onlab.onos.core"); | ||
47 | + private static final PortNumber P0 = PortNumber.portNumber(0); | ||
48 | + | ||
49 | + private final Logger log = getLogger(getClass()); | ||
50 | + | ||
51 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
52 | + protected TopologyService topologyService; | ||
53 | + | ||
54 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
55 | + protected HostService hostService; | ||
56 | + | ||
57 | + @Activate | ||
58 | + public void setUp() { | ||
59 | + log.info("Started"); | ||
60 | + } | ||
61 | + | ||
62 | + @Deactivate | ||
63 | + public void tearDown() { | ||
64 | + log.info("Stopped"); | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public Set<Path> getPaths(DeviceId src, DeviceId dst) { | ||
69 | + checkNotNull(src, DEVICE_ID_NULL); | ||
70 | + checkNotNull(dst, DEVICE_ID_NULL); | ||
71 | + Topology topology = topologyService.currentTopology(); | ||
72 | + return topologyService.getPaths(topology, src, dst); | ||
73 | + } | ||
74 | + | ||
75 | + @Override | ||
76 | + public Set<Path> getPaths(DeviceId src, DeviceId dst, LinkWeight weight) { | ||
77 | + checkNotNull(src, DEVICE_ID_NULL); | ||
78 | + checkNotNull(dst, DEVICE_ID_NULL); | ||
79 | + Topology topology = topologyService.currentTopology(); | ||
80 | + return topologyService.getPaths(topology, src, dst, weight); | ||
81 | + } | ||
82 | + | ||
83 | + @Override | ||
84 | + public Set<Path> getPaths(HostId src, HostId dst) { | ||
85 | + return getPaths(src, dst, null); | ||
86 | + } | ||
87 | + | ||
88 | + @Override | ||
89 | + public Set<Path> getPaths(HostId src, HostId dst, LinkWeight weight) { | ||
90 | + checkNotNull(src, HOST_ID_NULL); | ||
91 | + checkNotNull(dst, HOST_ID_NULL); | ||
92 | + | ||
93 | + // Resolve the source host, bail if unable. | ||
94 | + Host srcHost = hostService.getHost(src); | ||
95 | + if (srcHost == null) { | ||
96 | + return Sets.newHashSet(); | ||
97 | + } | ||
98 | + | ||
99 | + // Resolve the destination host, bail if unable. | ||
100 | + Host dstHost = hostService.getHost(dst); | ||
101 | + if (dstHost == null) { | ||
102 | + return Sets.newHashSet(); | ||
103 | + } | ||
104 | + | ||
105 | + // Get the source and destination edge locations | ||
106 | + EdgeLink srcEdge = new DefaultEdgeLink(PID, new ConnectPoint(src, P0), | ||
107 | + srcHost.location(), true); | ||
108 | + EdgeLink dstEdge = new DefaultEdgeLink(PID, new ConnectPoint(dst, P0), | ||
109 | + dstHost.location(), false); | ||
110 | + | ||
111 | + // If the source and destination are on the same edge device, there | ||
112 | + // is just one path, so build it and return it. | ||
113 | + if (srcEdge.dst().deviceId().equals(dstEdge.src().deviceId())) { | ||
114 | + return edgeToEdgePaths(srcEdge, dstEdge); | ||
115 | + } | ||
116 | + | ||
117 | + // Otherwise get all paths between the source and destination edge | ||
118 | + // devices. | ||
119 | + Topology topology = topologyService.currentTopology(); | ||
120 | + Set<Path> paths = weight == null ? | ||
121 | + topologyService.getPaths(topology, srcEdge.dst().deviceId(), | ||
122 | + dstEdge.src().deviceId()) : | ||
123 | + topologyService.getPaths(topology, srcEdge.dst().deviceId(), | ||
124 | + dstEdge.src().deviceId(), weight); | ||
125 | + | ||
126 | + return edgeToEdgePaths(srcEdge, dstEdge, paths); | ||
127 | + } | ||
128 | + | ||
129 | + // Produces a set of direct edge-to-edge paths. | ||
130 | + private Set<Path> edgeToEdgePaths(EdgeLink srcLink, EdgeLink dstLink) { | ||
131 | + Set<Path> endToEndPaths = Sets.newHashSetWithExpectedSize(1); | ||
132 | + endToEndPaths.add(edgeToEdgePath(srcLink, dstLink)); | ||
133 | + return endToEndPaths; | ||
134 | + } | ||
135 | + | ||
136 | + // Produces a direct edge-to-edge path. | ||
137 | + private Path edgeToEdgePath(EdgeLink srcLink, EdgeLink dstLink) { | ||
138 | + List<Link> links = Lists.newArrayListWithCapacity(2); | ||
139 | + links.add(srcLink); | ||
140 | + links.add(dstLink); | ||
141 | + return new DefaultPath(PID, links, 2); | ||
142 | + } | ||
143 | + | ||
144 | + // Produces a set of edge-to-edge paths using the set of infrastructure | ||
145 | + // paths and the given edge links. | ||
146 | + private Set<Path> edgeToEdgePaths(EdgeLink srcLink, EdgeLink dstLink, Set<Path> paths) { | ||
147 | + Set<Path> endToEndPaths = Sets.newHashSetWithExpectedSize(paths.size()); | ||
148 | + for (Path path : paths) { | ||
149 | + endToEndPaths.add(edgeToEdgePath(srcLink, dstLink, path)); | ||
150 | + } | ||
151 | + return endToEndPaths; | ||
152 | + } | ||
153 | + | ||
154 | + // Produces an edge-to-edge path using the specified infrastructure path | ||
155 | + // and edge links. | ||
156 | + private Path edgeToEdgePath(EdgeLink srcLink, EdgeLink dstLink, Path path) { | ||
157 | + List<Link> links = Lists.newArrayListWithCapacity(path.links().size() + 2); | ||
158 | + links.add(srcLink); | ||
159 | + links.addAll(path.links()); | ||
160 | + links.add(dstLink); | ||
161 | + return new DefaultPath(path.providerId(), links, path.cost() + 2); | ||
162 | + } | ||
163 | + | ||
164 | +} |
-
Please register or login to post a comment