Showing
10 changed files
with
153 additions
and
165 deletions
1 | -package org.onlab.onos.cli; | ||
2 | - | ||
3 | -import org.apache.karaf.shell.commands.Argument; | ||
4 | -import org.apache.karaf.shell.commands.Command; | ||
5 | -import org.onlab.onos.GreetService; | ||
6 | - | ||
7 | -/** | ||
8 | - * Simple command example to demonstrate use of Karaf shell extensions; shows | ||
9 | - * use of an optional parameter as well. | ||
10 | - */ | ||
11 | -@Command(scope = "onos", name = "greet", description = "Issues a greeting") | ||
12 | -public class GreetCommand extends AbstractShellCommand { | ||
13 | - | ||
14 | - @Argument(index = 0, name = "name", description = "Name to greet", | ||
15 | - required = false, multiValued = false) | ||
16 | - String name = "dude"; | ||
17 | - | ||
18 | - @Override | ||
19 | - protected Object doExecute() throws Exception { | ||
20 | - print(getService(GreetService.class).yo(name)); | ||
21 | - return null; | ||
22 | - } | ||
23 | -} |
1 | -package org.onlab.onos.cli; | ||
2 | - | ||
3 | -import org.apache.karaf.shell.console.Completer; | ||
4 | -import org.apache.karaf.shell.console.completer.StringsCompleter; | ||
5 | -import org.onlab.onos.GreetService; | ||
6 | - | ||
7 | -import java.util.Iterator; | ||
8 | -import java.util.List; | ||
9 | -import java.util.SortedSet; | ||
10 | - | ||
11 | -/** | ||
12 | - * Simple example of a command-line parameter completer. | ||
13 | - * For a more open-ended sets a more efficient implementation would be required. | ||
14 | - */ | ||
15 | -public class NameCompleter implements Completer { | ||
16 | - @Override | ||
17 | - public int complete(String buffer, int cursor, List<String> candidates) { | ||
18 | - // Delegate string completer | ||
19 | - StringsCompleter delegate = new StringsCompleter(); | ||
20 | - | ||
21 | - // Fetch our service and feed it's offerings to the string completer | ||
22 | - GreetService greetService = AbstractShellCommand.get(GreetService.class); | ||
23 | - Iterator<String> it = greetService.names().iterator(); | ||
24 | - SortedSet<String> strings = delegate.getStrings(); | ||
25 | - while (it.hasNext()) { | ||
26 | - strings.add(it.next()); | ||
27 | - } | ||
28 | - | ||
29 | - // Now let the completer do the work for figuring out what to offer. | ||
30 | - return delegate.complete(buffer, cursor, candidates); | ||
31 | - } | ||
32 | - | ||
33 | -} |
... | @@ -30,18 +30,9 @@ | ... | @@ -30,18 +30,9 @@ |
30 | <ref component-id="deviceIdCompleter"/> | 30 | <ref component-id="deviceIdCompleter"/> |
31 | </completers> | 31 | </completers> |
32 | </command> | 32 | </command> |
33 | - | ||
34 | - <command> | ||
35 | - <action class="org.onlab.onos.cli.GreetCommand"/> | ||
36 | - <completers> | ||
37 | - <ref component-id="nameCompleter"/> | ||
38 | - </completers> | ||
39 | - </command> | ||
40 | </command-bundle> | 33 | </command-bundle> |
41 | 34 | ||
42 | <bean id="deviceIdCompleter" class="org.onlab.onos.cli.net.DeviceIdCompleter"/> | 35 | <bean id="deviceIdCompleter" class="org.onlab.onos.cli.net.DeviceIdCompleter"/> |
43 | <bean id="roleCompleter" class="org.onlab.onos.cli.net.RoleCompleter"/> | 36 | <bean id="roleCompleter" class="org.onlab.onos.cli.net.RoleCompleter"/> |
44 | 37 | ||
45 | - <bean id="nameCompleter" class="org.onlab.onos.cli.NameCompleter"/> | ||
46 | - | ||
47 | </blueprint> | 38 | </blueprint> | ... | ... |
1 | package org.onlab.onos.net.topology; | 1 | package org.onlab.onos.net.topology; |
2 | 2 | ||
3 | +import com.google.common.collect.ImmutableMap; | ||
4 | +import com.google.common.collect.ImmutableSet; | ||
5 | +import com.google.common.collect.ImmutableSetMultimap; | ||
3 | import org.onlab.graph.Graph; | 6 | import org.onlab.graph.Graph; |
4 | -import org.onlab.graph.GraphPathSearch; | ||
5 | import org.onlab.onos.net.Description; | 7 | import org.onlab.onos.net.Description; |
6 | import org.onlab.onos.net.DeviceId; | 8 | import org.onlab.onos.net.DeviceId; |
7 | import org.onlab.onos.net.Link; | 9 | import org.onlab.onos.net.Link; |
8 | 10 | ||
9 | -import java.util.Set; | 11 | +import static org.onlab.graph.GraphPathSearch.Result; |
10 | 12 | ||
11 | /** | 13 | /** |
12 | * Describes attribute(s) of a network topology. | 14 | * Describes attribute(s) of a network topology. |
... | @@ -22,50 +24,39 @@ public interface TopologyDescription extends Description { | ... | @@ -22,50 +24,39 @@ public interface TopologyDescription extends Description { |
22 | long timestamp(); | 24 | long timestamp(); |
23 | 25 | ||
24 | /** | 26 | /** |
25 | - * Returns the topology graph. | 27 | + * Returns the topology graph in immutable form. |
26 | * | 28 | * |
27 | * @return network graph | 29 | * @return network graph |
28 | */ | 30 | */ |
29 | Graph<TopoVertex, TopoEdge> graph(); | 31 | Graph<TopoVertex, TopoEdge> graph(); |
30 | 32 | ||
31 | /** | 33 | /** |
32 | - * Returns the results of the path search through the network graph. This | 34 | + * Returns an immutable map of path search results for each source device. |
33 | - * is assumed to contain results of seach fro the given device to all | ||
34 | - * other devices. | ||
35 | * | 35 | * |
36 | - * @param srcDeviceId source device identifier | 36 | + * @return map of path search result for each source node |
37 | - * @return path search result for the given source node | ||
38 | */ | 37 | */ |
39 | - GraphPathSearch.Result pathResults(DeviceId srcDeviceId); | 38 | + ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> pathsBySource(); |
40 | 39 | ||
41 | /** | 40 | /** |
42 | * Returns the set of topology SCC clusters. | 41 | * Returns the set of topology SCC clusters. |
43 | * | 42 | * |
44 | * @return set of SCC clusters | 43 | * @return set of SCC clusters |
45 | */ | 44 | */ |
46 | - Set<TopologyCluster> clusters(); | 45 | + ImmutableSet<TopologyCluster> clusters(); |
47 | 46 | ||
48 | /** | 47 | /** |
49 | - * Returns the set of devices contained by the specified topology cluster. | 48 | + * Returns an immutable set multi-map of devices for each cluster. |
50 | * | 49 | * |
51 | - * @return set of devices that belong to the specified cluster | 50 | + * @return set multi-map of devices that belong to each cluster |
52 | */ | 51 | */ |
53 | - Set<DeviceId> clusterDevices(TopologyCluster cluster); | 52 | + ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster(); |
54 | 53 | ||
55 | /** | 54 | /** |
56 | - * Returns the set of infrastructure links contained by the specified cluster. | 55 | + * Returns an immutable set multi-map of links for each cluster. |
57 | * | 56 | * |
58 | - * @return set of links that form the given cluster | 57 | + * @return set multi-map of links that belong to each cluster |
59 | */ | 58 | */ |
60 | - Set<Link> clusterLinks(TopologyCluster cluster); | 59 | + ImmutableSetMultimap<TopologyCluster, Link> linksByCluster(); |
61 | - | ||
62 | - /** | ||
63 | - * Returns the topology SCC cluster which contains the given device. | ||
64 | - * | ||
65 | - * @param deviceId device identifier | ||
66 | - * @return topology cluster that contains the specified device | ||
67 | - */ | ||
68 | - TopologyCluster clusterFor(DeviceId deviceId); | ||
69 | 60 | ||
70 | } | 61 | } |
71 | 62 | ... | ... |
... | @@ -21,6 +21,7 @@ public interface TopologyService { | ... | @@ -21,6 +21,7 @@ public interface TopologyService { |
21 | 21 | ||
22 | /** | 22 | /** |
23 | * Indicates whether the specified topology is the latest or not. | 23 | * Indicates whether the specified topology is the latest or not. |
24 | + * | ||
24 | * @param topology topology descriptor | 25 | * @param topology topology descriptor |
25 | * @return true if the topology is the most recent; false otherwise | 26 | * @return true if the topology is the most recent; false otherwise |
26 | */ | 27 | */ | ... | ... |
1 | package org.onlab.onos.net.trivial.topology.impl; | 1 | package org.onlab.onos.net.trivial.topology.impl; |
2 | 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.graph.GraphPathSearch; | ||
3 | import org.onlab.onos.net.AbstractModel; | 8 | import org.onlab.onos.net.AbstractModel; |
9 | +import org.onlab.onos.net.ConnectPoint; | ||
10 | +import org.onlab.onos.net.DeviceId; | ||
11 | +import org.onlab.onos.net.Link; | ||
12 | +import org.onlab.onos.net.Path; | ||
4 | import org.onlab.onos.net.provider.ProviderId; | 13 | import org.onlab.onos.net.provider.ProviderId; |
14 | +import org.onlab.onos.net.topology.TopoEdge; | ||
15 | +import org.onlab.onos.net.topology.TopoVertex; | ||
5 | import org.onlab.onos.net.topology.Topology; | 16 | import org.onlab.onos.net.topology.Topology; |
17 | +import org.onlab.onos.net.topology.TopologyCluster; | ||
18 | +import org.onlab.onos.net.topology.TopologyDescription; | ||
19 | + | ||
20 | +import java.util.Set; | ||
6 | 21 | ||
7 | /** | 22 | /** |
8 | * Default implementation of the topology descriptor. This carries the | 23 | * Default implementation of the topology descriptor. This carries the |
... | @@ -11,29 +26,33 @@ import org.onlab.onos.net.topology.Topology; | ... | @@ -11,29 +26,33 @@ import org.onlab.onos.net.topology.Topology; |
11 | public class DefaultTopology extends AbstractModel implements Topology { | 26 | public class DefaultTopology extends AbstractModel implements Topology { |
12 | 27 | ||
13 | private final long time; | 28 | private final long time; |
14 | - private final int clusterCount; | ||
15 | - private final int deviceCount; | ||
16 | - private final int linkCount; | ||
17 | private final int pathCount; | 29 | private final int pathCount; |
18 | 30 | ||
31 | + private final Graph<TopoVertex, TopoEdge> graph; | ||
32 | + private final ImmutableMap<DeviceId, GraphPathSearch.Result<TopoVertex, TopoEdge>> results; | ||
33 | + | ||
34 | + private final ImmutableSet<TopologyCluster> clusters; | ||
35 | + private final ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster; | ||
36 | + private final ImmutableSetMultimap<TopologyCluster, Link> linksByCluster; | ||
37 | + private final ImmutableSet connectPoints; | ||
38 | + | ||
19 | /** | 39 | /** |
20 | * Creates a topology descriptor attributed to the specified provider. | 40 | * Creates a topology descriptor attributed to the specified provider. |
21 | * | 41 | * |
22 | - * @param providerId identity of the provider | 42 | + * @param providerId identity of the provider |
23 | - * @param time creation time in system nanos | 43 | + * @param description data describing the new topology |
24 | - * @param clusterCount number of clusters | ||
25 | - * @param deviceCount number of devices | ||
26 | - * @param linkCount number of links | ||
27 | - * @param pathCount number of pre-computed paths | ||
28 | */ | 44 | */ |
29 | - DefaultTopology(ProviderId providerId, long time, int clusterCount, | 45 | + DefaultTopology(ProviderId providerId, TopologyDescription description) { |
30 | - int deviceCount, int linkCount, int pathCount) { | ||
31 | super(providerId); | 46 | super(providerId); |
32 | - this.time = time; | 47 | + this.time = description.timestamp(); |
33 | - this.clusterCount = clusterCount; | 48 | + this.graph = description.graph(); |
34 | - this.deviceCount = deviceCount; | 49 | + this.results = description.pathsBySource(); |
35 | - this.linkCount = linkCount; | 50 | + this.clusters = description.clusters(); |
36 | - this.pathCount = pathCount; | 51 | + this.devicesByCluster = description.devicesByCluster(); |
52 | + this.linksByCluster = description.linksByCluster(); | ||
53 | + | ||
54 | + this.connectPoints = ImmutableSet.of(); | ||
55 | + this.pathCount = 0; | ||
37 | } | 56 | } |
38 | 57 | ||
39 | @Override | 58 | @Override |
... | @@ -43,17 +62,17 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -43,17 +62,17 @@ public class DefaultTopology extends AbstractModel implements Topology { |
43 | 62 | ||
44 | @Override | 63 | @Override |
45 | public int clusterCount() { | 64 | public int clusterCount() { |
46 | - return clusterCount; | 65 | + return clusters.size(); |
47 | } | 66 | } |
48 | 67 | ||
49 | @Override | 68 | @Override |
50 | public int deviceCount() { | 69 | public int deviceCount() { |
51 | - return deviceCount; | 70 | + return graph.getVertexes().size(); |
52 | } | 71 | } |
53 | 72 | ||
54 | @Override | 73 | @Override |
55 | public int linkCount() { | 74 | public int linkCount() { |
56 | - return linkCount; | 75 | + return graph.getEdges().size(); |
57 | } | 76 | } |
58 | 77 | ||
59 | @Override | 78 | @Override |
... | @@ -61,4 +80,23 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -61,4 +80,23 @@ public class DefaultTopology extends AbstractModel implements Topology { |
61 | return pathCount; | 80 | return pathCount; |
62 | } | 81 | } |
63 | 82 | ||
83 | + Set<TopologyCluster> getClusters() { | ||
84 | + return clusters; | ||
85 | + } | ||
86 | + | ||
87 | + Graph<TopoVertex, TopoEdge> getGraph() { | ||
88 | + return graph; | ||
89 | + } | ||
90 | + | ||
91 | + boolean isInfrastructure(ConnectPoint connectPoint) { | ||
92 | + return connectPoints.contains(connectPoint); | ||
93 | + } | ||
94 | + | ||
95 | + boolean isInBroadcastTree(ConnectPoint connectPoint) { | ||
96 | + return false; | ||
97 | + } | ||
98 | + | ||
99 | + Set<Path> getPaths(DeviceId src, DeviceId dst) { | ||
100 | + return null; // pointToPointPaths.get(key(src, dst)); | ||
101 | + } | ||
64 | } | 102 | } | ... | ... |
... | @@ -79,19 +79,28 @@ public class SimpleTopologyManager | ... | @@ -79,19 +79,28 @@ public class SimpleTopologyManager |
79 | @Override | 79 | @Override |
80 | public boolean isLatest(Topology topology) { | 80 | public boolean isLatest(Topology topology) { |
81 | checkNotNull(topology, TOPOLOGY_NULL); | 81 | checkNotNull(topology, TOPOLOGY_NULL); |
82 | - return store.isLatest(topology); | 82 | + return store.isLatest(defaultTopology(topology)); |
83 | + } | ||
84 | + | ||
85 | + // Validates the specified topology and returns it as a default | ||
86 | + private DefaultTopology defaultTopology(Topology topology) { | ||
87 | + if (topology instanceof DefaultTopology) { | ||
88 | + return (DefaultTopology) topology; | ||
89 | + } | ||
90 | + throw new IllegalArgumentException("Topology class " + topology.getClass() + | ||
91 | + " not supported"); | ||
83 | } | 92 | } |
84 | 93 | ||
85 | @Override | 94 | @Override |
86 | public Set<TopologyCluster> getClusters(Topology topology) { | 95 | public Set<TopologyCluster> getClusters(Topology topology) { |
87 | checkNotNull(topology, TOPOLOGY_NULL); | 96 | checkNotNull(topology, TOPOLOGY_NULL); |
88 | - return store.getClusters(topology); | 97 | + return store.getClusters(defaultTopology(topology)); |
89 | } | 98 | } |
90 | 99 | ||
91 | @Override | 100 | @Override |
92 | public Graph<TopoVertex, TopoEdge> getGraph(Topology topology) { | 101 | public Graph<TopoVertex, TopoEdge> getGraph(Topology topology) { |
93 | checkNotNull(topology, TOPOLOGY_NULL); | 102 | checkNotNull(topology, TOPOLOGY_NULL); |
94 | - return store.getGraph(topology); | 103 | + return store.getGraph(defaultTopology(topology)); |
95 | } | 104 | } |
96 | 105 | ||
97 | @Override | 106 | @Override |
... | @@ -99,7 +108,7 @@ public class SimpleTopologyManager | ... | @@ -99,7 +108,7 @@ public class SimpleTopologyManager |
99 | checkNotNull(topology, TOPOLOGY_NULL); | 108 | checkNotNull(topology, TOPOLOGY_NULL); |
100 | checkNotNull(src, DEVICE_ID_NULL); | 109 | checkNotNull(src, DEVICE_ID_NULL); |
101 | checkNotNull(dst, DEVICE_ID_NULL); | 110 | checkNotNull(dst, DEVICE_ID_NULL); |
102 | - return store.getPaths(topology, src, dst); | 111 | + return store.getPaths(defaultTopology(topology), src, dst); |
103 | } | 112 | } |
104 | 113 | ||
105 | @Override | 114 | @Override |
... | @@ -108,21 +117,21 @@ public class SimpleTopologyManager | ... | @@ -108,21 +117,21 @@ public class SimpleTopologyManager |
108 | checkNotNull(src, DEVICE_ID_NULL); | 117 | checkNotNull(src, DEVICE_ID_NULL); |
109 | checkNotNull(dst, DEVICE_ID_NULL); | 118 | checkNotNull(dst, DEVICE_ID_NULL); |
110 | checkNotNull(weight, "Link weight cannot be null"); | 119 | checkNotNull(weight, "Link weight cannot be null"); |
111 | - return store.getPaths(topology, src, dst, weight); | 120 | + return store.getPaths(defaultTopology(topology), src, dst, weight); |
112 | } | 121 | } |
113 | 122 | ||
114 | @Override | 123 | @Override |
115 | public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) { | 124 | public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) { |
116 | checkNotNull(topology, TOPOLOGY_NULL); | 125 | checkNotNull(topology, TOPOLOGY_NULL); |
117 | checkNotNull(connectPoint, CONNECTION_POINT_NULL); | 126 | checkNotNull(connectPoint, CONNECTION_POINT_NULL); |
118 | - return store.isInfrastructure(topology, connectPoint); | 127 | + return store.isInfrastructure(defaultTopology(topology), connectPoint); |
119 | } | 128 | } |
120 | 129 | ||
121 | @Override | 130 | @Override |
122 | public boolean isInBroadcastTree(Topology topology, ConnectPoint connectPoint) { | 131 | public boolean isInBroadcastTree(Topology topology, ConnectPoint connectPoint) { |
123 | checkNotNull(topology, TOPOLOGY_NULL); | 132 | checkNotNull(topology, TOPOLOGY_NULL); |
124 | checkNotNull(connectPoint, CONNECTION_POINT_NULL); | 133 | checkNotNull(connectPoint, CONNECTION_POINT_NULL); |
125 | - return store.isInBroadcastTree(topology, connectPoint); | 134 | + return store.isInBroadcastTree(defaultTopology(topology), connectPoint); |
126 | } | 135 | } |
127 | 136 | ||
128 | @Override | 137 | @Override |
... | @@ -156,7 +165,8 @@ public class SimpleTopologyManager | ... | @@ -156,7 +165,8 @@ public class SimpleTopologyManager |
156 | 165 | ||
157 | log.info("Topology changed due to: {}", // to be removed soon | 166 | log.info("Topology changed due to: {}", // to be removed soon |
158 | reasons == null ? "initial compute" : reasons); | 167 | reasons == null ? "initial compute" : reasons); |
159 | - TopologyEvent event = store.updateTopology(topoDescription, reasons); | 168 | + TopologyEvent event = store.updateTopology(provider().id(), |
169 | + topoDescription, reasons); | ||
160 | if (event != null) { | 170 | if (event != null) { |
161 | log.info("Topology changed due to: {}", | 171 | log.info("Topology changed due to: {}", |
162 | reasons == null ? "initial compute" : reasons); | 172 | reasons == null ? "initial compute" : reasons); | ... | ... |
... | @@ -5,6 +5,7 @@ import org.onlab.onos.event.Event; | ... | @@ -5,6 +5,7 @@ import org.onlab.onos.event.Event; |
5 | import org.onlab.onos.net.ConnectPoint; | 5 | import org.onlab.onos.net.ConnectPoint; |
6 | import org.onlab.onos.net.DeviceId; | 6 | import org.onlab.onos.net.DeviceId; |
7 | import org.onlab.onos.net.Path; | 7 | import org.onlab.onos.net.Path; |
8 | +import org.onlab.onos.net.provider.ProviderId; | ||
8 | import org.onlab.onos.net.topology.LinkWeight; | 9 | import org.onlab.onos.net.topology.LinkWeight; |
9 | import org.onlab.onos.net.topology.TopoEdge; | 10 | import org.onlab.onos.net.topology.TopoEdge; |
10 | import org.onlab.onos.net.topology.TopoVertex; | 11 | import org.onlab.onos.net.topology.TopoVertex; |
... | @@ -50,8 +51,8 @@ class SimpleTopologyStore { | ... | @@ -50,8 +51,8 @@ class SimpleTopologyStore { |
50 | * @param topology topology descriptor | 51 | * @param topology topology descriptor |
51 | * @return set of clusters | 52 | * @return set of clusters |
52 | */ | 53 | */ |
53 | - Set<TopologyCluster> getClusters(Topology topology) { | 54 | + Set<TopologyCluster> getClusters(DefaultTopology topology) { |
54 | - return null; | 55 | + return topology.getClusters(); |
55 | } | 56 | } |
56 | 57 | ||
57 | /** | 58 | /** |
... | @@ -60,8 +61,8 @@ class SimpleTopologyStore { | ... | @@ -60,8 +61,8 @@ class SimpleTopologyStore { |
60 | * @param topology topology descriptor | 61 | * @param topology topology descriptor |
61 | * @return graph view | 62 | * @return graph view |
62 | */ | 63 | */ |
63 | - Graph<TopoVertex, TopoEdge> getGraph(Topology topology) { | 64 | + Graph<TopoVertex, TopoEdge> getGraph(DefaultTopology topology) { |
64 | - return null; | 65 | + return topology.getGraph(); |
65 | } | 66 | } |
66 | 67 | ||
67 | /** | 68 | /** |
... | @@ -72,8 +73,8 @@ class SimpleTopologyStore { | ... | @@ -72,8 +73,8 @@ class SimpleTopologyStore { |
72 | * @param dst destination device | 73 | * @param dst destination device |
73 | * @return set of shortest paths | 74 | * @return set of shortest paths |
74 | */ | 75 | */ |
75 | - Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) { | 76 | + Set<Path> getPaths(DefaultTopology topology, DeviceId src, DeviceId dst) { |
76 | - return null; | 77 | + return topology.getPaths(src, dst); |
77 | } | 78 | } |
78 | 79 | ||
79 | /** | 80 | /** |
... | @@ -85,7 +86,7 @@ class SimpleTopologyStore { | ... | @@ -85,7 +86,7 @@ class SimpleTopologyStore { |
85 | * @param weight link weight function | 86 | * @param weight link weight function |
86 | * @return set of shortest paths | 87 | * @return set of shortest paths |
87 | */ | 88 | */ |
88 | - Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, | 89 | + Set<Path> getPaths(DefaultTopology topology, DeviceId src, DeviceId dst, |
89 | LinkWeight weight) { | 90 | LinkWeight weight) { |
90 | return null; | 91 | return null; |
91 | } | 92 | } |
... | @@ -97,8 +98,8 @@ class SimpleTopologyStore { | ... | @@ -97,8 +98,8 @@ class SimpleTopologyStore { |
97 | * @param connectPoint connection point | 98 | * @param connectPoint connection point |
98 | * @return true if infrastructure; false otherwise | 99 | * @return true if infrastructure; false otherwise |
99 | */ | 100 | */ |
100 | - boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) { | 101 | + boolean isInfrastructure(DefaultTopology topology, ConnectPoint connectPoint) { |
101 | - return false; | 102 | + return topology.isInfrastructure(connectPoint); |
102 | } | 103 | } |
103 | 104 | ||
104 | /** | 105 | /** |
... | @@ -108,20 +109,34 @@ class SimpleTopologyStore { | ... | @@ -108,20 +109,34 @@ class SimpleTopologyStore { |
108 | * @param connectPoint connection point | 109 | * @param connectPoint connection point |
109 | * @return true if in broadcast tree; false otherwise | 110 | * @return true if in broadcast tree; false otherwise |
110 | */ | 111 | */ |
111 | - boolean isInBroadcastTree(Topology topology, ConnectPoint connectPoint) { | 112 | + boolean isInBroadcastTree(DefaultTopology topology, ConnectPoint connectPoint) { |
112 | - return false; | 113 | + return topology.isInBroadcastTree(connectPoint); |
113 | } | 114 | } |
114 | 115 | ||
115 | /** | 116 | /** |
116 | * Generates a new topology snapshot from the specified description. | 117 | * Generates a new topology snapshot from the specified description. |
117 | * | 118 | * |
119 | + * @param providerId provider identification | ||
118 | * @param topoDescription topology description | 120 | * @param topoDescription topology description |
119 | * @param reasons list of events that triggered the update | 121 | * @param reasons list of events that triggered the update |
120 | * @return topology update event or null if the description is old | 122 | * @return topology update event or null if the description is old |
121 | */ | 123 | */ |
122 | - TopologyEvent updateTopology(TopologyDescription topoDescription, | 124 | + TopologyEvent updateTopology(ProviderId providerId, |
125 | + TopologyDescription topoDescription, | ||
123 | List<Event> reasons) { | 126 | List<Event> reasons) { |
124 | - return null; | 127 | + // First off, make sure that what we're given is indeed newer than |
128 | + // what we already have. | ||
129 | + if (current != null && topoDescription.timestamp() < current.time()) { | ||
130 | + return null; | ||
131 | + } | ||
132 | + | ||
133 | + // Have the default topology construct self from the description data. | ||
134 | + DefaultTopology newTopology = | ||
135 | + new DefaultTopology(providerId, topoDescription); | ||
136 | + | ||
137 | + // Promote the new topology to current and return a ready-to-send event. | ||
138 | + current = newTopology; | ||
139 | + return new TopologyEvent(TopologyEvent.Type.TOPOLOGY_CHANGED, current); | ||
125 | } | 140 | } |
126 | 141 | ||
127 | } | 142 | } | ... | ... |
1 | package org.onlab.onos.net.trivial.topology.provider.impl; | 1 | package org.onlab.onos.net.trivial.topology.provider.impl; |
2 | 2 | ||
3 | +import com.google.common.collect.ImmutableMap; | ||
3 | import com.google.common.collect.ImmutableSet; | 4 | import com.google.common.collect.ImmutableSet; |
4 | import com.google.common.collect.ImmutableSetMultimap; | 5 | import com.google.common.collect.ImmutableSetMultimap; |
5 | import com.google.common.collect.Maps; | 6 | import com.google.common.collect.Maps; |
... | @@ -26,6 +27,7 @@ import java.util.Map; | ... | @@ -26,6 +27,7 @@ import java.util.Map; |
26 | import java.util.Set; | 27 | import java.util.Set; |
27 | 28 | ||
28 | import static com.google.common.collect.ImmutableSetMultimap.Builder; | 29 | import static com.google.common.collect.ImmutableSetMultimap.Builder; |
30 | +import static com.google.common.collect.ImmutableSetMultimap.builder; | ||
29 | import static org.onlab.graph.GraphPathSearch.Result; | 31 | import static org.onlab.graph.GraphPathSearch.Result; |
30 | import static org.onlab.graph.TarjanGraphSearch.SCCResult; | 32 | import static org.onlab.graph.TarjanGraphSearch.SCCResult; |
31 | import static org.onlab.onos.net.Link.Type.INDIRECT; | 33 | import static org.onlab.onos.net.Link.Type.INDIRECT; |
... | @@ -43,13 +45,12 @@ class DefaultTopologyDescription implements TopologyDescription { | ... | @@ -43,13 +45,12 @@ class DefaultTopologyDescription implements TopologyDescription { |
43 | private final long nanos; | 45 | private final long nanos; |
44 | private final Map<DeviceId, TopoVertex> vertexesById = Maps.newHashMap(); | 46 | private final Map<DeviceId, TopoVertex> vertexesById = Maps.newHashMap(); |
45 | private final Graph<TopoVertex, TopoEdge> graph; | 47 | private final Graph<TopoVertex, TopoEdge> graph; |
46 | - private final Map<DeviceId, Result<TopoVertex, TopoEdge>> results; | 48 | + private final ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> results; |
47 | - private final Map<ClusterId, TopologyCluster> clusters; | ||
48 | 49 | ||
49 | - // Secondary look-up indexes | 50 | + // Cluster-related structures |
50 | - private ImmutableSetMultimap<ClusterId, DeviceId> devicesByCluster; | 51 | + private final ImmutableSet<TopologyCluster> clusters; |
51 | - private ImmutableSetMultimap<ClusterId, Link> linksByCluster; | 52 | + private ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster; |
52 | - private Map<DeviceId, TopologyCluster> clustersByDevice = Maps.newHashMap(); | 53 | + private ImmutableSetMultimap<TopologyCluster, Link> linksByCluster; |
53 | 54 | ||
54 | /** | 55 | /** |
55 | * Creates a topology description to carry topology vitals to the core. | 56 | * Creates a topology description to carry topology vitals to the core. |
... | @@ -76,31 +77,25 @@ class DefaultTopologyDescription implements TopologyDescription { | ... | @@ -76,31 +77,25 @@ class DefaultTopologyDescription implements TopologyDescription { |
76 | } | 77 | } |
77 | 78 | ||
78 | @Override | 79 | @Override |
79 | - public Result<TopoVertex, TopoEdge> pathResults(DeviceId srcDeviceId) { | 80 | + public ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> pathsBySource() { |
80 | - return results.get(srcDeviceId); | 81 | + return results; |
81 | - } | ||
82 | - | ||
83 | - @Override | ||
84 | - public Set<TopologyCluster> clusters() { | ||
85 | - return ImmutableSet.copyOf(clusters.values()); | ||
86 | } | 82 | } |
87 | 83 | ||
88 | @Override | 84 | @Override |
89 | - public Set<DeviceId> clusterDevices(TopologyCluster cluster) { | 85 | + public ImmutableSet<TopologyCluster> clusters() { |
90 | - return devicesByCluster.get(cluster.id()); | 86 | + return clusters; |
91 | } | 87 | } |
92 | 88 | ||
93 | @Override | 89 | @Override |
94 | - public Set<Link> clusterLinks(TopologyCluster cluster) { | 90 | + public ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster() { |
95 | - return linksByCluster.get(cluster.id()); | 91 | + return devicesByCluster; |
96 | } | 92 | } |
97 | 93 | ||
98 | @Override | 94 | @Override |
99 | - public TopologyCluster clusterFor(DeviceId deviceId) { | 95 | + public ImmutableSetMultimap<TopologyCluster, Link> linksByCluster() { |
100 | - return clustersByDevice.get(deviceId); | 96 | + return linksByCluster; |
101 | } | 97 | } |
102 | 98 | ||
103 | - | ||
104 | // Link weight for measuring link cost as hop count with indirect links | 99 | // Link weight for measuring link cost as hop count with indirect links |
105 | // being as expensive as traversing the entire graph to assume the worst. | 100 | // being as expensive as traversing the entire graph to assume the worst. |
106 | private static class HopCountLinkWeight implements LinkWeight { | 101 | private static class HopCountLinkWeight implements LinkWeight { |
... | @@ -156,29 +151,31 @@ class DefaultTopologyDescription implements TopologyDescription { | ... | @@ -156,29 +151,31 @@ class DefaultTopologyDescription implements TopologyDescription { |
156 | 151 | ||
157 | // Computes the default shortest paths for all source/dest pairs using | 152 | // Computes the default shortest paths for all source/dest pairs using |
158 | // the multi-path Dijkstra and hop-count as path cost. | 153 | // the multi-path Dijkstra and hop-count as path cost. |
159 | - private Map<DeviceId, Result<TopoVertex, TopoEdge>> computeDefaultPaths() { | 154 | + private ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> computeDefaultPaths() { |
160 | LinkWeight weight = new HopCountLinkWeight(graph.getVertexes().size()); | 155 | LinkWeight weight = new HopCountLinkWeight(graph.getVertexes().size()); |
161 | - Map<DeviceId, Result<TopoVertex, TopoEdge>> results = Maps.newHashMap(); | 156 | + ImmutableMap.Builder<DeviceId, Result<TopoVertex, TopoEdge>> results = |
157 | + ImmutableMap.builder(); | ||
162 | 158 | ||
163 | // Search graph paths for each source to all destinations. | 159 | // Search graph paths for each source to all destinations. |
164 | for (TopoVertex src : vertexesById.values()) { | 160 | for (TopoVertex src : vertexesById.values()) { |
165 | results.put(src.deviceId(), DIJKSTRA.search(graph, src, null, weight)); | 161 | results.put(src.deviceId(), DIJKSTRA.search(graph, src, null, weight)); |
166 | } | 162 | } |
167 | - return results; | 163 | + return results.build(); |
168 | } | 164 | } |
169 | 165 | ||
170 | // Computes topology SCC clusters using Tarjan algorithm. | 166 | // Computes topology SCC clusters using Tarjan algorithm. |
171 | - private Map<ClusterId, TopologyCluster> computeClusters() { | 167 | + private ImmutableSet<TopologyCluster> computeClusters() { |
172 | - Map<ClusterId, TopologyCluster> clusters = Maps.newHashMap(); | 168 | + ImmutableSet.Builder<TopologyCluster> clusterBuilder = ImmutableSet.builder(); |
173 | - SCCResult<TopoVertex, TopoEdge> result = TARJAN.search(graph, new NoIndirectLinksWeight()); | 169 | + SCCResult<TopoVertex, TopoEdge> result = |
170 | + TARJAN.search(graph, new NoIndirectLinksWeight()); | ||
174 | 171 | ||
175 | // Extract both vertexes and edges from the results; the lists form | 172 | // Extract both vertexes and edges from the results; the lists form |
176 | // pairs along the same index. | 173 | // pairs along the same index. |
177 | List<Set<TopoVertex>> clusterVertexes = result.clusterVertexes(); | 174 | List<Set<TopoVertex>> clusterVertexes = result.clusterVertexes(); |
178 | List<Set<TopoEdge>> clusterEdges = result.clusterEdges(); | 175 | List<Set<TopoEdge>> clusterEdges = result.clusterEdges(); |
179 | 176 | ||
180 | - Builder<ClusterId, DeviceId> devicesBuilder = ImmutableSetMultimap.builder(); | 177 | + Builder<TopologyCluster, DeviceId> devicesBuilder = ImmutableSetMultimap.builder(); |
181 | - Builder<ClusterId, Link> linksBuilder = ImmutableSetMultimap.builder(); | 178 | + Builder<TopologyCluster, Link> linksBuilder = ImmutableSetMultimap.builder(); |
182 | 179 | ||
183 | // Scan over the lists and create a cluster from the results. | 180 | // Scan over the lists and create a cluster from the results. |
184 | for (int i = 0, n = result.clusterCount(); i < n; i++) { | 181 | for (int i = 0, n = result.clusterCount(); i < n; i++) { |
... | @@ -189,10 +186,11 @@ class DefaultTopologyDescription implements TopologyDescription { | ... | @@ -189,10 +186,11 @@ class DefaultTopologyDescription implements TopologyDescription { |
189 | new DefaultTopologyCluster(ClusterId.clusterId(i), | 186 | new DefaultTopologyCluster(ClusterId.clusterId(i), |
190 | vertexSet.size(), edgeSet.size(), | 187 | vertexSet.size(), edgeSet.size(), |
191 | findRoot(vertexSet).deviceId()); | 188 | findRoot(vertexSet).deviceId()); |
189 | + clusterBuilder.add(cluster); | ||
192 | findClusterDevices(vertexSet, cluster, devicesBuilder); | 190 | findClusterDevices(vertexSet, cluster, devicesBuilder); |
193 | findClusterLinks(edgeSet, cluster, linksBuilder); | 191 | findClusterLinks(edgeSet, cluster, linksBuilder); |
194 | } | 192 | } |
195 | - return clusters; | 193 | + return clusterBuilder.build(); |
196 | } | 194 | } |
197 | 195 | ||
198 | // Scans through the set of cluster vertexes and puts their devices in a | 196 | // Scans through the set of cluster vertexes and puts their devices in a |
... | @@ -200,11 +198,10 @@ class DefaultTopologyDescription implements TopologyDescription { | ... | @@ -200,11 +198,10 @@ class DefaultTopologyDescription implements TopologyDescription { |
200 | // the cluster. | 198 | // the cluster. |
201 | private void findClusterDevices(Set<TopoVertex> vertexSet, | 199 | private void findClusterDevices(Set<TopoVertex> vertexSet, |
202 | DefaultTopologyCluster cluster, | 200 | DefaultTopologyCluster cluster, |
203 | - Builder<ClusterId, DeviceId> builder) { | 201 | + Builder<TopologyCluster, DeviceId> builder) { |
204 | for (TopoVertex vertex : vertexSet) { | 202 | for (TopoVertex vertex : vertexSet) { |
205 | DeviceId deviceId = vertex.deviceId(); | 203 | DeviceId deviceId = vertex.deviceId(); |
206 | - builder.put(cluster.id(), deviceId); | 204 | + builder.put(cluster, deviceId); |
207 | - clustersByDevice.put(deviceId, cluster); | ||
208 | } | 205 | } |
209 | } | 206 | } |
210 | 207 | ||
... | @@ -212,9 +209,9 @@ class DefaultTopologyDescription implements TopologyDescription { | ... | @@ -212,9 +209,9 @@ class DefaultTopologyDescription implements TopologyDescription { |
212 | // multi-map associated with the cluster. | 209 | // multi-map associated with the cluster. |
213 | private void findClusterLinks(Set<TopoEdge> edgeSet, | 210 | private void findClusterLinks(Set<TopoEdge> edgeSet, |
214 | DefaultTopologyCluster cluster, | 211 | DefaultTopologyCluster cluster, |
215 | - Builder<ClusterId, Link> builder) { | 212 | + Builder<TopologyCluster, Link> builder) { |
216 | for (TopoEdge edge : edgeSet) { | 213 | for (TopoEdge edge : edgeSet) { |
217 | - builder.put(cluster.id(), edge.link()); | 214 | + builder.put(cluster, edge.link()); |
218 | } | 215 | } |
219 | } | 216 | } |
220 | 217 | ... | ... |
... | @@ -90,6 +90,8 @@ public class SimpleTopologyProvider extends AbstractProvider | ... | @@ -90,6 +90,8 @@ public class SimpleTopologyProvider extends AbstractProvider |
90 | 90 | ||
91 | @Deactivate | 91 | @Deactivate |
92 | public synchronized void deactivate() { | 92 | public synchronized void deactivate() { |
93 | + isStarted = false; | ||
94 | + | ||
93 | deviceService.removeListener(deviceListener); | 95 | deviceService.removeListener(deviceListener); |
94 | linkService.removeListener(linkListener); | 96 | linkService.removeListener(linkListener); |
95 | providerRegistry.unregister(this); | 97 | providerRegistry.unregister(this); |
... | @@ -98,7 +100,6 @@ public class SimpleTopologyProvider extends AbstractProvider | ... | @@ -98,7 +100,6 @@ public class SimpleTopologyProvider extends AbstractProvider |
98 | executor.shutdownNow(); | 100 | executor.shutdownNow(); |
99 | executor = null; | 101 | executor = null; |
100 | 102 | ||
101 | - isStarted = false; | ||
102 | log.info("Stopped"); | 103 | log.info("Stopped"); |
103 | } | 104 | } |
104 | 105 | ||
... | @@ -108,7 +109,7 @@ public class SimpleTopologyProvider extends AbstractProvider | ... | @@ -108,7 +109,7 @@ public class SimpleTopologyProvider extends AbstractProvider |
108 | * | 109 | * |
109 | * @param reasons events which triggered the topology change | 110 | * @param reasons events which triggered the topology change |
110 | */ | 111 | */ |
111 | - private void triggerTopologyBuild(List<Event> reasons) { | 112 | + private synchronized void triggerTopologyBuild(List<Event> reasons) { |
112 | executor.execute(new TopologyBuilderTask(reasons)); | 113 | executor.execute(new TopologyBuilderTask(reasons)); |
113 | } | 114 | } |
114 | 115 | ... | ... |
-
Please register or login to post a comment