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