tom

Added PathService and initial implementation; tests coming soon.

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 +}