Added javadocs and separated trivial implementations into distinct packages.
Showing
23 changed files
with
128 additions
and
30 deletions
1 | -package org.onlab.onos.net.trivial.impl; | 1 | +package org.onlab.onos.net.trivial.device.impl; |
2 | 2 | ||
3 | import org.apache.felix.scr.annotations.Activate; | 3 | import org.apache.felix.scr.annotations.Activate; |
4 | import org.apache.felix.scr.annotations.Component; | 4 | import org.apache.felix.scr.annotations.Component; | ... | ... |
1 | -package org.onlab.onos.net.trivial.impl; | 1 | +package org.onlab.onos.net.trivial.link.impl; |
2 | 2 | ||
3 | import static com.google.common.base.Preconditions.checkNotNull; | 3 | import static com.google.common.base.Preconditions.checkNotNull; |
4 | import static org.slf4j.LoggerFactory.getLogger; | 4 | import static org.slf4j.LoggerFactory.getLogger; | ... | ... |
1 | -package org.onlab.onos.net.trivial.impl; | 1 | +package org.onlab.onos.net.trivial.topology.impl; |
2 | 2 | ||
3 | import org.apache.felix.scr.annotations.Activate; | 3 | import org.apache.felix.scr.annotations.Activate; |
4 | import org.apache.felix.scr.annotations.Component; | 4 | import org.apache.felix.scr.annotations.Component; | ... | ... |
1 | -package org.onlab.onos.net.trivial.impl; | 1 | +package org.onlab.onos.net.trivial.topology.provider.impl; |
2 | 2 | ||
3 | import com.google.common.collect.ImmutableSet; | 3 | import com.google.common.collect.ImmutableSet; |
4 | import com.google.common.collect.Maps; | 4 | import com.google.common.collect.Maps; |
5 | +import com.google.common.collect.Multimap; | ||
5 | import com.google.common.collect.Sets; | 6 | import com.google.common.collect.Sets; |
6 | import org.onlab.graph.AdjacencyListsGraph; | 7 | import org.onlab.graph.AdjacencyListsGraph; |
7 | import org.onlab.graph.DijkstraGraphSearch; | 8 | import org.onlab.graph.DijkstraGraphSearch; |
8 | import org.onlab.graph.Graph; | 9 | import org.onlab.graph.Graph; |
9 | import org.onlab.graph.GraphPathSearch; | 10 | import org.onlab.graph.GraphPathSearch; |
11 | +import org.onlab.graph.TarjanGraphSearch; | ||
10 | import org.onlab.onos.net.ConnectPoint; | 12 | import org.onlab.onos.net.ConnectPoint; |
11 | import org.onlab.onos.net.Device; | 13 | import org.onlab.onos.net.Device; |
12 | import org.onlab.onos.net.DeviceId; | 14 | import org.onlab.onos.net.DeviceId; |
13 | import org.onlab.onos.net.Link; | 15 | import org.onlab.onos.net.Link; |
14 | import org.onlab.onos.net.topology.ClusterId; | 16 | import org.onlab.onos.net.topology.ClusterId; |
17 | +import org.onlab.onos.net.topology.DefaultTopologyCluster; | ||
15 | import org.onlab.onos.net.topology.LinkWeight; | 18 | import org.onlab.onos.net.topology.LinkWeight; |
16 | import org.onlab.onos.net.topology.TopoEdge; | 19 | import org.onlab.onos.net.topology.TopoEdge; |
17 | import org.onlab.onos.net.topology.TopoVertex; | 20 | import org.onlab.onos.net.topology.TopoVertex; |
18 | import org.onlab.onos.net.topology.TopologyCluster; | 21 | import org.onlab.onos.net.topology.TopologyCluster; |
19 | import org.onlab.onos.net.topology.TopologyDescription; | 22 | import org.onlab.onos.net.topology.TopologyDescription; |
20 | 23 | ||
24 | +import java.util.HashSet; | ||
25 | +import java.util.List; | ||
21 | import java.util.Map; | 26 | import java.util.Map; |
22 | import java.util.Objects; | 27 | import java.util.Objects; |
23 | import java.util.Set; | 28 | import java.util.Set; |
24 | 29 | ||
25 | import static com.google.common.base.MoreObjects.toStringHelper; | 30 | import static com.google.common.base.MoreObjects.toStringHelper; |
26 | import static org.onlab.graph.GraphPathSearch.Result; | 31 | import static org.onlab.graph.GraphPathSearch.Result; |
32 | +import static org.onlab.graph.TarjanGraphSearch.SCCResult; | ||
27 | import static org.onlab.onos.net.Link.Type.INDIRECT; | 33 | import static org.onlab.onos.net.Link.Type.INDIRECT; |
28 | 34 | ||
29 | /** | 35 | /** |
... | @@ -33,25 +39,32 @@ class DefaultTopologyDescription implements TopologyDescription { | ... | @@ -33,25 +39,32 @@ class DefaultTopologyDescription implements TopologyDescription { |
33 | 39 | ||
34 | private static final GraphPathSearch<TopoVertex, TopoEdge> DIJKSTRA = | 40 | private static final GraphPathSearch<TopoVertex, TopoEdge> DIJKSTRA = |
35 | new DijkstraGraphSearch<>(); | 41 | new DijkstraGraphSearch<>(); |
42 | + private static final TarjanGraphSearch<TopoVertex, TopoEdge> TARJAN = | ||
43 | + new TarjanGraphSearch<>(); | ||
36 | 44 | ||
37 | private final long nanos; | 45 | private final long nanos; |
38 | private final Map<DeviceId, TopoVertex> vertexesById = Maps.newHashMap(); | 46 | private final Map<DeviceId, TopoVertex> vertexesById = Maps.newHashMap(); |
39 | private final Graph<TopoVertex, TopoEdge> graph; | 47 | private final Graph<TopoVertex, TopoEdge> graph; |
40 | private final Map<DeviceId, Result<TopoVertex, TopoEdge>> results; | 48 | private final Map<DeviceId, Result<TopoVertex, TopoEdge>> results; |
41 | private final Map<ClusterId, TopologyCluster> clusters; | 49 | private final Map<ClusterId, TopologyCluster> clusters; |
42 | -// private final Multimap<ClusterId, DeviceId> clusterDevices; | ||
43 | -// private final Multimap<ClusterId, Link> clusterLinks; | ||
44 | -// private final Map<DeviceId, TopologyCluster> deviceClusters; | ||
45 | - | ||
46 | 50 | ||
51 | + // Secondary look-up indexes | ||
52 | + private Multimap<ClusterId, DeviceId> devicesByCluster; | ||
53 | + private Multimap<ClusterId, Link> linksByCluster; | ||
54 | + private Map<DeviceId, TopologyCluster> clustersByDevice; | ||
55 | + | ||
56 | + /** | ||
57 | + * Creates a topology description to carry topology vitals to the core. | ||
58 | + * | ||
59 | + * @param nanos time in nanos of when the topology description was created | ||
60 | + * @param devices collection of devices | ||
61 | + * @param links | ||
62 | + */ | ||
47 | DefaultTopologyDescription(long nanos, Iterable<Device> devices, Iterable<Link> links) { | 63 | DefaultTopologyDescription(long nanos, Iterable<Device> devices, Iterable<Link> links) { |
48 | this.nanos = nanos; | 64 | this.nanos = nanos; |
49 | this.graph = buildGraph(devices, links); | 65 | this.graph = buildGraph(devices, links); |
50 | this.results = computeDefaultPaths(); | 66 | this.results = computeDefaultPaths(); |
51 | this.clusters = computeClusters(); | 67 | this.clusters = computeClusters(); |
52 | -// this.clusterDevices = clusterDevices; | ||
53 | -// this.clusterLinks = clusterLinks; | ||
54 | -// this.deviceClusters = deviceClusters; | ||
55 | } | 68 | } |
56 | 69 | ||
57 | // Constructs the topology graph using the supplied devices and links. | 70 | // Constructs the topology graph using the supplied devices and links. |
... | @@ -99,9 +112,62 @@ class DefaultTopologyDescription implements TopologyDescription { | ... | @@ -99,9 +112,62 @@ class DefaultTopologyDescription implements TopologyDescription { |
99 | // Computes topology SCC clusters using Tarjan algorithm. | 112 | // Computes topology SCC clusters using Tarjan algorithm. |
100 | private Map<ClusterId, TopologyCluster> computeClusters() { | 113 | private Map<ClusterId, TopologyCluster> computeClusters() { |
101 | Map<ClusterId, TopologyCluster> clusters = Maps.newHashMap(); | 114 | Map<ClusterId, TopologyCluster> clusters = Maps.newHashMap(); |
115 | + SCCResult<TopoVertex, TopoEdge> result = TARJAN.search(graph, new NoIndirectLinksWeight()); | ||
116 | + | ||
117 | + // Extract both vertexes and edges from the results; the lists form | ||
118 | + // pairs along the same index. | ||
119 | + List<Set<TopoVertex>> clusterVertexes = result.clusterVertexes(); | ||
120 | + List<Set<TopoEdge>> clusterEdges = result.clusterEdges(); | ||
121 | + | ||
122 | + // Scan over the lists and create a cluster from the results. | ||
123 | + for (int i = 0, n = result.clusterCount(); i < n; i++) { | ||
124 | + Set<TopoVertex> vertexSet = clusterVertexes.get(i); | ||
125 | + Set<TopoEdge> edgeSet = clusterEdges.get(i); | ||
126 | + | ||
127 | + DefaultTopologyCluster cluster = | ||
128 | + new DefaultTopologyCluster(ClusterId.clusterId(i), | ||
129 | + vertexSet.size(), edgeSet.size(), | ||
130 | + findRoot(vertexSet).deviceId()); | ||
131 | + | ||
132 | + findClusterDevices(vertexSet, cluster); | ||
133 | + findClusterLinks(edgeSet, cluster); | ||
134 | + } | ||
102 | return clusters; | 135 | return clusters; |
103 | } | 136 | } |
104 | 137 | ||
138 | + // Scan through the set of cluster vertices and convert it to a set of | ||
139 | + // device ids; register the cluster by device id as well. | ||
140 | + private void findClusterDevices(Set<TopoVertex> vertexSet, | ||
141 | + DefaultTopologyCluster cluster) { | ||
142 | + Set<DeviceId> ids = new HashSet<>(vertexSet.size()); | ||
143 | + for (TopoVertex v : vertexSet) { | ||
144 | + DeviceId deviceId = v.deviceId(); | ||
145 | + devicesByCluster.put(cluster.id(), deviceId); | ||
146 | + clustersByDevice.put(deviceId, cluster); | ||
147 | + } | ||
148 | + } | ||
149 | + | ||
150 | + private void findClusterLinks(Set<TopoEdge> edgeSet, | ||
151 | + DefaultTopologyCluster cluster) { | ||
152 | + for (TopoEdge e : edgeSet) { | ||
153 | + linksByCluster.put(cluster.id(), e.link()); | ||
154 | + } | ||
155 | + } | ||
156 | + | ||
157 | + // Finds the vertex whose device id is the lexicographical minimum in the | ||
158 | + // specified set. | ||
159 | + private TopoVertex findRoot(Set<TopoVertex> vertexSet) { | ||
160 | + TopoVertex minVertex = null; | ||
161 | + for (TopoVertex vertex : vertexSet) { | ||
162 | + if (minVertex == null || | ||
163 | + minVertex.deviceId().toString() | ||
164 | + .compareTo(minVertex.deviceId().toString()) < 0) { | ||
165 | + minVertex = vertex; | ||
166 | + } | ||
167 | + } | ||
168 | + return minVertex; | ||
169 | + } | ||
170 | + | ||
105 | // Fetches a vertex corresponding to the given connection point device. | 171 | // Fetches a vertex corresponding to the given connection point device. |
106 | private TopoVertex vertexOf(ConnectPoint connectPoint) { | 172 | private TopoVertex vertexOf(ConnectPoint connectPoint) { |
107 | DeviceId id = connectPoint.deviceId(); | 173 | DeviceId id = connectPoint.deviceId(); |
... | @@ -232,7 +298,7 @@ class DefaultTopologyDescription implements TopologyDescription { | ... | @@ -232,7 +298,7 @@ class DefaultTopologyDescription implements TopologyDescription { |
232 | 298 | ||
233 | // Link weight for measuring link cost as hop count with indirect links | 299 | // Link weight for measuring link cost as hop count with indirect links |
234 | // being as expensive as traversing the entire graph to assume the worst. | 300 | // being as expensive as traversing the entire graph to assume the worst. |
235 | - private class HopCountLinkWeight implements LinkWeight { | 301 | + private static class HopCountLinkWeight implements LinkWeight { |
236 | private final int indirectLinkCost; | 302 | private final int indirectLinkCost; |
237 | 303 | ||
238 | public HopCountLinkWeight(int indirectLinkCost) { | 304 | public HopCountLinkWeight(int indirectLinkCost) { |
... | @@ -247,4 +313,12 @@ class DefaultTopologyDescription implements TopologyDescription { | ... | @@ -247,4 +313,12 @@ class DefaultTopologyDescription implements TopologyDescription { |
247 | } | 313 | } |
248 | } | 314 | } |
249 | 315 | ||
316 | + // Link weight for preventing traversal over indirect links. | ||
317 | + private static class NoIndirectLinksWeight implements LinkWeight { | ||
318 | + @Override | ||
319 | + public double weight(TopoEdge edge) { | ||
320 | + return edge.link().type() == INDIRECT ? -1 : 1; | ||
321 | + } | ||
322 | + } | ||
323 | + | ||
250 | } | 324 | } | ... | ... |
1 | -package org.onlab.onos.net.trivial.impl; | 1 | +package org.onlab.onos.net.trivial.topology.provider.impl; |
2 | 2 | ||
3 | import org.apache.felix.scr.annotations.Activate; | 3 | import org.apache.felix.scr.annotations.Activate; |
4 | import org.apache.felix.scr.annotations.Component; | 4 | import org.apache.felix.scr.annotations.Component; | ... | ... |
1 | -package org.onlab.onos.net.trivial.impl; | 1 | +package org.onlab.onos.net.trivial.device.impl; |
2 | 2 | ||
3 | import org.junit.After; | 3 | import org.junit.After; |
4 | import org.junit.Before; | 4 | import org.junit.Before; |
... | @@ -22,6 +22,7 @@ import org.onlab.onos.net.device.DeviceService; | ... | @@ -22,6 +22,7 @@ import org.onlab.onos.net.device.DeviceService; |
22 | import org.onlab.onos.net.device.PortDescription; | 22 | import org.onlab.onos.net.device.PortDescription; |
23 | import org.onlab.onos.net.provider.AbstractProvider; | 23 | import org.onlab.onos.net.provider.AbstractProvider; |
24 | import org.onlab.onos.net.provider.ProviderId; | 24 | import org.onlab.onos.net.provider.ProviderId; |
25 | +import org.onlab.onos.event.impl.TestEventDispatcher; | ||
25 | 26 | ||
26 | import java.util.ArrayList; | 27 | import java.util.ArrayList; |
27 | import java.util.Iterator; | 28 | import java.util.Iterator; | ... | ... |
1 | -package org.onlab.onos.net.trivial.impl; | 1 | +package org.onlab.onos.net.trivial.link.impl; |
2 | 2 | ||
3 | import com.google.common.collect.ImmutableSet; | 3 | import com.google.common.collect.ImmutableSet; |
4 | import org.junit.After; | 4 | import org.junit.After; |
... | @@ -21,6 +21,7 @@ import org.onlab.onos.net.link.LinkProviderService; | ... | @@ -21,6 +21,7 @@ import org.onlab.onos.net.link.LinkProviderService; |
21 | import org.onlab.onos.net.link.LinkService; | 21 | import org.onlab.onos.net.link.LinkService; |
22 | import org.onlab.onos.net.provider.AbstractProvider; | 22 | import org.onlab.onos.net.provider.AbstractProvider; |
23 | import org.onlab.onos.net.provider.ProviderId; | 23 | import org.onlab.onos.net.provider.ProviderId; |
24 | +import org.onlab.onos.event.impl.TestEventDispatcher; | ||
24 | 25 | ||
25 | import java.util.ArrayList; | 26 | import java.util.ArrayList; |
26 | import java.util.Iterator; | 27 | import java.util.Iterator; | ... | ... |
... | @@ -332,7 +332,7 @@ | ... | @@ -332,7 +332,7 @@ |
332 | <group> | 332 | <group> |
333 | <title>Core Subsystems</title> | 333 | <title>Core Subsystems</title> |
334 | <packages> | 334 | <packages> |
335 | - org.onlab.onos.net.trivial.impl:org.onlab.onos.net.*.impl:org.onlab.onos.impl:org.onlab.onos.event.impl | 335 | + org.onlab.onos.net.trivial.*:org.onlab.onos.net.*.impl:org.onlab.onos.impl:org.onlab.onos.event.impl |
336 | </packages> | 336 | </packages> |
337 | </group> | 337 | </group> |
338 | <group> | 338 | <group> | ... | ... |
... | @@ -42,7 +42,7 @@ import org.onlab.onos.of.controller.OpenFlowSwitch; | ... | @@ -42,7 +42,7 @@ import org.onlab.onos.of.controller.OpenFlowSwitch; |
42 | import org.onlab.packet.Ethernet; | 42 | import org.onlab.packet.Ethernet; |
43 | import org.onlab.packet.ONLabLddp; | 43 | import org.onlab.packet.ONLabLddp; |
44 | import org.onlab.packet.ONLabLddp.DPIDandPort; | 44 | import org.onlab.packet.ONLabLddp.DPIDandPort; |
45 | -import org.onlab.timer.Timer; | 45 | +import org.onlab.util.Timer; |
46 | import org.projectfloodlight.openflow.protocol.OFFactory; | 46 | import org.projectfloodlight.openflow.protocol.OFFactory; |
47 | import org.projectfloodlight.openflow.protocol.OFMessage; | 47 | import org.projectfloodlight.openflow.protocol.OFMessage; |
48 | import org.projectfloodlight.openflow.protocol.OFPacketOut; | 48 | import org.projectfloodlight.openflow.protocol.OFPacketOut; | ... | ... |
... | @@ -23,7 +23,7 @@ import org.onlab.onos.of.controller.OpenFlowController; | ... | @@ -23,7 +23,7 @@ import org.onlab.onos.of.controller.OpenFlowController; |
23 | import org.onlab.onos.of.controller.OpenFlowSwitchListener; | 23 | import org.onlab.onos.of.controller.OpenFlowSwitchListener; |
24 | import org.onlab.onos.of.controller.PacketContext; | 24 | import org.onlab.onos.of.controller.PacketContext; |
25 | import org.onlab.onos.of.controller.PacketListener; | 25 | import org.onlab.onos.of.controller.PacketListener; |
26 | -import org.onlab.timer.Timer; | 26 | +import org.onlab.util.Timer; |
27 | import org.projectfloodlight.openflow.protocol.OFPortConfig; | 27 | import org.projectfloodlight.openflow.protocol.OFPortConfig; |
28 | import org.projectfloodlight.openflow.protocol.OFPortDesc; | 28 | import org.projectfloodlight.openflow.protocol.OFPortDesc; |
29 | import org.projectfloodlight.openflow.protocol.OFPortState; | 29 | import org.projectfloodlight.openflow.protocol.OFPortState; | ... | ... |
1 | -package org.onlab.timer; | 1 | +package org.onlab.util; |
2 | 2 | ||
3 | import org.jboss.netty.util.HashedWheelTimer; | 3 | import org.jboss.netty.util.HashedWheelTimer; |
4 | 4 | ||
5 | - | 5 | +/** |
6 | + * Hashed-wheel timer singleton. Care must be taken to shutdown the timer | ||
7 | + * only when the VM is ready to exit. | ||
8 | + */ | ||
6 | public final class Timer { | 9 | public final class Timer { |
7 | 10 | ||
8 | - private Timer() {} | ||
9 | - | ||
10 | private static HashedWheelTimer timer; | 11 | private static HashedWheelTimer timer; |
11 | 12 | ||
13 | + // Ban public construction | ||
14 | + private Timer() { | ||
15 | + } | ||
16 | + | ||
17 | + /** | ||
18 | + * Returns the singleton hashed-wheel timer. | ||
19 | + * | ||
20 | + * @return hashed-wheel timer | ||
21 | + */ | ||
12 | public static HashedWheelTimer getTimer() { | 22 | public static HashedWheelTimer getTimer() { |
13 | if (Timer.timer == null) { | 23 | if (Timer.timer == null) { |
14 | Timer.timer = new HashedWheelTimer(); | 24 | Timer.timer = new HashedWheelTimer(); | ... | ... |
-
Please register or login to post a comment