tom

Enhanced topo viewer sample GUI to allow path selection from any node (host or d…

…evice). Fixed path service implementaiton.
...@@ -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 }
......