tom

Re-assembled the topology subsystem.

Showing 23 changed files with 341 additions and 370 deletions
...@@ -16,7 +16,7 @@ public class DefaultLink extends AbstractModel implements Link { ...@@ -16,7 +16,7 @@ public class DefaultLink extends AbstractModel implements Link {
16 private final Type type; 16 private final Type type;
17 17
18 /** 18 /**
19 - * Creates a link description using the supplied information. 19 + * Creates an infrastructure link using the supplied information.
20 * 20 *
21 * @param providerId provider identity 21 * @param providerId provider identity
22 * @param src link source 22 * @param src link source
......
1 +package org.onlab.onos.net;
2 +
3 +import com.google.common.collect.ImmutableList;
4 +import org.onlab.onos.net.provider.ProviderId;
5 +
6 +import java.util.List;
7 +import java.util.Objects;
8 +
9 +import static com.google.common.base.Preconditions.checkArgument;
10 +import static com.google.common.base.Preconditions.checkNotNull;
11 +
12 +/**
13 + * Default implementation of a network path.
14 + */
15 +public class DefaultPath extends DefaultLink implements Path {
16 +
17 + private final List<Link> links;
18 + private final double cost;
19 +
20 + /**
21 + * Creates a path from the specified source and destination using the
22 + * supplied list of links.
23 + *
24 + * @param providerId provider identity
25 + * @param links contiguous links that comprise the path
26 + * @param cost unit-less path cost
27 + */
28 + public DefaultPath(ProviderId providerId, List<Link> links, double cost) {
29 + super(providerId, source(links), destination(links), Type.INDIRECT);
30 + this.links = ImmutableList.copyOf(links);
31 + this.cost = cost;
32 + }
33 +
34 + @Override
35 + public List<Link> links() {
36 + return links;
37 + }
38 +
39 + @Override
40 + public double cost() {
41 + return cost;
42 + }
43 +
44 + // Returns the source of the first link.
45 + private static ConnectPoint source(List<Link> links) {
46 + checkNotNull(links, "List of path links cannot be null");
47 + checkArgument(!links.isEmpty(), "List of path links cannot be empty");
48 + return links.get(0).src();
49 + }
50 +
51 + // Returns the destination of the last link.
52 + private static ConnectPoint destination(List<Link> links) {
53 + checkNotNull(links, "List of path links cannot be null");
54 + checkArgument(!links.isEmpty(), "List of path links cannot be empty");
55 + return links.get(links.size() - 1).dst();
56 + }
57 +
58 + @Override
59 + public int hashCode() {
60 + return 31 * super.hashCode() + Objects.hash(links);
61 + }
62 +
63 + @Override
64 + public boolean equals(Object obj) {
65 + if (obj instanceof DefaultPath) {
66 + final DefaultPath other = (DefaultPath) obj;
67 + return Objects.equals(this.links, other.links);
68 + }
69 + return false;
70 + }
71 +}
...@@ -17,4 +17,11 @@ public interface Path extends Link { ...@@ -17,4 +17,11 @@ public interface Path extends Link {
17 */ 17 */
18 List<Link> links(); 18 List<Link> links();
19 19
20 + /**
21 + * Returns the path cost as a unit-less value.
22 + *
23 + * @return unit-less path cost
24 + */
25 + double cost();
26 +
20 } 27 }
......
...@@ -27,6 +27,15 @@ public final class ClusterId { ...@@ -27,6 +27,15 @@ public final class ClusterId {
27 return new ClusterId(id); 27 return new ClusterId(id);
28 } 28 }
29 29
30 + /**
31 + * Returns the backing integer index.
32 + *
33 + * @return backing integer index
34 + */
35 + public int index() {
36 + return id;
37 + }
38 +
30 @Override 39 @Override
31 public int hashCode() { 40 public int hashCode() {
32 return Objects.hash(id); 41 return Objects.hash(id);
......
1 +package org.onlab.onos.net.topology;
2 +
3 +import com.google.common.collect.ImmutableSet;
4 +import org.onlab.onos.net.Description;
5 +
6 +/**
7 + * Describes attribute(s) of a network graph.
8 + */
9 +public interface GraphDescription extends Description {
10 +
11 + /**
12 + * Returns the creation timestamp of the graph description. This is
13 + * expressed in system nanos to allow proper sequencing.
14 + *
15 + * @return graph description creation timestamp
16 + */
17 + long timestamp();
18 +
19 + /**
20 + * Returns the set of topology graph vertexes.
21 + *
22 + * @return set of graph vertexes
23 + */
24 + ImmutableSet<TopologyVertex> vertexes();
25 +
26 + /**
27 + * Returns the set of topology graph edges.
28 + *
29 + * @return set of graph edges
30 + */
31 + ImmutableSet<TopologyEdge> edges();
32 +
33 +}
34 +
...@@ -6,5 +6,5 @@ import org.onlab.graph.EdgeWeight; ...@@ -6,5 +6,5 @@ import org.onlab.graph.EdgeWeight;
6 * Entity capable of determining cost or weight of a specified topology 6 * Entity capable of determining cost or weight of a specified topology
7 * graph edge. 7 * graph edge.
8 */ 8 */
9 -public interface LinkWeight extends EdgeWeight<TopoVertex, TopoEdge> { 9 +public interface LinkWeight extends EdgeWeight<TopologyVertex, TopologyEdge> {
10 } 10 }
......
1 -package org.onlab.onos.net.topology;
2 -
3 -import com.google.common.collect.ImmutableMap;
4 -import com.google.common.collect.ImmutableSet;
5 -import com.google.common.collect.ImmutableSetMultimap;
6 -import org.onlab.graph.Graph;
7 -import org.onlab.onos.net.Description;
8 -import org.onlab.onos.net.DeviceId;
9 -import org.onlab.onos.net.Link;
10 -
11 -import static org.onlab.graph.GraphPathSearch.Result;
12 -
13 -/**
14 - * Describes attribute(s) of a network topology.
15 - */
16 -public interface TopologyDescription extends Description {
17 -
18 - /**
19 - * Returns the creation timestamp of the topology description. This is
20 - * expressed in system nanos to allow proper sequencing.
21 - *
22 - * @return topology description creation timestamp
23 - */
24 - long timestamp();
25 -
26 - /**
27 - * Returns the topology graph in immutable form.
28 - *
29 - * @return network graph
30 - */
31 - Graph<TopoVertex, TopoEdge> graph();
32 -
33 - /**
34 - * Returns an immutable map of path search results for each source device.
35 - *
36 - * @return map of path search result for each source node
37 - */
38 - ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> pathsBySource();
39 -
40 - /**
41 - * Returns the set of topology SCC clusters.
42 - *
43 - * @return set of SCC clusters
44 - */
45 - ImmutableSet<TopologyCluster> clusters();
46 -
47 - /**
48 - * Returns an immutable set multi-map of devices for each cluster.
49 - *
50 - * @return set multi-map of devices that belong to each cluster
51 - */
52 - ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster();
53 -
54 - /**
55 - * Returns an immutable set multi-map of links for each cluster.
56 - *
57 - * @return set multi-map of links that belong to each cluster
58 - */
59 - ImmutableSetMultimap<TopologyCluster, Link> linksByCluster();
60 -
61 -}
62 -
...@@ -6,7 +6,7 @@ import org.onlab.onos.net.Link; ...@@ -6,7 +6,7 @@ import org.onlab.onos.net.Link;
6 /** 6 /**
7 * Represents an edge in the topology graph. 7 * Represents an edge in the topology graph.
8 */ 8 */
9 -public interface TopoEdge extends Edge<TopoVertex> { 9 +public interface TopologyEdge extends Edge<TopologyVertex> {
10 10
11 /** 11 /**
12 * Returns the associated infrastructure link. 12 * Returns the associated infrastructure link.
......
1 +package org.onlab.onos.net.topology;
2 +
3 +import org.onlab.graph.Graph;
4 +
5 +/**
6 + * Represents an immutable topology graph.
7 + */
8 +public interface TopologyGraph extends Graph<TopologyVertex, TopologyEdge> {
9 +
10 +}
...@@ -10,16 +10,13 @@ import java.util.List; ...@@ -10,16 +10,13 @@ import java.util.List;
10 */ 10 */
11 public interface TopologyProviderService extends ProviderService<TopologyProvider> { 11 public interface TopologyProviderService extends ProviderService<TopologyProvider> {
12 12
13 - // What can be conveyed in a topology that isn't by individual
14 - // providers?
15 -
16 /** 13 /**
17 * Signals the core that some aspect of the topology has changed. 14 * Signals the core that some aspect of the topology has changed.
18 * 15 *
19 - * @param topoDescription information about topology 16 + * @param graphDescription information about the network graph
20 - * @param reasons events that triggered topology change 17 + * @param reasons events that triggered topology change
21 */ 18 */
22 - void topologyChanged(TopologyDescription topoDescription, 19 + void topologyChanged(GraphDescription graphDescription,
23 List<Event> reasons); 20 List<Event> reasons);
24 21
25 } 22 }
......
1 package org.onlab.onos.net.topology; 1 package org.onlab.onos.net.topology;
2 2
3 -import org.onlab.graph.Graph;
4 import org.onlab.onos.net.ConnectPoint; 3 import org.onlab.onos.net.ConnectPoint;
5 import org.onlab.onos.net.DeviceId; 4 import org.onlab.onos.net.DeviceId;
6 import org.onlab.onos.net.Path; 5 import org.onlab.onos.net.Path;
...@@ -41,7 +40,7 @@ public interface TopologyService { ...@@ -41,7 +40,7 @@ public interface TopologyService {
41 * @param topology topology descriptor 40 * @param topology topology descriptor
42 * @return topology graph view 41 * @return topology graph view
43 */ 42 */
44 - Graph<TopoVertex, TopoEdge> getGraph(Topology topology); 43 + TopologyGraph getGraph(Topology topology);
45 44
46 /** 45 /**
47 * Returns the set of all shortest paths, precomputed in terms of hop-count, 46 * Returns the set of all shortest paths, precomputed in terms of hop-count,
......
...@@ -6,7 +6,7 @@ import org.onlab.onos.net.DeviceId; ...@@ -6,7 +6,7 @@ import org.onlab.onos.net.DeviceId;
6 /** 6 /**
7 * Represents a vertex in the topology graph. 7 * Represents a vertex in the topology graph.
8 */ 8 */
9 -public interface TopoVertex extends Vertex { 9 +public interface TopologyVertex extends Vertex {
10 10
11 /** 11 /**
12 * Returns the associated infrastructure device identification. 12 * Returns the associated infrastructure device identification.
......
1 +package org.onlab.onos.net.trivial.topology.impl;
2 +
3 +import com.google.common.collect.ImmutableSet;
4 +import com.google.common.collect.Maps;
5 +import org.onlab.onos.net.ConnectPoint;
6 +import org.onlab.onos.net.Device;
7 +import org.onlab.onos.net.DeviceId;
8 +import org.onlab.onos.net.Link;
9 +import org.onlab.onos.net.topology.GraphDescription;
10 +import org.onlab.onos.net.topology.TopologyEdge;
11 +import org.onlab.onos.net.topology.TopologyVertex;
12 +
13 +import java.util.Map;
14 +
15 +/**
16 + * Default implementation of an immutable topology graph data carrier.
17 + */
18 +class DefaultGraphDescription implements GraphDescription {
19 +
20 + private final long nanos;
21 + private final ImmutableSet<TopologyVertex> vertexes;
22 + private final ImmutableSet<TopologyEdge> edges;
23 +
24 + private final Map<DeviceId, TopologyVertex> vertexesById = Maps.newHashMap();
25 +
26 +
27 + /**
28 + * Creates a minimal topology graph description to allow core to construct
29 + * and process the topology graph.
30 + *
31 + * @param nanos time in nanos of when the topology description was created
32 + * @param devices collection of infrastructure devices
33 + * @param links collection of infrastructure links
34 + */
35 + DefaultGraphDescription(long nanos, Iterable<Device> devices, Iterable<Link> links) {
36 + this.nanos = nanos;
37 + this.vertexes = buildVertexes(devices);
38 + this.edges = buildEdges(links);
39 + vertexesById.clear();
40 + }
41 +
42 + @Override
43 + public long timestamp() {
44 + return nanos;
45 + }
46 +
47 + @Override
48 + public ImmutableSet<TopologyVertex> vertexes() {
49 + return vertexes;
50 + }
51 +
52 + @Override
53 + public ImmutableSet<TopologyEdge> edges() {
54 + return edges;
55 + }
56 +
57 + // Builds a set of topology vertexes from the specified list of devices
58 + private ImmutableSet<TopologyVertex> buildVertexes(Iterable<Device> devices) {
59 + ImmutableSet.Builder<TopologyVertex> vertexes = ImmutableSet.builder();
60 + for (Device device : devices) {
61 + TopologyVertex vertex = new DefaultTopologyVertex(device.id());
62 + vertexes.add(vertex);
63 + vertexesById.put(vertex.deviceId(), vertex);
64 + }
65 + return vertexes.build();
66 + }
67 +
68 + // Builds a set of topology vertexes from the specified list of links
69 + private ImmutableSet<TopologyEdge> buildEdges(Iterable<Link> links) {
70 + ImmutableSet.Builder<TopologyEdge> edges = ImmutableSet.builder();
71 + for (Link link : links) {
72 + edges.add(new DefaultTopologyEdge(vertexOf(link.src()),
73 + vertexOf(link.dst()), link));
74 + }
75 + return edges.build();
76 + }
77 +
78 + // Fetches a vertex corresponding to the given connection point device.
79 + private TopologyVertex vertexOf(ConnectPoint connectPoint) {
80 + DeviceId id = connectPoint.deviceId();
81 + TopologyVertex vertex = vertexesById.get(id);
82 + if (vertex == null) {
83 + // If vertex does not exist, create one and register it.
84 + vertex = new DefaultTopologyVertex(id);
85 + vertexesById.put(id, vertex);
86 + }
87 + return vertex;
88 + }
89 +
90 +}
1 -package org.onlab.onos.net.trivial.topology.provider.impl; 1 +package org.onlab.onos.net.trivial.topology.impl;
2 2
3 import org.onlab.onos.net.Link; 3 import org.onlab.onos.net.Link;
4 -import org.onlab.onos.net.topology.TopoEdge; 4 +import org.onlab.onos.net.topology.TopologyEdge;
5 -import org.onlab.onos.net.topology.TopoVertex; 5 +import org.onlab.onos.net.topology.TopologyVertex;
6 6
7 import java.util.Objects; 7 import java.util.Objects;
8 8
...@@ -11,11 +11,11 @@ import static com.google.common.base.MoreObjects.toStringHelper; ...@@ -11,11 +11,11 @@ import static com.google.common.base.MoreObjects.toStringHelper;
11 /** 11 /**
12 * Implementation of the topology edge backed by a link. 12 * Implementation of the topology edge backed by a link.
13 */ 13 */
14 -class DefaultTopoEdge implements TopoEdge { 14 +class DefaultTopologyEdge implements TopologyEdge {
15 15
16 private final Link link; 16 private final Link link;
17 - private final TopoVertex src; 17 + private final TopologyVertex src;
18 - private final TopoVertex dst; 18 + private final TopologyVertex dst;
19 19
20 /** 20 /**
21 * Creates a new topology edge. 21 * Creates a new topology edge.
...@@ -24,7 +24,7 @@ class DefaultTopoEdge implements TopoEdge { ...@@ -24,7 +24,7 @@ class DefaultTopoEdge implements TopoEdge {
24 * @param dst destination vertex 24 * @param dst destination vertex
25 * @param link infrastructure link 25 * @param link infrastructure link
26 */ 26 */
27 - DefaultTopoEdge(TopoVertex src, TopoVertex dst, Link link) { 27 + DefaultTopologyEdge(TopologyVertex src, TopologyVertex dst, Link link) {
28 this.src = src; 28 this.src = src;
29 this.dst = dst; 29 this.dst = dst;
30 this.link = link; 30 this.link = link;
...@@ -36,12 +36,12 @@ class DefaultTopoEdge implements TopoEdge { ...@@ -36,12 +36,12 @@ class DefaultTopoEdge implements TopoEdge {
36 } 36 }
37 37
38 @Override 38 @Override
39 - public TopoVertex src() { 39 + public TopologyVertex src() {
40 return src; 40 return src;
41 } 41 }
42 42
43 @Override 43 @Override
44 - public TopoVertex dst() { 44 + public TopologyVertex dst() {
45 return dst; 45 return dst;
46 } 46 }
47 47
...@@ -52,8 +52,8 @@ class DefaultTopoEdge implements TopoEdge { ...@@ -52,8 +52,8 @@ class DefaultTopoEdge implements TopoEdge {
52 52
53 @Override 53 @Override
54 public boolean equals(Object obj) { 54 public boolean equals(Object obj) {
55 - if (obj instanceof DefaultTopoEdge) { 55 + if (obj instanceof DefaultTopologyEdge) {
56 - final DefaultTopoEdge other = (DefaultTopoEdge) obj; 56 + final DefaultTopologyEdge other = (DefaultTopologyEdge) obj;
57 return Objects.equals(this.link, other.link); 57 return Objects.equals(this.link, other.link);
58 } 58 }
59 return false; 59 return false;
......
1 +package org.onlab.onos.net.trivial.topology.impl;
2 +
3 +import org.onlab.graph.AdjacencyListsGraph;
4 +import org.onlab.onos.net.topology.TopologyEdge;
5 +import org.onlab.onos.net.topology.TopologyGraph;
6 +import org.onlab.onos.net.topology.TopologyVertex;
7 +
8 +import java.util.Set;
9 +
10 +/**
11 + * Default implementation of an immutable topology graph based on a generic
12 + * implementation of adjacency lists graph.
13 + */
14 +public class DefaultTopologyGraph
15 + extends AdjacencyListsGraph<TopologyVertex, TopologyEdge>
16 + implements TopologyGraph {
17 +
18 + /**
19 + * Creates a topology graph comprising of the specified vertexes and edges.
20 + *
21 + * @param vertexes set of graph vertexes
22 + * @param edges set of graph edges
23 + */
24 + public DefaultTopologyGraph(Set<TopologyVertex> vertexes, Set<TopologyEdge> edges) {
25 + super(vertexes, edges);
26 + }
27 +
28 +}
1 -package org.onlab.onos.net.trivial.topology.provider.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;
...@@ -16,7 +16,7 @@ import org.onlab.onos.net.link.LinkListener; ...@@ -16,7 +16,7 @@ import org.onlab.onos.net.link.LinkListener;
16 import org.onlab.onos.net.link.LinkService; 16 import org.onlab.onos.net.link.LinkService;
17 import org.onlab.onos.net.provider.AbstractProvider; 17 import org.onlab.onos.net.provider.AbstractProvider;
18 import org.onlab.onos.net.provider.ProviderId; 18 import org.onlab.onos.net.provider.ProviderId;
19 -import org.onlab.onos.net.topology.TopologyDescription; 19 +import org.onlab.onos.net.topology.GraphDescription;
20 import org.onlab.onos.net.topology.TopologyProvider; 20 import org.onlab.onos.net.topology.TopologyProvider;
21 import org.onlab.onos.net.topology.TopologyProviderRegistry; 21 import org.onlab.onos.net.topology.TopologyProviderRegistry;
22 import org.onlab.onos.net.topology.TopologyProviderService; 22 import org.onlab.onos.net.topology.TopologyProviderService;
...@@ -35,7 +35,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -35,7 +35,7 @@ import static org.slf4j.LoggerFactory.getLogger;
35 * Simple implementation of a network topology provider/computor. 35 * Simple implementation of a network topology provider/computor.
36 */ 36 */
37 @Component(immediate = true) 37 @Component(immediate = true)
38 -public class SimpleTopologyProvider extends AbstractProvider 38 +public class DefaultTopologyProvider extends AbstractProvider
39 implements TopologyProvider { 39 implements TopologyProvider {
40 40
41 // TODO: make these configurable 41 // TODO: make these configurable
...@@ -70,7 +70,7 @@ public class SimpleTopologyProvider extends AbstractProvider ...@@ -70,7 +70,7 @@ public class SimpleTopologyProvider extends AbstractProvider
70 /** 70 /**
71 * Creates a provider with the supplier identifier. 71 * Creates a provider with the supplier identifier.
72 */ 72 */
73 - public SimpleTopologyProvider() { 73 + public DefaultTopologyProvider() {
74 super(new ProviderId("org.onlab.onos.provider.topology")); 74 super(new ProviderId("org.onlab.onos.provider.topology"));
75 } 75 }
76 76
...@@ -110,17 +110,19 @@ public class SimpleTopologyProvider extends AbstractProvider ...@@ -110,17 +110,19 @@ public class SimpleTopologyProvider extends AbstractProvider
110 * @param reasons events which triggered the topology change 110 * @param reasons events which triggered the topology change
111 */ 111 */
112 private synchronized void triggerTopologyBuild(List<Event> reasons) { 112 private synchronized void triggerTopologyBuild(List<Event> reasons) {
113 - executor.execute(new TopologyBuilderTask(reasons)); 113 + if (executor != null) {
114 + executor.execute(new TopologyBuilderTask(reasons));
115 + }
114 } 116 }
115 117
116 // Builds the topology using the latest device and link information 118 // Builds the topology using the latest device and link information
117 // and citing the specified events as reasons for the change. 119 // and citing the specified events as reasons for the change.
118 private void buildTopology(List<Event> reasons) { 120 private void buildTopology(List<Event> reasons) {
119 if (isStarted) { 121 if (isStarted) {
120 - TopologyDescription desc = 122 + GraphDescription desc =
121 - new DefaultTopologyDescription(System.nanoTime(), 123 + new DefaultGraphDescription(System.nanoTime(),
122 - deviceService.getDevices(), 124 + deviceService.getDevices(),
123 - linkService.getLinks()); 125 + linkService.getLinks());
124 providerService.topologyChanged(desc, reasons); 126 providerService.topologyChanged(desc, reasons);
125 } 127 }
126 } 128 }
......
1 -package org.onlab.onos.net.trivial.topology.provider.impl; 1 +package org.onlab.onos.net.trivial.topology.impl;
2 2
3 import org.onlab.onos.net.DeviceId; 3 import org.onlab.onos.net.DeviceId;
4 -import org.onlab.onos.net.topology.TopoVertex; 4 +import org.onlab.onos.net.topology.TopologyVertex;
5 5
6 import java.util.Objects; 6 import java.util.Objects;
7 7
8 /** 8 /**
9 * Implementation of the topology vertex backed by a device id. 9 * Implementation of the topology vertex backed by a device id.
10 */ 10 */
11 -class DefaultTopoVertex implements TopoVertex { 11 +class DefaultTopologyVertex implements TopologyVertex {
12 12
13 private final DeviceId deviceId; 13 private final DeviceId deviceId;
14 14
...@@ -17,7 +17,7 @@ class DefaultTopoVertex implements TopoVertex { ...@@ -17,7 +17,7 @@ class DefaultTopoVertex implements TopoVertex {
17 * 17 *
18 * @param deviceId backing infrastructure device identifier 18 * @param deviceId backing infrastructure device identifier
19 */ 19 */
20 - DefaultTopoVertex(DeviceId deviceId) { 20 + DefaultTopologyVertex(DeviceId deviceId) {
21 this.deviceId = deviceId; 21 this.deviceId = deviceId;
22 } 22 }
23 23
...@@ -33,8 +33,8 @@ class DefaultTopoVertex implements TopoVertex { ...@@ -33,8 +33,8 @@ class DefaultTopoVertex implements TopoVertex {
33 33
34 @Override 34 @Override
35 public boolean equals(Object obj) { 35 public boolean equals(Object obj) {
36 - if (obj instanceof DefaultTopoVertex) { 36 + if (obj instanceof DefaultTopologyVertex) {
37 - final DefaultTopoVertex other = (DefaultTopoVertex) obj; 37 + final DefaultTopologyVertex other = (DefaultTopologyVertex) obj;
38 return Objects.equals(this.deviceId, other.deviceId); 38 return Objects.equals(this.deviceId, other.deviceId);
39 } 39 }
40 return false; 40 return false;
......
1 +package org.onlab.onos.net.trivial.topology.impl;
2 +
3 +import org.onlab.onos.net.DeviceId;
4 +
5 +import java.util.Objects;
6 +
7 +/**
8 + * Key for filing src/dst paths.
9 + */
10 +class PathKey {
11 + private final DeviceId src;
12 + private final DeviceId dst;
13 +
14 + /**
15 + * Creates a path key from the given source/dest pair.
16 + * @param src source device
17 + * @param dst destination device
18 + */
19 + PathKey(DeviceId src, DeviceId dst) {
20 + this.src = src;
21 + this.dst = dst;
22 + }
23 +
24 + @Override
25 + public int hashCode() {
26 + return Objects.hash(src, dst);
27 + }
28 +
29 + @Override
30 + public boolean equals(Object obj) {
31 + if (obj instanceof PathKey) {
32 + final PathKey other = (PathKey) obj;
33 + return Objects.equals(this.src, other.src) && Objects.equals(this.dst, other.dst);
34 + }
35 + return false;
36 + }
37 +}
...@@ -6,7 +6,6 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -6,7 +6,6 @@ import org.apache.felix.scr.annotations.Deactivate;
6 import org.apache.felix.scr.annotations.Reference; 6 import org.apache.felix.scr.annotations.Reference;
7 import org.apache.felix.scr.annotations.ReferenceCardinality; 7 import org.apache.felix.scr.annotations.ReferenceCardinality;
8 import org.apache.felix.scr.annotations.Service; 8 import org.apache.felix.scr.annotations.Service;
9 -import org.onlab.graph.Graph;
10 import org.onlab.onos.event.AbstractListenerRegistry; 9 import org.onlab.onos.event.AbstractListenerRegistry;
11 import org.onlab.onos.event.Event; 10 import org.onlab.onos.event.Event;
12 import org.onlab.onos.event.EventDeliveryService; 11 import org.onlab.onos.event.EventDeliveryService;
...@@ -15,13 +14,12 @@ import org.onlab.onos.net.DeviceId; ...@@ -15,13 +14,12 @@ import org.onlab.onos.net.DeviceId;
15 import org.onlab.onos.net.Path; 14 import org.onlab.onos.net.Path;
16 import org.onlab.onos.net.provider.AbstractProviderRegistry; 15 import org.onlab.onos.net.provider.AbstractProviderRegistry;
17 import org.onlab.onos.net.provider.AbstractProviderService; 16 import org.onlab.onos.net.provider.AbstractProviderService;
17 +import org.onlab.onos.net.topology.GraphDescription;
18 import org.onlab.onos.net.topology.LinkWeight; 18 import org.onlab.onos.net.topology.LinkWeight;
19 -import org.onlab.onos.net.topology.TopoEdge;
20 -import org.onlab.onos.net.topology.TopoVertex;
21 import org.onlab.onos.net.topology.Topology; 19 import org.onlab.onos.net.topology.Topology;
22 import org.onlab.onos.net.topology.TopologyCluster; 20 import org.onlab.onos.net.topology.TopologyCluster;
23 -import org.onlab.onos.net.topology.TopologyDescription;
24 import org.onlab.onos.net.topology.TopologyEvent; 21 import org.onlab.onos.net.topology.TopologyEvent;
22 +import org.onlab.onos.net.topology.TopologyGraph;
25 import org.onlab.onos.net.topology.TopologyListener; 23 import org.onlab.onos.net.topology.TopologyListener;
26 import org.onlab.onos.net.topology.TopologyProvider; 24 import org.onlab.onos.net.topology.TopologyProvider;
27 import org.onlab.onos.net.topology.TopologyProviderRegistry; 25 import org.onlab.onos.net.topology.TopologyProviderRegistry;
...@@ -98,7 +96,7 @@ public class SimpleTopologyManager ...@@ -98,7 +96,7 @@ public class SimpleTopologyManager
98 } 96 }
99 97
100 @Override 98 @Override
101 - public Graph<TopoVertex, TopoEdge> getGraph(Topology topology) { 99 + public TopologyGraph getGraph(Topology topology) {
102 checkNotNull(topology, TOPOLOGY_NULL); 100 checkNotNull(topology, TOPOLOGY_NULL);
103 return store.getGraph(defaultTopology(topology)); 101 return store.getGraph(defaultTopology(topology));
104 } 102 }
...@@ -159,16 +157,14 @@ public class SimpleTopologyManager ...@@ -159,16 +157,14 @@ public class SimpleTopologyManager
159 } 157 }
160 158
161 @Override 159 @Override
162 - public void topologyChanged(TopologyDescription topoDescription, 160 + public void topologyChanged(GraphDescription topoDescription,
163 List<Event> reasons) { 161 List<Event> reasons) {
164 checkNotNull(topoDescription, "Topology description cannot be null"); 162 checkNotNull(topoDescription, "Topology description cannot be null");
165 163
166 - log.info("Topology changed due to: {}", // to be removed soon
167 - reasons == null ? "initial compute" : reasons);
168 TopologyEvent event = store.updateTopology(provider().id(), 164 TopologyEvent event = store.updateTopology(provider().id(),
169 topoDescription, reasons); 165 topoDescription, reasons);
170 if (event != null) { 166 if (event != null) {
171 - log.info("Topology changed due to: {}", 167 + log.info("Topology {} changed due to: {}", event.subject(),
172 reasons == null ? "initial compute" : reasons); 168 reasons == null ? "initial compute" : reasons);
173 eventDispatcher.post(event); 169 eventDispatcher.post(event);
174 } 170 }
......
1 package org.onlab.onos.net.trivial.topology.impl; 1 package org.onlab.onos.net.trivial.topology.impl;
2 2
3 -import org.onlab.graph.Graph;
4 import org.onlab.onos.event.Event; 3 import org.onlab.onos.event.Event;
5 import org.onlab.onos.net.ConnectPoint; 4 import org.onlab.onos.net.ConnectPoint;
6 import org.onlab.onos.net.DeviceId; 5 import org.onlab.onos.net.DeviceId;
7 import org.onlab.onos.net.Path; 6 import org.onlab.onos.net.Path;
8 import org.onlab.onos.net.provider.ProviderId; 7 import org.onlab.onos.net.provider.ProviderId;
8 +import org.onlab.onos.net.topology.GraphDescription;
9 import org.onlab.onos.net.topology.LinkWeight; 9 import org.onlab.onos.net.topology.LinkWeight;
10 -import org.onlab.onos.net.topology.TopoEdge;
11 -import org.onlab.onos.net.topology.TopoVertex;
12 import org.onlab.onos.net.topology.Topology; 10 import org.onlab.onos.net.topology.Topology;
13 import org.onlab.onos.net.topology.TopologyCluster; 11 import org.onlab.onos.net.topology.TopologyCluster;
14 -import org.onlab.onos.net.topology.TopologyDescription;
15 import org.onlab.onos.net.topology.TopologyEvent; 12 import org.onlab.onos.net.topology.TopologyEvent;
13 +import org.onlab.onos.net.topology.TopologyGraph;
16 14
17 import java.util.List; 15 import java.util.List;
18 import java.util.Set; 16 import java.util.Set;
...@@ -61,7 +59,7 @@ class SimpleTopologyStore { ...@@ -61,7 +59,7 @@ class SimpleTopologyStore {
61 * @param topology topology descriptor 59 * @param topology topology descriptor
62 * @return graph view 60 * @return graph view
63 */ 61 */
64 - Graph<TopoVertex, TopoEdge> getGraph(DefaultTopology topology) { 62 + TopologyGraph getGraph(DefaultTopology topology) {
65 return topology.getGraph(); 63 return topology.getGraph();
66 } 64 }
67 65
...@@ -88,7 +86,7 @@ class SimpleTopologyStore { ...@@ -88,7 +86,7 @@ class SimpleTopologyStore {
88 */ 86 */
89 Set<Path> getPaths(DefaultTopology topology, DeviceId src, DeviceId dst, 87 Set<Path> getPaths(DefaultTopology topology, DeviceId src, DeviceId dst,
90 LinkWeight weight) { 88 LinkWeight weight) {
91 - return null; 89 + return topology.getPaths(src, dst, weight);
92 } 90 }
93 91
94 /** 92 /**
...@@ -116,27 +114,29 @@ class SimpleTopologyStore { ...@@ -116,27 +114,29 @@ class SimpleTopologyStore {
116 /** 114 /**
117 * Generates a new topology snapshot from the specified description. 115 * Generates a new topology snapshot from the specified description.
118 * 116 *
119 - * @param providerId provider identification 117 + * @param providerId provider identification
120 - * @param topoDescription topology description 118 + * @param graphDescription topology graph description
121 - * @param reasons list of events that triggered the update 119 + * @param reasons list of events that triggered the update
122 * @return topology update event or null if the description is old 120 * @return topology update event or null if the description is old
123 */ 121 */
124 TopologyEvent updateTopology(ProviderId providerId, 122 TopologyEvent updateTopology(ProviderId providerId,
125 - TopologyDescription topoDescription, 123 + GraphDescription graphDescription,
126 List<Event> reasons) { 124 List<Event> reasons) {
127 // First off, make sure that what we're given is indeed newer than 125 // First off, make sure that what we're given is indeed newer than
128 // what we already have. 126 // what we already have.
129 - if (current != null && topoDescription.timestamp() < current.time()) { 127 + if (current != null && graphDescription.timestamp() < current.time()) {
130 return null; 128 return null;
131 } 129 }
132 130
133 // Have the default topology construct self from the description data. 131 // Have the default topology construct self from the description data.
134 DefaultTopology newTopology = 132 DefaultTopology newTopology =
135 - new DefaultTopology(providerId, topoDescription); 133 + new DefaultTopology(providerId, graphDescription);
136 134
137 // Promote the new topology to current and return a ready-to-send event. 135 // Promote the new topology to current and return a ready-to-send event.
138 - current = newTopology; 136 + synchronized (this) {
139 - return new TopologyEvent(TopologyEvent.Type.TOPOLOGY_CHANGED, current); 137 + current = newTopology;
138 + return new TopologyEvent(TopologyEvent.Type.TOPOLOGY_CHANGED, current);
139 + }
140 } 140 }
141 141
142 } 142 }
......
1 -package org.onlab.onos.net.trivial.topology.provider.impl;
2 -
3 -import com.google.common.collect.ImmutableMap;
4 -import com.google.common.collect.ImmutableSet;
5 -import com.google.common.collect.ImmutableSetMultimap;
6 -import com.google.common.collect.Maps;
7 -import com.google.common.collect.Sets;
8 -import org.onlab.graph.AdjacencyListsGraph;
9 -import org.onlab.graph.DijkstraGraphSearch;
10 -import org.onlab.graph.Graph;
11 -import org.onlab.graph.GraphPathSearch;
12 -import org.onlab.graph.TarjanGraphSearch;
13 -import org.onlab.onos.net.ConnectPoint;
14 -import org.onlab.onos.net.Device;
15 -import org.onlab.onos.net.DeviceId;
16 -import org.onlab.onos.net.Link;
17 -import org.onlab.onos.net.topology.ClusterId;
18 -import org.onlab.onos.net.topology.DefaultTopologyCluster;
19 -import org.onlab.onos.net.topology.LinkWeight;
20 -import org.onlab.onos.net.topology.TopoEdge;
21 -import org.onlab.onos.net.topology.TopoVertex;
22 -import org.onlab.onos.net.topology.TopologyCluster;
23 -import org.onlab.onos.net.topology.TopologyDescription;
24 -
25 -import java.util.List;
26 -import java.util.Map;
27 -import java.util.Set;
28 -
29 -import static com.google.common.collect.ImmutableSetMultimap.Builder;
30 -import static com.google.common.collect.ImmutableSetMultimap.builder;
31 -import static org.onlab.graph.GraphPathSearch.Result;
32 -import static org.onlab.graph.TarjanGraphSearch.SCCResult;
33 -import static org.onlab.onos.net.Link.Type.INDIRECT;
34 -
35 -/**
36 - * Default implementation of an immutable topology data carrier.
37 - */
38 -class DefaultTopologyDescription implements TopologyDescription {
39 -
40 - private static final GraphPathSearch<TopoVertex, TopoEdge> DIJKSTRA =
41 - new DijkstraGraphSearch<>();
42 - private static final TarjanGraphSearch<TopoVertex, TopoEdge> TARJAN =
43 - new TarjanGraphSearch<>();
44 -
45 - private final long nanos;
46 - private final Map<DeviceId, TopoVertex> vertexesById = Maps.newHashMap();
47 - private final Graph<TopoVertex, TopoEdge> graph;
48 - private final ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> results;
49 -
50 - // Cluster-related structures
51 - private final ImmutableSet<TopologyCluster> clusters;
52 - private ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster;
53 - private ImmutableSetMultimap<TopologyCluster, Link> linksByCluster;
54 -
55 - /**
56 - * Creates a topology description to carry topology vitals to the core.
57 - *
58 - * @param nanos time in nanos of when the topology description was created
59 - * @param devices collection of infrastructure devices
60 - * @param links collection of infrastructure links
61 - */
62 - DefaultTopologyDescription(long nanos, Iterable<Device> devices, Iterable<Link> links) {
63 - this.nanos = nanos;
64 - this.graph = buildGraph(devices, links);
65 - this.results = computeDefaultPaths();
66 - this.clusters = computeClusters();
67 - }
68 -
69 - @Override
70 - public long timestamp() {
71 - return nanos;
72 - }
73 -
74 - @Override
75 - public Graph<TopoVertex, TopoEdge> graph() {
76 - return graph;
77 - }
78 -
79 - @Override
80 - public ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> pathsBySource() {
81 - return results;
82 - }
83 -
84 - @Override
85 - public ImmutableSet<TopologyCluster> clusters() {
86 - return clusters;
87 - }
88 -
89 - @Override
90 - public ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster() {
91 - return devicesByCluster;
92 - }
93 -
94 - @Override
95 - public ImmutableSetMultimap<TopologyCluster, Link> linksByCluster() {
96 - return linksByCluster;
97 - }
98 -
99 - // Link weight for measuring link cost as hop count with indirect links
100 - // being as expensive as traversing the entire graph to assume the worst.
101 - private static class HopCountLinkWeight implements LinkWeight {
102 - private final int indirectLinkCost;
103 -
104 - HopCountLinkWeight(int indirectLinkCost) {
105 - this.indirectLinkCost = indirectLinkCost;
106 - }
107 -
108 - @Override
109 - public double weight(TopoEdge edge) {
110 - // To force preference to use direct paths first, make indirect
111 - // links as expensive as the linear vertex traversal.
112 - return edge.link().type() == INDIRECT ? indirectLinkCost : 1;
113 - }
114 - }
115 -
116 - // Link weight for preventing traversal over indirect links.
117 - private static class NoIndirectLinksWeight implements LinkWeight {
118 - @Override
119 - public double weight(TopoEdge edge) {
120 - return edge.link().type() == INDIRECT ? -1 : 1;
121 - }
122 - }
123 -
124 - // Constructs the topology graph using the supplied devices and links.
125 - private Graph<TopoVertex, TopoEdge> buildGraph(Iterable<Device> devices,
126 - Iterable<Link> links) {
127 - return new AdjacencyListsGraph<>(buildVertexes(devices),
128 - buildEdges(links));
129 - }
130 -
131 - // Builds a set of topology vertexes from the specified list of devices
132 - private Set<TopoVertex> buildVertexes(Iterable<Device> devices) {
133 - Set<TopoVertex> vertexes = Sets.newHashSet();
134 - for (Device device : devices) {
135 - TopoVertex vertex = new DefaultTopoVertex(device.id());
136 - vertexes.add(vertex);
137 - vertexesById.put(vertex.deviceId(), vertex);
138 - }
139 - return vertexes;
140 - }
141 -
142 - // Builds a set of topology vertexes from the specified list of links
143 - private Set<TopoEdge> buildEdges(Iterable<Link> links) {
144 - Set<TopoEdge> edges = Sets.newHashSet();
145 - for (Link link : links) {
146 - edges.add(new DefaultTopoEdge(vertexOf(link.src()),
147 - vertexOf(link.dst()), link));
148 - }
149 - return edges;
150 - }
151 -
152 - // Computes the default shortest paths for all source/dest pairs using
153 - // the multi-path Dijkstra and hop-count as path cost.
154 - private ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> computeDefaultPaths() {
155 - LinkWeight weight = new HopCountLinkWeight(graph.getVertexes().size());
156 - ImmutableMap.Builder<DeviceId, Result<TopoVertex, TopoEdge>> results =
157 - ImmutableMap.builder();
158 -
159 - // Search graph paths for each source to all destinations.
160 - for (TopoVertex src : vertexesById.values()) {
161 - results.put(src.deviceId(), DIJKSTRA.search(graph, src, null, weight));
162 - }
163 - return results.build();
164 - }
165 -
166 - // Computes topology SCC clusters using Tarjan algorithm.
167 - private ImmutableSet<TopologyCluster> computeClusters() {
168 - ImmutableSet.Builder<TopologyCluster> clusterBuilder = ImmutableSet.builder();
169 - SCCResult<TopoVertex, TopoEdge> result =
170 - TARJAN.search(graph, new NoIndirectLinksWeight());
171 -
172 - // Extract both vertexes and edges from the results; the lists form
173 - // pairs along the same index.
174 - List<Set<TopoVertex>> clusterVertexes = result.clusterVertexes();
175 - List<Set<TopoEdge>> clusterEdges = result.clusterEdges();
176 -
177 - Builder<TopologyCluster, DeviceId> devicesBuilder = ImmutableSetMultimap.builder();
178 - Builder<TopologyCluster, Link> linksBuilder = ImmutableSetMultimap.builder();
179 -
180 - // Scan over the lists and create a cluster from the results.
181 - for (int i = 0, n = result.clusterCount(); i < n; i++) {
182 - Set<TopoVertex> vertexSet = clusterVertexes.get(i);
183 - Set<TopoEdge> edgeSet = clusterEdges.get(i);
184 -
185 - DefaultTopologyCluster cluster =
186 - new DefaultTopologyCluster(ClusterId.clusterId(i),
187 - vertexSet.size(), edgeSet.size(),
188 - findRoot(vertexSet).deviceId());
189 - clusterBuilder.add(cluster);
190 - findClusterDevices(vertexSet, cluster, devicesBuilder);
191 - findClusterLinks(edgeSet, cluster, linksBuilder);
192 - }
193 - return clusterBuilder.build();
194 - }
195 -
196 - // Scans through the set of cluster vertexes and puts their devices in a
197 - // multi-map associated with the cluster. It also binds the devices to
198 - // the cluster.
199 - private void findClusterDevices(Set<TopoVertex> vertexSet,
200 - DefaultTopologyCluster cluster,
201 - Builder<TopologyCluster, DeviceId> builder) {
202 - for (TopoVertex vertex : vertexSet) {
203 - DeviceId deviceId = vertex.deviceId();
204 - builder.put(cluster, deviceId);
205 - }
206 - }
207 -
208 - // Scans through the set of cluster edges and puts their links in a
209 - // multi-map associated with the cluster.
210 - private void findClusterLinks(Set<TopoEdge> edgeSet,
211 - DefaultTopologyCluster cluster,
212 - Builder<TopologyCluster, Link> builder) {
213 - for (TopoEdge edge : edgeSet) {
214 - builder.put(cluster, edge.link());
215 - }
216 - }
217 -
218 - // Finds the vertex whose device id is the lexicographical minimum in the
219 - // specified set.
220 - private TopoVertex findRoot(Set<TopoVertex> vertexSet) {
221 - TopoVertex minVertex = null;
222 - for (TopoVertex vertex : vertexSet) {
223 - if (minVertex == null ||
224 - minVertex.deviceId().toString()
225 - .compareTo(minVertex.deviceId().toString()) < 0) {
226 - minVertex = vertex;
227 - }
228 - }
229 - return minVertex;
230 - }
231 -
232 - // Fetches a vertex corresponding to the given connection point device.
233 - private TopoVertex vertexOf(ConnectPoint connectPoint) {
234 - DeviceId id = connectPoint.deviceId();
235 - TopoVertex vertex = vertexesById.get(id);
236 - if (vertex == null) {
237 - // If vertex does not exist, create one and register it.
238 - vertex = new DefaultTopoVertex(id);
239 - vertexesById.put(id, vertex);
240 - }
241 - return vertex;
242 - }
243 -
244 -}
1 -<body>
2 -Built-in protocol-agnostic topology builder &amp; provider.
3 -</body>
...\ No newline at end of file ...\ No newline at end of file