Enhanced topo viewer sample GUI to allow path selection from any node (host or d…
…evice). Fixed path service implementaiton.
Showing
7 changed files
with
81 additions
and
91 deletions
... | @@ -11,6 +11,7 @@ import org.onlab.onos.net.Path; | ... | @@ -11,6 +11,7 @@ import org.onlab.onos.net.Path; |
11 | import org.onlab.onos.net.device.DeviceService; | 11 | import org.onlab.onos.net.device.DeviceService; |
12 | import org.onlab.onos.net.host.HostService; | 12 | import org.onlab.onos.net.host.HostService; |
13 | import org.onlab.onos.net.link.LinkService; | 13 | import org.onlab.onos.net.link.LinkService; |
14 | +import org.onlab.onos.net.path.PathService; | ||
14 | import org.onlab.onos.net.topology.Topology; | 15 | import org.onlab.onos.net.topology.Topology; |
15 | import org.onlab.onos.net.topology.TopologyGraph; | 16 | import org.onlab.onos.net.topology.TopologyGraph; |
16 | import org.onlab.onos.net.topology.TopologyService; | 17 | import org.onlab.onos.net.topology.TopologyService; |
... | @@ -28,6 +29,7 @@ import java.util.Map; | ... | @@ -28,6 +29,7 @@ import java.util.Map; |
28 | import java.util.Set; | 29 | import java.util.Set; |
29 | 30 | ||
30 | import static org.onlab.onos.net.DeviceId.deviceId; | 31 | import static org.onlab.onos.net.DeviceId.deviceId; |
32 | +import static org.onlab.onos.net.HostId.hostId; | ||
31 | import static org.onlab.onos.net.PortNumber.portNumber; | 33 | import static org.onlab.onos.net.PortNumber.portNumber; |
32 | 34 | ||
33 | /** | 35 | /** |
... | @@ -99,12 +101,11 @@ public class TopologyResource extends BaseResource { | ... | @@ -99,12 +101,11 @@ public class TopologyResource extends BaseResource { |
99 | @Produces("application/json") | 101 | @Produces("application/json") |
100 | public Response paths(@PathParam("src") String src, @PathParam("dst") String dst) { | 102 | public Response paths(@PathParam("src") String src, @PathParam("dst") String dst) { |
101 | ObjectMapper mapper = new ObjectMapper(); | 103 | ObjectMapper mapper = new ObjectMapper(); |
102 | - | 104 | + PathService pathService = get(PathService.class); |
103 | - TopologyService topologyService = get(TopologyService.class); | 105 | + Set<Path> paths = pathService.getPaths(elementId(src), elementId(dst)); |
104 | - Topology topology = topologyService.currentTopology(); | ||
105 | 106 | ||
106 | ArrayNode pathsNode = mapper.createArrayNode(); | 107 | ArrayNode pathsNode = mapper.createArrayNode(); |
107 | - for (Path path : topologyService.getPaths(topology, deviceId(src), deviceId(dst))) { | 108 | + for (Path path : paths) { |
108 | pathsNode.add(json(mapper, path)); | 109 | pathsNode.add(json(mapper, path)); |
109 | } | 110 | } |
110 | 111 | ||
... | @@ -114,6 +115,11 @@ public class TopologyResource extends BaseResource { | ... | @@ -114,6 +115,11 @@ public class TopologyResource extends BaseResource { |
114 | return Response.ok(rootNode.toString()).build(); | 115 | return Response.ok(rootNode.toString()).build(); |
115 | } | 116 | } |
116 | 117 | ||
118 | + // Creates either device ID or host ID as appropriate. | ||
119 | + private ElementId elementId(String id) { | ||
120 | + return id.startsWith("nic:") ? hostId(id) : deviceId(id); | ||
121 | + } | ||
122 | + | ||
117 | // Scan all links and counts number of them between the same devices | 123 | // Scan all links and counts number of them between the same devices |
118 | // using a normalized link key. | 124 | // using a normalized link key. |
119 | private Map<String, AggLink> aggregateLinks() { | 125 | private Map<String, AggLink> aggregateLinks() { | ... | ... |
... | @@ -23,8 +23,8 @@ public class DefaultEdgeLink extends DefaultLink implements EdgeLink { | ... | @@ -23,8 +23,8 @@ public class DefaultEdgeLink extends DefaultLink implements EdgeLink { |
23 | */ | 23 | */ |
24 | public DefaultEdgeLink(ProviderId providerId, ConnectPoint hostPoint, | 24 | public DefaultEdgeLink(ProviderId providerId, ConnectPoint hostPoint, |
25 | HostLocation hostLocation, boolean isIngress) { | 25 | HostLocation hostLocation, boolean isIngress) { |
26 | - super(providerId, isIngress ? hostLocation : hostPoint, | 26 | + super(providerId, isIngress ? hostPoint : hostLocation, |
27 | - isIngress ? hostPoint : hostLocation, Type.EDGE); | 27 | + isIngress ? hostLocation : hostPoint, Type.EDGE); |
28 | checkArgument(hostPoint.elementId() instanceof HostId, | 28 | checkArgument(hostPoint.elementId() instanceof HostId, |
29 | "Host point does not refer to a host ID"); | 29 | "Host point does not refer to a host ID"); |
30 | this.hostId = (HostId) hostPoint.elementId(); | 30 | this.hostId = (HostId) hostPoint.elementId(); | ... | ... |
... | @@ -44,7 +44,7 @@ public final class HostId extends ElementId { | ... | @@ -44,7 +44,7 @@ public final class HostId extends ElementId { |
44 | */ | 44 | */ |
45 | public static HostId hostId(MACAddress mac, VLANID vlanId) { | 45 | public static HostId hostId(MACAddress mac, VLANID vlanId) { |
46 | // FIXME: use more efficient means of encoding | 46 | // FIXME: use more efficient means of encoding |
47 | - return hostId("nic" + ":" + mac + "/" + vlanId); | 47 | + return hostId("nic" + ":" + mac + "-" + vlanId); |
48 | } | 48 | } |
49 | 49 | ||
50 | /** | 50 | /** | ... | ... |
1 | package org.onlab.onos.net.path; | 1 | package org.onlab.onos.net.path; |
2 | 2 | ||
3 | -import org.onlab.onos.net.DeviceId; | 3 | +import org.onlab.onos.net.ElementId; |
4 | -import org.onlab.onos.net.HostId; | ||
5 | import org.onlab.onos.net.Path; | 4 | import org.onlab.onos.net.Path; |
6 | import org.onlab.onos.net.topology.LinkWeight; | 5 | import org.onlab.onos.net.topology.LinkWeight; |
7 | 6 | ||
... | @@ -15,44 +14,23 @@ public interface PathService { | ... | @@ -15,44 +14,23 @@ public interface PathService { |
15 | 14 | ||
16 | /** | 15 | /** |
17 | * Returns the set of all shortest paths, precomputed in terms of hop-count, | 16 | * Returns the set of all shortest paths, precomputed in terms of hop-count, |
18 | - * between the specified source and destination devices. | 17 | + * between the specified source and destination elements. |
19 | * | 18 | * |
20 | - * @param src source device | 19 | + * @param src source element |
21 | - * @param dst destination device | 20 | + * @param dst destination element |
22 | - * @return set of all shortest paths between the two devices | 21 | + * @return set of all shortest paths between the two elements |
23 | */ | 22 | */ |
24 | - Set<Path> getPaths(DeviceId src, DeviceId dst); | 23 | + Set<Path> getPaths(ElementId src, ElementId dst); |
25 | 24 | ||
26 | /** | 25 | /** |
27 | * Returns the set of all shortest paths, computed using the supplied | 26 | * Returns the set of all shortest paths, computed using the supplied |
28 | - * edge-weight entity, between the specified source and destination devices. | 27 | + * edge-weight entity, between the specified source and destination |
28 | + * network elements. | ||
29 | * | 29 | * |
30 | - * @param src source device | 30 | + * @param src source element |
31 | - * @param dst destination device | 31 | + * @param dst destination element |
32 | - * @return set of all shortest paths between the two devices | 32 | + * @return set of all shortest paths between the two element |
33 | */ | 33 | */ |
34 | - Set<Path> getPaths(DeviceId src, DeviceId dst, | 34 | + Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight); |
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 | 35 | ||
58 | } | 36 | } | ... | ... |
... | @@ -47,8 +47,8 @@ public class DefaultEdgeLinkTest { | ... | @@ -47,8 +47,8 @@ public class DefaultEdgeLinkTest { |
47 | public void basics() { | 47 | public void basics() { |
48 | HostLocation hostLocation = new HostLocation(DID1, P1, 123L); | 48 | HostLocation hostLocation = new HostLocation(DID1, P1, 123L); |
49 | EdgeLink link = new DefaultEdgeLink(PID, cp(HID1, P0), hostLocation, false); | 49 | EdgeLink link = new DefaultEdgeLink(PID, cp(HID1, P0), hostLocation, false); |
50 | - assertEquals("incorrect src", cp(HID1, P0), link.src()); | 50 | + assertEquals("incorrect src", cp(HID1, P0), link.dst()); |
51 | - assertEquals("incorrect dst", hostLocation, link.dst()); | 51 | + assertEquals("incorrect dst", hostLocation, link.src()); |
52 | assertEquals("incorrect type", Link.Type.EDGE, link.type()); | 52 | assertEquals("incorrect type", Link.Type.EDGE, link.type()); |
53 | assertEquals("incorrect hostId", HID1, link.hostId()); | 53 | assertEquals("incorrect hostId", HID1, link.hostId()); |
54 | assertEquals("incorrect connect point", hostLocation, link.hostLocation()); | 54 | assertEquals("incorrect connect point", hostLocation, link.hostLocation()); | ... | ... |
... | @@ -22,7 +22,7 @@ public class HostIdTest extends ElementIdTest { | ... | @@ -22,7 +22,7 @@ public class HostIdTest extends ElementIdTest { |
22 | @Test | 22 | @Test |
23 | public void basics() { | 23 | public void basics() { |
24 | new EqualsTester() | 24 | new EqualsTester() |
25 | - .addEqualityGroup(hostId("nic:00:11:00:00:00:01/11"), | 25 | + .addEqualityGroup(hostId("nic:00:11:00:00:00:01-11"), |
26 | hostId(MAC1, VLAN1)) | 26 | hostId(MAC1, VLAN1)) |
27 | .addEqualityGroup(hostId(MAC2, VLAN2)) | 27 | .addEqualityGroup(hostId(MAC2, VLAN2)) |
28 | .testEquals(); | 28 | .testEquals(); | ... | ... |
... | @@ -13,8 +13,10 @@ import org.onlab.onos.net.DefaultEdgeLink; | ... | @@ -13,8 +13,10 @@ import org.onlab.onos.net.DefaultEdgeLink; |
13 | import org.onlab.onos.net.DefaultPath; | 13 | import org.onlab.onos.net.DefaultPath; |
14 | import org.onlab.onos.net.DeviceId; | 14 | import org.onlab.onos.net.DeviceId; |
15 | import org.onlab.onos.net.EdgeLink; | 15 | import org.onlab.onos.net.EdgeLink; |
16 | +import org.onlab.onos.net.ElementId; | ||
16 | import org.onlab.onos.net.Host; | 17 | import org.onlab.onos.net.Host; |
17 | import org.onlab.onos.net.HostId; | 18 | import org.onlab.onos.net.HostId; |
19 | +import org.onlab.onos.net.HostLocation; | ||
18 | import org.onlab.onos.net.Link; | 20 | import org.onlab.onos.net.Link; |
19 | import org.onlab.onos.net.Path; | 21 | import org.onlab.onos.net.Path; |
20 | import org.onlab.onos.net.PortNumber; | 22 | import org.onlab.onos.net.PortNumber; |
... | @@ -30,6 +32,7 @@ import java.util.List; | ... | @@ -30,6 +32,7 @@ import java.util.List; |
30 | import java.util.Set; | 32 | import java.util.Set; |
31 | 33 | ||
32 | import static com.google.common.base.Preconditions.checkNotNull; | 34 | import static com.google.common.base.Preconditions.checkNotNull; |
35 | +import static org.onlab.onos.net.DeviceId.deviceId; | ||
33 | import static org.slf4j.LoggerFactory.getLogger; | 36 | import static org.slf4j.LoggerFactory.getLogger; |
34 | 37 | ||
35 | /** | 38 | /** |
... | @@ -38,14 +41,15 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -38,14 +41,15 @@ import static org.slf4j.LoggerFactory.getLogger; |
38 | */ | 41 | */ |
39 | @Component(immediate = true) | 42 | @Component(immediate = true) |
40 | @Service | 43 | @Service |
41 | -public class PathManager implements PathService { | 44 | +public class SimplePathManager implements PathService { |
42 | 45 | ||
43 | - private static final String DEVICE_ID_NULL = "Device ID cannot be null"; | 46 | + private static final String ELEMENT_ID_NULL = "Element ID cannot be null"; |
44 | - private static final String HOST_ID_NULL = "Host ID cannot be null"; | ||
45 | 47 | ||
46 | private static final ProviderId PID = new ProviderId("org.onlab.onos.core"); | 48 | private static final ProviderId PID = new ProviderId("org.onlab.onos.core"); |
47 | private static final PortNumber P0 = PortNumber.portNumber(0); | 49 | private static final PortNumber P0 = PortNumber.portNumber(0); |
48 | 50 | ||
51 | + private static final EdgeLink NOT_HOST = new NotHost(); | ||
52 | + | ||
49 | private final Logger log = getLogger(getClass()); | 53 | private final Logger log = getLogger(getClass()); |
50 | 54 | ||
51 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 55 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
... | @@ -65,52 +69,25 @@ public class PathManager implements PathService { | ... | @@ -65,52 +69,25 @@ public class PathManager implements PathService { |
65 | } | 69 | } |
66 | 70 | ||
67 | @Override | 71 | @Override |
68 | - public Set<Path> getPaths(DeviceId src, DeviceId dst) { | 72 | + public Set<Path> getPaths(ElementId src, ElementId 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); | 73 | return getPaths(src, dst, null); |
86 | } | 74 | } |
87 | 75 | ||
88 | @Override | 76 | @Override |
89 | - public Set<Path> getPaths(HostId src, HostId dst, LinkWeight weight) { | 77 | + public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) { |
90 | - checkNotNull(src, HOST_ID_NULL); | 78 | + checkNotNull(src, ELEMENT_ID_NULL); |
91 | - checkNotNull(dst, HOST_ID_NULL); | 79 | + checkNotNull(dst, ELEMENT_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 | 80 | ||
105 | // Get the source and destination edge locations | 81 | // Get the source and destination edge locations |
106 | - EdgeLink srcEdge = new DefaultEdgeLink(PID, new ConnectPoint(src, P0), | 82 | + EdgeLink srcEdge = getEdgeLink(src, true); |
107 | - srcHost.location(), true); | 83 | + EdgeLink dstEdge = getEdgeLink(dst, false); |
108 | - EdgeLink dstEdge = new DefaultEdgeLink(PID, new ConnectPoint(dst, P0), | 84 | + |
109 | - dstHost.location(), false); | 85 | + DeviceId srcDevice = srcEdge != NOT_HOST ? srcEdge.dst().deviceId() : (DeviceId) src; |
86 | + DeviceId dstDevice = dstEdge != NOT_HOST ? dstEdge.src().deviceId() : (DeviceId) dst; | ||
110 | 87 | ||
111 | // If the source and destination are on the same edge device, there | 88 | // If the source and destination are on the same edge device, there |
112 | // is just one path, so build it and return it. | 89 | // is just one path, so build it and return it. |
113 | - if (srcEdge.dst().deviceId().equals(dstEdge.src().deviceId())) { | 90 | + if (srcDevice.equals(dstDevice)) { |
114 | return edgeToEdgePaths(srcEdge, dstEdge); | 91 | return edgeToEdgePaths(srcEdge, dstEdge); |
115 | } | 92 | } |
116 | 93 | ||
... | @@ -118,26 +95,47 @@ public class PathManager implements PathService { | ... | @@ -118,26 +95,47 @@ public class PathManager implements PathService { |
118 | // devices. | 95 | // devices. |
119 | Topology topology = topologyService.currentTopology(); | 96 | Topology topology = topologyService.currentTopology(); |
120 | Set<Path> paths = weight == null ? | 97 | Set<Path> paths = weight == null ? |
121 | - topologyService.getPaths(topology, srcEdge.dst().deviceId(), | 98 | + topologyService.getPaths(topology, srcDevice, dstDevice) : |
122 | - dstEdge.src().deviceId()) : | 99 | + topologyService.getPaths(topology, srcDevice, dstDevice, weight); |
123 | - topologyService.getPaths(topology, srcEdge.dst().deviceId(), | ||
124 | - dstEdge.src().deviceId(), weight); | ||
125 | 100 | ||
126 | return edgeToEdgePaths(srcEdge, dstEdge, paths); | 101 | return edgeToEdgePaths(srcEdge, dstEdge, paths); |
127 | } | 102 | } |
128 | 103 | ||
104 | + // Finds the host edge link if the element ID is a host id of an existing | ||
105 | + // host. Otherwise, if the host does not exist, it returns null and if | ||
106 | + // the element ID is not a host ID, returns NOT_HOST edge link. | ||
107 | + private EdgeLink getEdgeLink(ElementId elementId, boolean isIngress) { | ||
108 | + if (elementId instanceof HostId) { | ||
109 | + // Resolve the host, return null. | ||
110 | + Host host = hostService.getHost((HostId) elementId); | ||
111 | + if (host == null) { | ||
112 | + return null; | ||
113 | + } | ||
114 | + return new DefaultEdgeLink(PID, new ConnectPoint(elementId, P0), | ||
115 | + host.location(), isIngress); | ||
116 | + } | ||
117 | + return NOT_HOST; | ||
118 | + } | ||
119 | + | ||
129 | // Produces a set of direct edge-to-edge paths. | 120 | // Produces a set of direct edge-to-edge paths. |
130 | private Set<Path> edgeToEdgePaths(EdgeLink srcLink, EdgeLink dstLink) { | 121 | private Set<Path> edgeToEdgePaths(EdgeLink srcLink, EdgeLink dstLink) { |
131 | Set<Path> endToEndPaths = Sets.newHashSetWithExpectedSize(1); | 122 | Set<Path> endToEndPaths = Sets.newHashSetWithExpectedSize(1); |
132 | - endToEndPaths.add(edgeToEdgePath(srcLink, dstLink)); | 123 | + if (srcLink != NOT_HOST || dstLink != NOT_HOST) { |
124 | + endToEndPaths.add(edgeToEdgePath(srcLink, dstLink)); | ||
125 | + } | ||
133 | return endToEndPaths; | 126 | return endToEndPaths; |
134 | } | 127 | } |
135 | 128 | ||
136 | // Produces a direct edge-to-edge path. | 129 | // Produces a direct edge-to-edge path. |
137 | private Path edgeToEdgePath(EdgeLink srcLink, EdgeLink dstLink) { | 130 | private Path edgeToEdgePath(EdgeLink srcLink, EdgeLink dstLink) { |
138 | List<Link> links = Lists.newArrayListWithCapacity(2); | 131 | List<Link> links = Lists.newArrayListWithCapacity(2); |
139 | - links.add(srcLink); | 132 | + // Add source and destination edge links only if they are real. |
140 | - links.add(dstLink); | 133 | + if (srcLink != NOT_HOST) { |
134 | + links.add(srcLink); | ||
135 | + } | ||
136 | + if (dstLink != NOT_HOST) { | ||
137 | + links.add(dstLink); | ||
138 | + } | ||
141 | return new DefaultPath(PID, links, 2); | 139 | return new DefaultPath(PID, links, 2); |
142 | } | 140 | } |
143 | 141 | ||
... | @@ -161,4 +159,12 @@ public class PathManager implements PathService { | ... | @@ -161,4 +159,12 @@ public class PathManager implements PathService { |
161 | return new DefaultPath(path.providerId(), links, path.cost() + 2); | 159 | return new DefaultPath(path.providerId(), links, path.cost() + 2); |
162 | } | 160 | } |
163 | 161 | ||
162 | + // Special value for edge link to represent that this is really not an | ||
163 | + // edge link since the src or dst are really an infrastructure device. | ||
164 | + private static class NotHost extends DefaultEdgeLink implements EdgeLink { | ||
165 | + NotHost() { | ||
166 | + super(PID, new ConnectPoint(HostId.hostId("nic:none"), P0), | ||
167 | + new HostLocation(deviceId("none:none"), P0, 0L), false); | ||
168 | + } | ||
169 | + } | ||
164 | } | 170 | } | ... | ... |
-
Please register or login to post a comment