Ayaka Koshibe

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

Showing 40 changed files with 749 additions and 468 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.net;
2 +
3 +import com.google.common.collect.Lists;
4 +import org.apache.karaf.shell.commands.Argument;
5 +import org.apache.karaf.shell.commands.Command;
6 +import org.onlab.onos.net.DeviceId;
7 +import org.onlab.onos.net.topology.TopologyCluster;
8 +
9 +import java.util.Collections;
10 +import java.util.Comparator;
11 +import java.util.List;
12 +
13 +import static org.onlab.onos.net.topology.ClusterId.clusterId;
14 +
15 +/**
16 + * Lists devices of the specified topology cluster in the current topology.
17 + */
18 +@Command(scope = "onos", name = "cluster-devices",
19 + description = "Lists devices of the specified topology cluster in the current topology")
20 +public class ClusterDevicesCommand extends ClustersListCommand {
21 +
22 + @Argument(index = 0, name = "id", description = "Cluster ID",
23 + required = false, multiValued = false)
24 + String id = null;
25 +
26 + protected static final Comparator<DeviceId> ID_COMPARATOR = new Comparator<DeviceId>() {
27 + @Override
28 + public int compare(DeviceId id1, DeviceId id2) {
29 + return id1.uri().toString().compareTo(id2.uri().toString());
30 + }
31 + };
32 +
33 + @Override
34 + protected Object doExecute() throws Exception {
35 + int cid = Integer.parseInt(id);
36 + init();
37 + TopologyCluster cluster = service.getCluster(topology, clusterId(cid));
38 + List<DeviceId> ids = Lists.newArrayList(service.getClusterDevices(topology, cluster));
39 + Collections.sort(ids, ID_COMPARATOR);
40 + for (DeviceId deviceId : ids) {
41 + print("%s", deviceId);
42 + }
43 + return null;
44 + }
45 +
46 +
47 +}
1 -package org.onlab.onos.cli; 1 +package org.onlab.onos.cli.net;
2 2
3 import org.apache.karaf.shell.console.Completer; 3 import org.apache.karaf.shell.console.Completer;
4 import org.apache.karaf.shell.console.completer.StringsCompleter; 4 import org.apache.karaf.shell.console.completer.StringsCompleter;
5 -import org.onlab.onos.GreetService; 5 +import org.onlab.onos.cli.AbstractShellCommand;
6 +import org.onlab.onos.net.topology.Topology;
7 +import org.onlab.onos.net.topology.TopologyCluster;
8 +import org.onlab.onos.net.topology.TopologyService;
6 9
7 -import java.util.Iterator;
8 import java.util.List; 10 import java.util.List;
9 import java.util.SortedSet; 11 import java.util.SortedSet;
10 12
11 /** 13 /**
12 - * Simple example of a command-line parameter completer. 14 + * Cluster ID completer.
13 - * For a more open-ended sets a more efficient implementation would be required.
14 */ 15 */
15 -public class NameCompleter implements Completer { 16 +public class ClusterIdCompleter implements Completer {
16 @Override 17 @Override
17 public int complete(String buffer, int cursor, List<String> candidates) { 18 public int complete(String buffer, int cursor, List<String> candidates) {
18 // Delegate string completer 19 // Delegate string completer
19 StringsCompleter delegate = new StringsCompleter(); 20 StringsCompleter delegate = new StringsCompleter();
20 21
21 // Fetch our service and feed it's offerings to the string completer 22 // Fetch our service and feed it's offerings to the string completer
22 - GreetService greetService = AbstractShellCommand.get(GreetService.class); 23 + TopologyService service = AbstractShellCommand.get(TopologyService.class);
23 - Iterator<String> it = greetService.names().iterator(); 24 + Topology topology = service.currentTopology();
25 +
24 SortedSet<String> strings = delegate.getStrings(); 26 SortedSet<String> strings = delegate.getStrings();
25 - while (it.hasNext()) { 27 + for (TopologyCluster cluster : service.getClusters(topology)) {
26 - strings.add(it.next()); 28 + strings.add(Integer.toString(cluster.id().index()));
27 } 29 }
28 30
29 // Now let the completer do the work for figuring out what to offer. 31 // Now let the completer do the work for figuring out what to offer.
......
1 +package org.onlab.onos.cli.net;
2 +
3 +import org.apache.karaf.shell.commands.Argument;
4 +import org.apache.karaf.shell.commands.Command;
5 +import org.onlab.onos.net.Link;
6 +import org.onlab.onos.net.topology.TopologyCluster;
7 +
8 +import static org.onlab.onos.cli.net.LinksListCommand.linkString;
9 +import static org.onlab.onos.net.topology.ClusterId.clusterId;
10 +
11 +/**
12 + * Lists links of the specified topology cluster in the current topology.
13 + */
14 +@Command(scope = "onos", name = "cluster-links",
15 + description = "Lists links of the specified topology cluster in the current topology")
16 +public class ClusterLinksCommand extends ClustersListCommand {
17 +
18 + @Argument(index = 0, name = "id", description = "Cluster ID",
19 + required = false, multiValued = false)
20 + String id = null;
21 +
22 + @Override
23 + protected Object doExecute() throws Exception {
24 + int cid = Integer.parseInt(id);
25 + init();
26 + TopologyCluster cluster = service.getCluster(topology, clusterId(cid));
27 + for (Link link : service.getClusterLinks(topology, cluster)) {
28 + print(linkString(link));
29 + }
30 + return null;
31 + }
32 +
33 +
34 +}
1 +package org.onlab.onos.cli.net;
2 +
3 +import com.google.common.collect.Lists;
4 +import org.apache.karaf.shell.commands.Command;
5 +import org.onlab.onos.net.topology.TopologyCluster;
6 +
7 +import java.util.Collections;
8 +import java.util.Comparator;
9 +import java.util.List;
10 +
11 +/**
12 + * Lists all clusters in the current topology.
13 + */
14 +@Command(scope = "onos", name = "clusters",
15 + description = "Lists all clusters in the current topology")
16 +public class ClustersListCommand extends TopologyCommand {
17 +
18 + private static final String FMT =
19 + "id=%s, devices=%d, links=%d";
20 +
21 + protected static final Comparator<TopologyCluster> ID_COMPARATOR =
22 + new Comparator<TopologyCluster>() {
23 + @Override
24 + public int compare(TopologyCluster c1, TopologyCluster c2) {
25 + return c1.id().index() - c2.id().index();
26 + }
27 + };
28 +
29 + @Override
30 + protected Object doExecute() throws Exception {
31 + init();
32 + List<TopologyCluster> clusters = Lists.newArrayList(service.getClusters(topology));
33 + Collections.sort(clusters, ID_COMPARATOR);
34 +
35 + for (TopologyCluster cluster : clusters) {
36 + print(FMT, cluster.id(), cluster.deviceCount(), cluster.linkCount());
37 + }
38 + return null;
39 + }
40 +
41 +}
...@@ -27,9 +27,20 @@ public class LinksListCommand extends AbstractShellCommand { ...@@ -27,9 +27,20 @@ public class LinksListCommand extends AbstractShellCommand {
27 Iterable<Link> links = uri != null ? 27 Iterable<Link> links = uri != null ?
28 service.getDeviceLinks(deviceId(uri)) : service.getLinks(); 28 service.getDeviceLinks(deviceId(uri)) : service.getLinks();
29 for (Link link : links) { 29 for (Link link : links) {
30 - print(FMT, link.src().deviceId(), link.src().port(), 30 + print(linkString(link));
31 - link.dst().deviceId(), link.dst().port(), link.type());
32 } 31 }
33 return null; 32 return null;
34 } 33 }
34 +
35 + /**
36 + * Returns a formated string representing the gien link.
37 + *
38 + * @param link infrastructure link
39 + * @return formated link string
40 + */
41 + public static String linkString(Link link) {
42 + return String.format(FMT, link.src().deviceId(), link.src().port(),
43 + link.dst().deviceId(), link.dst().port(), link.type());
44 +
45 + }
35 } 46 }
......
1 +package org.onlab.onos.cli.net;
2 +
3 +import org.apache.karaf.shell.commands.Command;
4 +import org.onlab.onos.cli.AbstractShellCommand;
5 +import org.onlab.onos.net.topology.Topology;
6 +import org.onlab.onos.net.topology.TopologyService;
7 +
8 +/**
9 + * Lists summary of the current topology.
10 + */
11 +@Command(scope = "onos", name = "topology",
12 + description = "Lists summary of the current topology")
13 +public class TopologyCommand extends AbstractShellCommand {
14 +
15 + private static final String FMT =
16 + "time=%s, devices=%d, links=%d, clusters=%d, paths=%d";
17 +
18 + protected TopologyService service;
19 + protected Topology topology;
20 +
21 + /**
22 + * Initializes the context for all cluster commands.
23 + */
24 + protected void init() {
25 + service = getService(TopologyService.class);
26 + topology = service.currentTopology();
27 + }
28 +
29 + @Override
30 + protected Object doExecute() throws Exception {
31 + init();
32 + print(FMT, topology.time(), topology.deviceCount(), topology.linkCount(),
33 + topology.clusterCount(), topology.pathCount());
34 + return null;
35 + }
36 +
37 +}
...@@ -32,16 +32,27 @@ ...@@ -32,16 +32,27 @@
32 </command> 32 </command>
33 33
34 <command> 34 <command>
35 - <action class="org.onlab.onos.cli.GreetCommand"/> 35 + <action class="org.onlab.onos.cli.net.TopologyCommand"/>
36 + </command>
37 + <command>
38 + <action class="org.onlab.onos.cli.net.ClustersListCommand"/>
39 + </command>
40 + <command>
41 + <action class="org.onlab.onos.cli.net.ClusterDevicesCommand"/>
36 <completers> 42 <completers>
37 - <ref component-id="nameCompleter"/> 43 + <ref component-id="clusterIdCompleter"/>
44 + </completers>
45 + </command>
46 + <command>
47 + <action class="org.onlab.onos.cli.net.ClusterLinksCommand"/>
48 + <completers>
49 + <ref component-id="clusterIdCompleter"/>
38 </completers> 50 </completers>
39 </command> 51 </command>
40 </command-bundle> 52 </command-bundle>
41 53
42 <bean id="deviceIdCompleter" class="org.onlab.onos.cli.net.DeviceIdCompleter"/> 54 <bean id="deviceIdCompleter" class="org.onlab.onos.cli.net.DeviceIdCompleter"/>
55 + <bean id="clusterIdCompleter" class="org.onlab.onos.cli.net.ClusterIdCompleter"/>
43 <bean id="roleCompleter" class="org.onlab.onos.cli.net.RoleCompleter"/> 56 <bean id="roleCompleter" class="org.onlab.onos.cli.net.RoleCompleter"/>
44 57
45 - <bean id="nameCompleter" class="org.onlab.onos.cli.NameCompleter"/>
46 -
47 </blueprint> 58 </blueprint>
......
...@@ -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 org.onlab.graph.Graph;
4 -import org.onlab.graph.GraphPathSearch;
5 -import org.onlab.onos.net.Description;
6 -import org.onlab.onos.net.DeviceId;
7 -import org.onlab.onos.net.Link;
8 -
9 -import java.util.Set;
10 -
11 -/**
12 - * Describes attribute(s) of a network topology.
13 - */
14 -public interface TopologyDescription extends Description {
15 -
16 - /**
17 - * Returns the creation timestamp of the topology description. This is
18 - * expressed in system nanos to allow proper sequencing.
19 - *
20 - * @return topology description creation timestamp
21 - */
22 - long timestamp();
23 -
24 - /**
25 - * Returns the topology graph.
26 - *
27 - * @return network graph
28 - */
29 - Graph<TopoVertex, TopoEdge> graph();
30 -
31 - /**
32 - * Returns the results of the path search through the network graph. This
33 - * is assumed to contain results of seach fro the given device to all
34 - * other devices.
35 - *
36 - * @param srcDeviceId source device identifier
37 - * @return path search result for the given source node
38 - */
39 - GraphPathSearch.Result pathResults(DeviceId srcDeviceId);
40 -
41 - /**
42 - * Returns the set of topology SCC clusters.
43 - *
44 - * @return set of SCC clusters
45 - */
46 - Set<TopologyCluster> clusters();
47 -
48 - /**
49 - * Returns the set of devices contained by the specified topology cluster.
50 - *
51 - * @return set of devices that belong to the specified cluster
52 - */
53 - Set<DeviceId> clusterDevices(TopologyCluster cluster);
54 -
55 - /**
56 - * Returns the set of infrastructure links contained by the specified cluster.
57 - *
58 - * @return set of links that form the given cluster
59 - */
60 - Set<Link> clusterLinks(TopologyCluster cluster);
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 -
70 -}
71 -
...@@ -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;
5 +import org.onlab.onos.net.Link;
6 import org.onlab.onos.net.Path; 6 import org.onlab.onos.net.Path;
7 7
8 import java.util.Set; 8 import java.util.Set;
...@@ -21,12 +21,21 @@ public interface TopologyService { ...@@ -21,12 +21,21 @@ 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 */
27 boolean isLatest(Topology topology); 28 boolean isLatest(Topology topology);
28 29
29 /** 30 /**
31 + * Returns the graph view of the specified topology.
32 + *
33 + * @param topology topology descriptor
34 + * @return topology graph view
35 + */
36 + TopologyGraph getGraph(Topology topology);
37 +
38 + /**
30 * Returns the set of clusters in the specified topology. 39 * Returns the set of clusters in the specified topology.
31 * 40 *
32 * @param topology topology descriptor 41 * @param topology topology descriptor
...@@ -35,12 +44,31 @@ public interface TopologyService { ...@@ -35,12 +44,31 @@ public interface TopologyService {
35 Set<TopologyCluster> getClusters(Topology topology); 44 Set<TopologyCluster> getClusters(Topology topology);
36 45
37 /** 46 /**
38 - * Returns the graph view of the specified topology. 47 + * Returns the cluster with the specified ID.
39 * 48 *
40 - * @param topology topology descriptor 49 + * @param topology topology descriptor
41 - * @return topology graph view 50 + * @param clusterId cluster identifier
51 + * @return topology cluster
52 + */
53 + TopologyCluster getCluster(Topology topology, ClusterId clusterId);
54 +
55 + /**
56 + * Returns the set of devices that belong to the specified cluster.
57 + *
58 + * @param topology topology descriptor
59 + * @param cluster topology cluster
60 + * @return set of cluster devices
61 + */
62 + Set<DeviceId> getClusterDevices(Topology topology, TopologyCluster cluster);
63 +
64 + /**
65 + * Returns the set of links that form the specified cluster.
66 + *
67 + * @param topology topology descriptor
68 + * @param cluster topology cluster
69 + * @return set of cluster links
42 */ 70 */
43 - Graph<TopoVertex, TopoEdge> getGraph(Topology topology); 71 + Set<Link> getClusterLinks(Topology topology, TopologyCluster cluster);
44 72
45 /** 73 /**
46 * Returns the set of all shortest paths, precomputed in terms of hop-count, 74 * 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.impl; 1 +package org.onlab.onos.net.trivial.host.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.host.impl;
2 +
3 +import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED;
4 +import static org.onlab.onos.net.host.HostEvent.Type.HOST_MOVED;
5 +import static org.onlab.onos.net.host.HostEvent.Type.HOST_REMOVED;
6 +import static org.onlab.onos.net.host.HostEvent.Type.HOST_UPDATED;
7 +
8 +import java.util.Collections;
9 +import java.util.HashSet;
10 +import java.util.Map;
11 +import java.util.Set;
12 +import java.util.concurrent.ConcurrentHashMap;
2 13
3 import org.onlab.onos.net.ConnectPoint; 14 import org.onlab.onos.net.ConnectPoint;
4 import org.onlab.onos.net.DefaultHost; 15 import org.onlab.onos.net.DefaultHost;
...@@ -15,17 +26,6 @@ import com.google.common.collect.HashMultimap; ...@@ -15,17 +26,6 @@ import com.google.common.collect.HashMultimap;
15 import com.google.common.collect.ImmutableSet; 26 import com.google.common.collect.ImmutableSet;
16 import com.google.common.collect.Multimap; 27 import com.google.common.collect.Multimap;
17 28
18 -import java.util.Collections;
19 -import java.util.HashSet;
20 -import java.util.Map;
21 -import java.util.Set;
22 -import java.util.concurrent.ConcurrentHashMap;
23 -
24 -import static org.onlab.onos.net.host.HostEvent.Type.HOST_REMOVED;
25 -import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED;
26 -import static org.onlab.onos.net.host.HostEvent.Type.HOST_UPDATED;
27 -import static org.onlab.onos.net.host.HostEvent.Type.HOST_MOVED;
28 -
29 /** 29 /**
30 * Manages inventory of end-station hosts using trivial in-memory 30 * Manages inventory of end-station hosts using trivial in-memory
31 * implementation. 31 * implementation.
...@@ -36,6 +36,7 @@ public class SimpleHostStore { ...@@ -36,6 +36,7 @@ public class SimpleHostStore {
36 36
37 // hosts sorted based on their location 37 // hosts sorted based on their location
38 private final Multimap<ConnectPoint, Host> locations = HashMultimap.create(); 38 private final Multimap<ConnectPoint, Host> locations = HashMultimap.create();
39 +
39 /** 40 /**
40 * Creates a new host or updates the existing one based on the specified 41 * Creates a new host or updates the existing one based on the specified
41 * description. 42 * description.
...@@ -46,7 +47,7 @@ public class SimpleHostStore { ...@@ -46,7 +47,7 @@ public class SimpleHostStore {
46 * @return appropriate event or null if no change resulted 47 * @return appropriate event or null if no change resulted
47 */ 48 */
48 HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId, 49 HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId,
49 - HostDescription hostDescription) { 50 + HostDescription hostDescription) {
50 Host host = hosts.get(hostId); 51 Host host = hosts.get(hostId);
51 if (host == null) { 52 if (host == null) {
52 return createHost(providerId, hostId, hostDescription); 53 return createHost(providerId, hostId, hostDescription);
......
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;
...@@ -32,10 +32,12 @@ import static org.onlab.util.Tools.namedThreads; ...@@ -32,10 +32,12 @@ import static org.onlab.util.Tools.namedThreads;
32 import static org.slf4j.LoggerFactory.getLogger; 32 import static org.slf4j.LoggerFactory.getLogger;
33 33
34 /** 34 /**
35 - * Simple implementation of a network topology provider/computor. 35 + * Default implementation of a network topology provider that feeds off
36 + * device and link subsystem events to trigger assembly and computation of
37 + * new topology snapshots.
36 */ 38 */
37 @Component(immediate = true) 39 @Component(immediate = true)
38 -public class SimpleTopologyProvider extends AbstractProvider 40 +public class DefaultTopologyProvider extends AbstractProvider
39 implements TopologyProvider { 41 implements TopologyProvider {
40 42
41 // TODO: make these configurable 43 // TODO: make these configurable
...@@ -70,13 +72,13 @@ public class SimpleTopologyProvider extends AbstractProvider ...@@ -70,13 +72,13 @@ public class SimpleTopologyProvider extends AbstractProvider
70 /** 72 /**
71 * Creates a provider with the supplier identifier. 73 * Creates a provider with the supplier identifier.
72 */ 74 */
73 - public SimpleTopologyProvider() { 75 + public DefaultTopologyProvider() {
74 super(new ProviderId("org.onlab.onos.provider.topology")); 76 super(new ProviderId("org.onlab.onos.provider.topology"));
75 } 77 }
76 78
77 @Activate 79 @Activate
78 public synchronized void activate() { 80 public synchronized void activate() {
79 - executor = newFixedThreadPool(MAX_THREADS, namedThreads("topo-compute-%d")); 81 + executor = newFixedThreadPool(MAX_THREADS, namedThreads("topo-build-%d"));
80 accumulator = new TopologyChangeAccumulator(); 82 accumulator = new TopologyChangeAccumulator();
81 83
82 providerService = providerRegistry.register(this); 84 providerService = providerRegistry.register(this);
...@@ -90,6 +92,8 @@ public class SimpleTopologyProvider extends AbstractProvider ...@@ -90,6 +92,8 @@ public class SimpleTopologyProvider extends AbstractProvider
90 92
91 @Deactivate 93 @Deactivate
92 public synchronized void deactivate() { 94 public synchronized void deactivate() {
95 + isStarted = false;
96 +
93 deviceService.removeListener(deviceListener); 97 deviceService.removeListener(deviceListener);
94 linkService.removeListener(linkListener); 98 linkService.removeListener(linkListener);
95 providerRegistry.unregister(this); 99 providerRegistry.unregister(this);
...@@ -98,7 +102,6 @@ public class SimpleTopologyProvider extends AbstractProvider ...@@ -98,7 +102,6 @@ public class SimpleTopologyProvider extends AbstractProvider
98 executor.shutdownNow(); 102 executor.shutdownNow();
99 executor = null; 103 executor = null;
100 104
101 - isStarted = false;
102 log.info("Stopped"); 105 log.info("Stopped");
103 } 106 }
104 107
...@@ -108,18 +111,20 @@ public class SimpleTopologyProvider extends AbstractProvider ...@@ -108,18 +111,20 @@ public class SimpleTopologyProvider extends AbstractProvider
108 * 111 *
109 * @param reasons events which triggered the topology change 112 * @param reasons events which triggered the topology change
110 */ 113 */
111 - private void triggerTopologyBuild(List<Event> reasons) { 114 + private synchronized void triggerTopologyBuild(List<Event> reasons) {
112 - executor.execute(new TopologyBuilderTask(reasons)); 115 + if (executor != null) {
116 + executor.execute(new TopologyBuilderTask(reasons));
117 + }
113 } 118 }
114 119
115 // Builds the topology using the latest device and link information 120 // Builds the topology using the latest device and link information
116 // and citing the specified events as reasons for the change. 121 // and citing the specified events as reasons for the change.
117 private void buildTopology(List<Event> reasons) { 122 private void buildTopology(List<Event> reasons) {
118 if (isStarted) { 123 if (isStarted) {
119 - TopologyDescription desc = 124 + GraphDescription desc =
120 - new DefaultTopologyDescription(System.nanoTime(), 125 + new DefaultGraphDescription(System.nanoTime(),
121 - deviceService.getDevices(), 126 + deviceService.getDevices(),
122 - linkService.getLinks()); 127 + linkService.getLinks());
123 providerService.topologyChanged(desc, reasons); 128 providerService.topologyChanged(desc, reasons);
124 } 129 }
125 } 130 }
......
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 pre-computed paths between source and destination devices.
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,22 +6,22 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -6,22 +6,22 @@ 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;
13 import org.onlab.onos.net.ConnectPoint; 12 import org.onlab.onos.net.ConnectPoint;
14 import org.onlab.onos.net.DeviceId; 13 import org.onlab.onos.net.DeviceId;
14 +import org.onlab.onos.net.Link;
15 import org.onlab.onos.net.Path; 15 import org.onlab.onos.net.Path;
16 import org.onlab.onos.net.provider.AbstractProviderRegistry; 16 import org.onlab.onos.net.provider.AbstractProviderRegistry;
17 import org.onlab.onos.net.provider.AbstractProviderService; 17 import org.onlab.onos.net.provider.AbstractProviderService;
18 +import org.onlab.onos.net.topology.ClusterId;
19 +import org.onlab.onos.net.topology.GraphDescription;
18 import org.onlab.onos.net.topology.LinkWeight; 20 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; 21 import org.onlab.onos.net.topology.Topology;
22 import org.onlab.onos.net.topology.TopologyCluster; 22 import org.onlab.onos.net.topology.TopologyCluster;
23 -import org.onlab.onos.net.topology.TopologyDescription;
24 import org.onlab.onos.net.topology.TopologyEvent; 23 import org.onlab.onos.net.topology.TopologyEvent;
24 +import org.onlab.onos.net.topology.TopologyGraph;
25 import org.onlab.onos.net.topology.TopologyListener; 25 import org.onlab.onos.net.topology.TopologyListener;
26 import org.onlab.onos.net.topology.TopologyProvider; 26 import org.onlab.onos.net.topology.TopologyProvider;
27 import org.onlab.onos.net.topology.TopologyProviderRegistry; 27 import org.onlab.onos.net.topology.TopologyProviderRegistry;
...@@ -46,6 +46,8 @@ public class SimpleTopologyManager ...@@ -46,6 +46,8 @@ public class SimpleTopologyManager
46 46
47 public static final String TOPOLOGY_NULL = "Topology cannot be null"; 47 public static final String TOPOLOGY_NULL = "Topology cannot be null";
48 private static final String DEVICE_ID_NULL = "Device ID cannot be null"; 48 private static final String DEVICE_ID_NULL = "Device ID cannot be null";
49 + private static final String CLUSTER_ID_NULL = "Cluster ID cannot be null";
50 + private static final String CLUSTER_NULL = "Topology cluster cannot be null";
49 public static final String CONNECTION_POINT_NULL = "Connection point cannot be null"; 51 public static final String CONNECTION_POINT_NULL = "Connection point cannot be null";
50 52
51 private final Logger log = getLogger(getClass()); 53 private final Logger log = getLogger(getClass());
...@@ -79,19 +81,49 @@ public class SimpleTopologyManager ...@@ -79,19 +81,49 @@ public class SimpleTopologyManager
79 @Override 81 @Override
80 public boolean isLatest(Topology topology) { 82 public boolean isLatest(Topology topology) {
81 checkNotNull(topology, TOPOLOGY_NULL); 83 checkNotNull(topology, TOPOLOGY_NULL);
82 - return store.isLatest(topology); 84 + return store.isLatest(defaultTopology(topology));
85 + }
86 +
87 + // Validates the specified topology and returns it as a default
88 + private DefaultTopology defaultTopology(Topology topology) {
89 + if (topology instanceof DefaultTopology) {
90 + return (DefaultTopology) topology;
91 + }
92 + throw new IllegalArgumentException("Topology class " + topology.getClass() +
93 + " not supported");
83 } 94 }
84 95
85 @Override 96 @Override
86 public Set<TopologyCluster> getClusters(Topology topology) { 97 public Set<TopologyCluster> getClusters(Topology topology) {
87 checkNotNull(topology, TOPOLOGY_NULL); 98 checkNotNull(topology, TOPOLOGY_NULL);
88 - return store.getClusters(topology); 99 + return store.getClusters(defaultTopology(topology));
100 + }
101 +
102 + @Override
103 + public TopologyCluster getCluster(Topology topology, ClusterId clusterId) {
104 + checkNotNull(topology, TOPOLOGY_NULL);
105 + checkNotNull(topology, CLUSTER_ID_NULL);
106 + return store.getCluster(defaultTopology(topology), clusterId);
107 + }
108 +
109 + @Override
110 + public Set<DeviceId> getClusterDevices(Topology topology, TopologyCluster cluster) {
111 + checkNotNull(topology, TOPOLOGY_NULL);
112 + checkNotNull(topology, CLUSTER_NULL);
113 + return store.getClusterDevices(defaultTopology(topology), cluster);
114 + }
115 +
116 + @Override
117 + public Set<Link> getClusterLinks(Topology topology, TopologyCluster cluster) {
118 + checkNotNull(topology, TOPOLOGY_NULL);
119 + checkNotNull(topology, CLUSTER_NULL);
120 + return store.getClusterLinks(defaultTopology(topology), cluster);
89 } 121 }
90 122
91 @Override 123 @Override
92 - public Graph<TopoVertex, TopoEdge> getGraph(Topology topology) { 124 + public TopologyGraph getGraph(Topology topology) {
93 checkNotNull(topology, TOPOLOGY_NULL); 125 checkNotNull(topology, TOPOLOGY_NULL);
94 - return store.getGraph(topology); 126 + return store.getGraph(defaultTopology(topology));
95 } 127 }
96 128
97 @Override 129 @Override
...@@ -99,7 +131,7 @@ public class SimpleTopologyManager ...@@ -99,7 +131,7 @@ public class SimpleTopologyManager
99 checkNotNull(topology, TOPOLOGY_NULL); 131 checkNotNull(topology, TOPOLOGY_NULL);
100 checkNotNull(src, DEVICE_ID_NULL); 132 checkNotNull(src, DEVICE_ID_NULL);
101 checkNotNull(dst, DEVICE_ID_NULL); 133 checkNotNull(dst, DEVICE_ID_NULL);
102 - return store.getPaths(topology, src, dst); 134 + return store.getPaths(defaultTopology(topology), src, dst);
103 } 135 }
104 136
105 @Override 137 @Override
...@@ -108,21 +140,21 @@ public class SimpleTopologyManager ...@@ -108,21 +140,21 @@ public class SimpleTopologyManager
108 checkNotNull(src, DEVICE_ID_NULL); 140 checkNotNull(src, DEVICE_ID_NULL);
109 checkNotNull(dst, DEVICE_ID_NULL); 141 checkNotNull(dst, DEVICE_ID_NULL);
110 checkNotNull(weight, "Link weight cannot be null"); 142 checkNotNull(weight, "Link weight cannot be null");
111 - return store.getPaths(topology, src, dst, weight); 143 + return store.getPaths(defaultTopology(topology), src, dst, weight);
112 } 144 }
113 145
114 @Override 146 @Override
115 public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) { 147 public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) {
116 checkNotNull(topology, TOPOLOGY_NULL); 148 checkNotNull(topology, TOPOLOGY_NULL);
117 checkNotNull(connectPoint, CONNECTION_POINT_NULL); 149 checkNotNull(connectPoint, CONNECTION_POINT_NULL);
118 - return store.isInfrastructure(topology, connectPoint); 150 + return store.isInfrastructure(defaultTopology(topology), connectPoint);
119 } 151 }
120 152
121 @Override 153 @Override
122 public boolean isInBroadcastTree(Topology topology, ConnectPoint connectPoint) { 154 public boolean isInBroadcastTree(Topology topology, ConnectPoint connectPoint) {
123 checkNotNull(topology, TOPOLOGY_NULL); 155 checkNotNull(topology, TOPOLOGY_NULL);
124 checkNotNull(connectPoint, CONNECTION_POINT_NULL); 156 checkNotNull(connectPoint, CONNECTION_POINT_NULL);
125 - return store.isInBroadcastTree(topology, connectPoint); 157 + return store.isInBroadcastTree(defaultTopology(topology), connectPoint);
126 } 158 }
127 159
128 @Override 160 @Override
...@@ -150,15 +182,14 @@ public class SimpleTopologyManager ...@@ -150,15 +182,14 @@ public class SimpleTopologyManager
150 } 182 }
151 183
152 @Override 184 @Override
153 - public void topologyChanged(TopologyDescription topoDescription, 185 + public void topologyChanged(GraphDescription topoDescription,
154 List<Event> reasons) { 186 List<Event> reasons) {
155 checkNotNull(topoDescription, "Topology description cannot be null"); 187 checkNotNull(topoDescription, "Topology description cannot be null");
156 188
157 - log.info("Topology changed due to: {}", // to be removed soon 189 + TopologyEvent event = store.updateTopology(provider().id(),
158 - reasons == null ? "initial compute" : reasons); 190 + topoDescription, reasons);
159 - TopologyEvent event = store.updateTopology(topoDescription, reasons);
160 if (event != null) { 191 if (event != null) {
161 - log.info("Topology changed due to: {}", 192 + log.info("Topology {} changed due to: {}", event.subject(),
162 reasons == null ? "initial compute" : reasons); 193 reasons == null ? "initial compute" : reasons);
163 eventDispatcher.post(event); 194 eventDispatcher.post(event);
164 } 195 }
......
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;
6 +import org.onlab.onos.net.Link;
7 import org.onlab.onos.net.Path; 7 import org.onlab.onos.net.Path;
8 +import org.onlab.onos.net.provider.ProviderId;
9 +import org.onlab.onos.net.topology.ClusterId;
10 +import org.onlab.onos.net.topology.GraphDescription;
8 import org.onlab.onos.net.topology.LinkWeight; 11 import org.onlab.onos.net.topology.LinkWeight;
9 -import org.onlab.onos.net.topology.TopoEdge;
10 -import org.onlab.onos.net.topology.TopoVertex;
11 import org.onlab.onos.net.topology.Topology; 12 import org.onlab.onos.net.topology.Topology;
12 import org.onlab.onos.net.topology.TopologyCluster; 13 import org.onlab.onos.net.topology.TopologyCluster;
13 -import org.onlab.onos.net.topology.TopologyDescription;
14 import org.onlab.onos.net.topology.TopologyEvent; 14 import org.onlab.onos.net.topology.TopologyEvent;
15 +import org.onlab.onos.net.topology.TopologyGraph;
15 16
16 import java.util.List; 17 import java.util.List;
17 import java.util.Set; 18 import java.util.Set;
...@@ -45,23 +46,56 @@ class SimpleTopologyStore { ...@@ -45,23 +46,56 @@ class SimpleTopologyStore {
45 } 46 }
46 47
47 /** 48 /**
49 + * Returns the immutable graph view of the current topology.
50 + *
51 + * @param topology topology descriptor
52 + * @return graph view
53 + */
54 + TopologyGraph getGraph(DefaultTopology topology) {
55 + return topology.getGraph();
56 + }
57 +
58 + /**
48 * Returns the set of topology SCC clusters. 59 * Returns the set of topology SCC clusters.
49 * 60 *
50 * @param topology topology descriptor 61 * @param topology topology descriptor
51 * @return set of clusters 62 * @return set of clusters
52 */ 63 */
53 - Set<TopologyCluster> getClusters(Topology topology) { 64 + Set<TopologyCluster> getClusters(DefaultTopology topology) {
54 - return null; 65 + return topology.getClusters();
55 } 66 }
56 67
57 /** 68 /**
58 - * Returns the immutable graph view of the current topology. 69 + * Returns the cluster of the specified topology.
59 * 70 *
60 - * @param topology topology descriptor 71 + * @param topology topology descriptor
61 - * @return graph view 72 + * @param clusterId cluster identity
73 + * @return topology cluster
62 */ 74 */
63 - Graph<TopoVertex, TopoEdge> getGraph(Topology topology) { 75 + TopologyCluster getCluster(DefaultTopology topology, ClusterId clusterId) {
64 - return null; 76 + return topology.getCluster(clusterId);
77 + }
78 +
79 + /**
80 + * Returns the cluster of the specified topology.
81 + *
82 + * @param topology topology descriptor
83 + * @param cluster topology cluster
84 + * @return set of cluster links
85 + */
86 + Set<DeviceId> getClusterDevices(DefaultTopology topology, TopologyCluster cluster) {
87 + return topology.getClusterDevices(cluster);
88 + }
89 +
90 + /**
91 + * Returns the cluster of the specified topology.
92 + *
93 + * @param topology topology descriptor
94 + * @param cluster topology cluster
95 + * @return set of cluster links
96 + */
97 + Set<Link> getClusterLinks(DefaultTopology topology, TopologyCluster cluster) {
98 + return topology.getClusterLinks(cluster);
65 } 99 }
66 100
67 /** 101 /**
...@@ -72,8 +106,8 @@ class SimpleTopologyStore { ...@@ -72,8 +106,8 @@ class SimpleTopologyStore {
72 * @param dst destination device 106 * @param dst destination device
73 * @return set of shortest paths 107 * @return set of shortest paths
74 */ 108 */
75 - Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) { 109 + Set<Path> getPaths(DefaultTopology topology, DeviceId src, DeviceId dst) {
76 - return null; 110 + return topology.getPaths(src, dst);
77 } 111 }
78 112
79 /** 113 /**
...@@ -85,9 +119,9 @@ class SimpleTopologyStore { ...@@ -85,9 +119,9 @@ class SimpleTopologyStore {
85 * @param weight link weight function 119 * @param weight link weight function
86 * @return set of shortest paths 120 * @return set of shortest paths
87 */ 121 */
88 - Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, 122 + Set<Path> getPaths(DefaultTopology topology, DeviceId src, DeviceId dst,
89 LinkWeight weight) { 123 LinkWeight weight) {
90 - return null; 124 + return topology.getPaths(src, dst, weight);
91 } 125 }
92 126
93 /** 127 /**
...@@ -97,8 +131,8 @@ class SimpleTopologyStore { ...@@ -97,8 +131,8 @@ class SimpleTopologyStore {
97 * @param connectPoint connection point 131 * @param connectPoint connection point
98 * @return true if infrastructure; false otherwise 132 * @return true if infrastructure; false otherwise
99 */ 133 */
100 - boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) { 134 + boolean isInfrastructure(DefaultTopology topology, ConnectPoint connectPoint) {
101 - return false; 135 + return topology.isInfrastructure(connectPoint);
102 } 136 }
103 137
104 /** 138 /**
...@@ -108,20 +142,36 @@ class SimpleTopologyStore { ...@@ -108,20 +142,36 @@ class SimpleTopologyStore {
108 * @param connectPoint connection point 142 * @param connectPoint connection point
109 * @return true if in broadcast tree; false otherwise 143 * @return true if in broadcast tree; false otherwise
110 */ 144 */
111 - boolean isInBroadcastTree(Topology topology, ConnectPoint connectPoint) { 145 + boolean isInBroadcastTree(DefaultTopology topology, ConnectPoint connectPoint) {
112 - return false; 146 + return topology.isInBroadcastTree(connectPoint);
113 } 147 }
114 148
115 /** 149 /**
116 * Generates a new topology snapshot from the specified description. 150 * Generates a new topology snapshot from the specified description.
117 * 151 *
118 - * @param topoDescription topology description 152 + * @param providerId provider identification
119 - * @param reasons list of events that triggered the update 153 + * @param graphDescription topology graph description
154 + * @param reasons list of events that triggered the update
120 * @return topology update event or null if the description is old 155 * @return topology update event or null if the description is old
121 */ 156 */
122 - TopologyEvent updateTopology(TopologyDescription topoDescription, 157 + TopologyEvent updateTopology(ProviderId providerId,
158 + GraphDescription graphDescription,
123 List<Event> reasons) { 159 List<Event> reasons) {
124 - return null; 160 + // First off, make sure that what we're given is indeed newer than
161 + // what we already have.
162 + if (current != null && graphDescription.timestamp() < current.time()) {
163 + return null;
164 + }
165 +
166 + // Have the default topology construct self from the description data.
167 + DefaultTopology newTopology =
168 + new DefaultTopology(providerId, graphDescription);
169 +
170 + // Promote the new topology to current and return a ready-to-send event.
171 + synchronized (this) {
172 + current = newTopology;
173 + return new TopologyEvent(TopologyEvent.Type.TOPOLOGY_CHANGED, current);
174 + }
125 } 175 }
126 176
127 } 177 }
......
1 -package org.onlab.onos.net.trivial.topology.provider.impl;
2 -
3 -import com.google.common.collect.ImmutableSet;
4 -import com.google.common.collect.ImmutableSetMultimap;
5 -import com.google.common.collect.Maps;
6 -import com.google.common.collect.Sets;
7 -import org.onlab.graph.AdjacencyListsGraph;
8 -import org.onlab.graph.DijkstraGraphSearch;
9 -import org.onlab.graph.Graph;
10 -import org.onlab.graph.GraphPathSearch;
11 -import org.onlab.graph.TarjanGraphSearch;
12 -import org.onlab.onos.net.ConnectPoint;
13 -import org.onlab.onos.net.Device;
14 -import org.onlab.onos.net.DeviceId;
15 -import org.onlab.onos.net.Link;
16 -import org.onlab.onos.net.topology.ClusterId;
17 -import org.onlab.onos.net.topology.DefaultTopologyCluster;
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.TopologyCluster;
22 -import org.onlab.onos.net.topology.TopologyDescription;
23 -
24 -import java.util.List;
25 -import java.util.Map;
26 -import java.util.Set;
27 -
28 -import static com.google.common.collect.ImmutableSetMultimap.Builder;
29 -import static org.onlab.graph.GraphPathSearch.Result;
30 -import static org.onlab.graph.TarjanGraphSearch.SCCResult;
31 -import static org.onlab.onos.net.Link.Type.INDIRECT;
32 -
33 -/**
34 - * Default implementation of an immutable topology data carrier.
35 - */
36 -class DefaultTopologyDescription implements TopologyDescription {
37 -
38 - private static final GraphPathSearch<TopoVertex, TopoEdge> DIJKSTRA =
39 - new DijkstraGraphSearch<>();
40 - private static final TarjanGraphSearch<TopoVertex, TopoEdge> TARJAN =
41 - new TarjanGraphSearch<>();
42 -
43 - private final long nanos;
44 - private final Map<DeviceId, TopoVertex> vertexesById = Maps.newHashMap();
45 - private final Graph<TopoVertex, TopoEdge> graph;
46 - private final Map<DeviceId, Result<TopoVertex, TopoEdge>> results;
47 - private final Map<ClusterId, TopologyCluster> clusters;
48 -
49 - // Secondary look-up indexes
50 - private ImmutableSetMultimap<ClusterId, DeviceId> devicesByCluster;
51 - private ImmutableSetMultimap<ClusterId, Link> linksByCluster;
52 - private Map<DeviceId, TopologyCluster> clustersByDevice = Maps.newHashMap();
53 -
54 - /**
55 - * Creates a topology description to carry topology vitals to the core.
56 - *
57 - * @param nanos time in nanos of when the topology description was created
58 - * @param devices collection of infrastructure devices
59 - * @param links collection of infrastructure links
60 - */
61 - DefaultTopologyDescription(long nanos, Iterable<Device> devices, Iterable<Link> links) {
62 - this.nanos = nanos;
63 - this.graph = buildGraph(devices, links);
64 - this.results = computeDefaultPaths();
65 - this.clusters = computeClusters();
66 - }
67 -
68 - @Override
69 - public long timestamp() {
70 - return nanos;
71 - }
72 -
73 - @Override
74 - public Graph<TopoVertex, TopoEdge> graph() {
75 - return graph;
76 - }
77 -
78 - @Override
79 - public Result<TopoVertex, TopoEdge> pathResults(DeviceId srcDeviceId) {
80 - return results.get(srcDeviceId);
81 - }
82 -
83 - @Override
84 - public Set<TopologyCluster> clusters() {
85 - return ImmutableSet.copyOf(clusters.values());
86 - }
87 -
88 - @Override
89 - public Set<DeviceId> clusterDevices(TopologyCluster cluster) {
90 - return devicesByCluster.get(cluster.id());
91 - }
92 -
93 - @Override
94 - public Set<Link> clusterLinks(TopologyCluster cluster) {
95 - return linksByCluster.get(cluster.id());
96 - }
97 -
98 - @Override
99 - public TopologyCluster clusterFor(DeviceId deviceId) {
100 - return clustersByDevice.get(deviceId);
101 - }
102 -
103 -
104 - // 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.
106 - private static class HopCountLinkWeight implements LinkWeight {
107 - private final int indirectLinkCost;
108 -
109 - HopCountLinkWeight(int indirectLinkCost) {
110 - this.indirectLinkCost = indirectLinkCost;
111 - }
112 -
113 - @Override
114 - public double weight(TopoEdge edge) {
115 - // To force preference to use direct paths first, make indirect
116 - // links as expensive as the linear vertex traversal.
117 - return edge.link().type() == INDIRECT ? indirectLinkCost : 1;
118 - }
119 - }
120 -
121 - // Link weight for preventing traversal over indirect links.
122 - private static class NoIndirectLinksWeight implements LinkWeight {
123 - @Override
124 - public double weight(TopoEdge edge) {
125 - return edge.link().type() == INDIRECT ? -1 : 1;
126 - }
127 - }
128 -
129 - // Constructs the topology graph using the supplied devices and links.
130 - private Graph<TopoVertex, TopoEdge> buildGraph(Iterable<Device> devices,
131 - Iterable<Link> links) {
132 - return new AdjacencyListsGraph<>(buildVertexes(devices),
133 - buildEdges(links));
134 - }
135 -
136 - // Builds a set of topology vertexes from the specified list of devices
137 - private Set<TopoVertex> buildVertexes(Iterable<Device> devices) {
138 - Set<TopoVertex> vertexes = Sets.newHashSet();
139 - for (Device device : devices) {
140 - TopoVertex vertex = new DefaultTopoVertex(device.id());
141 - vertexes.add(vertex);
142 - vertexesById.put(vertex.deviceId(), vertex);
143 - }
144 - return vertexes;
145 - }
146 -
147 - // Builds a set of topology vertexes from the specified list of links
148 - private Set<TopoEdge> buildEdges(Iterable<Link> links) {
149 - Set<TopoEdge> edges = Sets.newHashSet();
150 - for (Link link : links) {
151 - edges.add(new DefaultTopoEdge(vertexOf(link.src()),
152 - vertexOf(link.dst()), link));
153 - }
154 - return edges;
155 - }
156 -
157 - // Computes the default shortest paths for all source/dest pairs using
158 - // the multi-path Dijkstra and hop-count as path cost.
159 - private Map<DeviceId, Result<TopoVertex, TopoEdge>> computeDefaultPaths() {
160 - LinkWeight weight = new HopCountLinkWeight(graph.getVertexes().size());
161 - Map<DeviceId, Result<TopoVertex, TopoEdge>> results = Maps.newHashMap();
162 -
163 - // Search graph paths for each source to all destinations.
164 - for (TopoVertex src : vertexesById.values()) {
165 - results.put(src.deviceId(), DIJKSTRA.search(graph, src, null, weight));
166 - }
167 - return results;
168 - }
169 -
170 - // Computes topology SCC clusters using Tarjan algorithm.
171 - private Map<ClusterId, TopologyCluster> computeClusters() {
172 - Map<ClusterId, TopologyCluster> clusters = Maps.newHashMap();
173 - SCCResult<TopoVertex, TopoEdge> result = TARJAN.search(graph, new NoIndirectLinksWeight());
174 -
175 - // Extract both vertexes and edges from the results; the lists form
176 - // pairs along the same index.
177 - List<Set<TopoVertex>> clusterVertexes = result.clusterVertexes();
178 - List<Set<TopoEdge>> clusterEdges = result.clusterEdges();
179 -
180 - Builder<ClusterId, DeviceId> devicesBuilder = ImmutableSetMultimap.builder();
181 - Builder<ClusterId, Link> linksBuilder = ImmutableSetMultimap.builder();
182 -
183 - // Scan over the lists and create a cluster from the results.
184 - for (int i = 0, n = result.clusterCount(); i < n; i++) {
185 - Set<TopoVertex> vertexSet = clusterVertexes.get(i);
186 - Set<TopoEdge> edgeSet = clusterEdges.get(i);
187 -
188 - DefaultTopologyCluster cluster =
189 - new DefaultTopologyCluster(ClusterId.clusterId(i),
190 - vertexSet.size(), edgeSet.size(),
191 - findRoot(vertexSet).deviceId());
192 - findClusterDevices(vertexSet, cluster, devicesBuilder);
193 - findClusterLinks(edgeSet, cluster, linksBuilder);
194 - }
195 - return clusters;
196 - }
197 -
198 - // Scans through the set of cluster vertexes and puts their devices in a
199 - // multi-map associated with the cluster. It also binds the devices to
200 - // the cluster.
201 - private void findClusterDevices(Set<TopoVertex> vertexSet,
202 - DefaultTopologyCluster cluster,
203 - Builder<ClusterId, DeviceId> builder) {
204 - for (TopoVertex vertex : vertexSet) {
205 - DeviceId deviceId = vertex.deviceId();
206 - builder.put(cluster.id(), deviceId);
207 - clustersByDevice.put(deviceId, cluster);
208 - }
209 - }
210 -
211 - // Scans through the set of cluster edges and puts their links in a
212 - // multi-map associated with the cluster.
213 - private void findClusterLinks(Set<TopoEdge> edgeSet,
214 - DefaultTopologyCluster cluster,
215 - Builder<ClusterId, Link> builder) {
216 - for (TopoEdge edge : edgeSet) {
217 - builder.put(cluster.id(), edge.link());
218 - }
219 - }
220 -
221 - // Finds the vertex whose device id is the lexicographical minimum in the
222 - // specified set.
223 - private TopoVertex findRoot(Set<TopoVertex> vertexSet) {
224 - TopoVertex minVertex = null;
225 - for (TopoVertex vertex : vertexSet) {
226 - if (minVertex == null ||
227 - minVertex.deviceId().toString()
228 - .compareTo(minVertex.deviceId().toString()) < 0) {
229 - minVertex = vertex;
230 - }
231 - }
232 - return minVertex;
233 - }
234 -
235 - // Fetches a vertex corresponding to the given connection point device.
236 - private TopoVertex vertexOf(ConnectPoint connectPoint) {
237 - DeviceId id = connectPoint.deviceId();
238 - TopoVertex vertex = vertexesById.get(id);
239 - if (vertex == null) {
240 - // If vertex does not exist, create one and register it.
241 - vertex = new DefaultTopoVertex(id);
242 - vertexesById.put(id, vertex);
243 - }
244 - return vertex;
245 - }
246 -
247 -}
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
...@@ -7,6 +7,7 @@ import org.projectfloodlight.openflow.protocol.OFPacketIn; ...@@ -7,6 +7,7 @@ import org.projectfloodlight.openflow.protocol.OFPacketIn;
7 import org.projectfloodlight.openflow.protocol.OFPacketOut; 7 import org.projectfloodlight.openflow.protocol.OFPacketOut;
8 import org.projectfloodlight.openflow.protocol.action.OFAction; 8 import org.projectfloodlight.openflow.protocol.action.OFAction;
9 import org.projectfloodlight.openflow.protocol.action.OFActionOutput; 9 import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
10 +import org.projectfloodlight.openflow.protocol.match.MatchField;
10 import org.projectfloodlight.openflow.types.OFBufferId; 11 import org.projectfloodlight.openflow.types.OFBufferId;
11 import org.projectfloodlight.openflow.types.OFPort; 12 import org.projectfloodlight.openflow.types.OFPort;
12 13
...@@ -83,12 +84,18 @@ public final class DefaultPacketContext implements PacketContext { ...@@ -83,12 +84,18 @@ public final class DefaultPacketContext implements PacketContext {
83 84
84 @Override 85 @Override
85 public Integer inPort() { 86 public Integer inPort() {
86 - return pktin.getInPort().getPortNumber(); 87 + try {
88 + return pktin.getInPort().getPortNumber();
89 + } catch (UnsupportedOperationException e) {
90 + return pktin.getMatch().get(MatchField.IN_PORT).getPortNumber();
91 + }
87 } 92 }
88 93
89 @Override 94 @Override
90 public byte[] unparsed() { 95 public byte[] unparsed() {
96 +
91 return pktin.getData().clone(); 97 return pktin.getData().clone();
98 +
92 } 99 }
93 100
94 private OFActionOutput buildOutput(Integer port) { 101 private OFActionOutput buildOutput(Integer port) {
......
...@@ -250,9 +250,12 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -250,9 +250,12 @@ public class OpenFlowControllerImpl implements OpenFlowController {
250 } 250 }
251 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid); 251 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
252 if (sw == null) { 252 if (sw == null) {
253 - log.error("Transition to equal called on sw {}, but switch " 253 + sw = getSwitch(dpid);
254 - + "was not found in controller-cache", dpid); 254 + if (sw == null) {
255 - return; 255 + log.error("Transition to equal called on sw {}, but switch "
256 + + "was not found in controller-cache", dpid);
257 + return;
258 + }
256 } 259 }
257 log.info("Transitioned switch {} to EQUAL", dpid); 260 log.info("Transitioned switch {} to EQUAL", dpid);
258 activeEqualSwitches.put(dpid, sw); 261 activeEqualSwitches.put(dpid, sw);
......
...@@ -2,10 +2,15 @@ package org.onlab.onos.of.drivers.impl; ...@@ -2,10 +2,15 @@ package org.onlab.onos.of.drivers.impl;
2 2
3 3
4 4
5 +import java.util.Collections;
6 +import java.util.List;
7 +
5 import org.onlab.onos.of.controller.Dpid; 8 import org.onlab.onos.of.controller.Dpid;
9 +import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
6 import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver; 10 import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver;
7 import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriverFactory; 11 import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriverFactory;
8 import org.projectfloodlight.openflow.protocol.OFDescStatsReply; 12 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
13 +import org.projectfloodlight.openflow.protocol.OFMessage;
9 import org.projectfloodlight.openflow.protocol.OFVersion; 14 import org.projectfloodlight.openflow.protocol.OFVersion;
10 import org.slf4j.Logger; 15 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 16 import org.slf4j.LoggerFactory;
...@@ -51,8 +56,36 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory { ...@@ -51,8 +56,36 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory {
51 } 56 }
52 57
53 log.warn("DriverManager could not identify switch desc: {}. " 58 log.warn("DriverManager could not identify switch desc: {}. "
54 - + "Assigning OFSwitchImplBase", desc); 59 + + "Assigning AbstractOpenFlowSwich", desc);
55 - return null; 60 + return new AbstractOpenFlowSwitch(dpid) {
61 +
62 + @Override
63 + public void write(List<OFMessage> msgs) {
64 + channel.write(msgs);
65 + }
66 +
67 + @Override
68 + public void write(OFMessage msg) {
69 + channel.write(Collections.singletonList(msg));
70 +
71 + }
72 +
73 + @Override
74 + public Boolean supportNxRole() {
75 + return false;
76 + }
77 +
78 + @Override
79 + public void startDriverHandshake() {}
80 +
81 + @Override
82 + public void processDriverHandshakeMessage(OFMessage m) {}
83 +
84 + @Override
85 + public boolean isDriverHandshakeComplete() {
86 + return true;
87 + }
88 + };
56 } 89 }
57 90
58 /** 91 /**
......
...@@ -320,6 +320,7 @@ ...@@ -320,6 +320,7 @@
320 <artifactId>maven-javadoc-plugin</artifactId> 320 <artifactId>maven-javadoc-plugin</artifactId>
321 <version>2.9.1</version> 321 <version>2.9.1</version>
322 <configuration> 322 <configuration>
323 + <show>package</show>
323 <docfilessubdirs>true</docfilessubdirs> 324 <docfilessubdirs>true</docfilessubdirs>
324 <doctitle>ONOS Java API</doctitle> 325 <doctitle>ONOS Java API</doctitle>
325 <groups> 326 <groups>
......
...@@ -60,7 +60,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -60,7 +60,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
60 * Creates an OpenFlow device provider. 60 * Creates an OpenFlow device provider.
61 */ 61 */
62 public OpenFlowDeviceProvider() { 62 public OpenFlowDeviceProvider() {
63 - super(new ProviderId("org.onlab.onos.provider.of.device")); 63 + super(new ProviderId("org.onlab.onos.provider.openflow"));
64 } 64 }
65 65
66 @Activate 66 @Activate
......
...@@ -37,7 +37,7 @@ public class OpenFlowHostProvider extends AbstractProvider implements HostProvid ...@@ -37,7 +37,7 @@ public class OpenFlowHostProvider extends AbstractProvider implements HostProvid
37 * Creates an OpenFlow host provider. 37 * Creates an OpenFlow host provider.
38 */ 38 */
39 public OpenFlowHostProvider() { 39 public OpenFlowHostProvider() {
40 - super(new ProviderId("org.onlab.onos.provider.of.host")); 40 + super(new ProviderId("org.onlab.onos.provider.openflow"));
41 } 41 }
42 42
43 @Activate 43 @Activate
......
...@@ -55,7 +55,7 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid ...@@ -55,7 +55,7 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
55 * Creates an OpenFlow link provider. 55 * Creates an OpenFlow link provider.
56 */ 56 */
57 public OpenFlowLinkProvider() { 57 public OpenFlowLinkProvider() {
58 - super(new ProviderId("org.onlab.onos.provider.of.link")); 58 + super(new ProviderId("org.onlab.onos.provider.openflow"));
59 } 59 }
60 60
61 @Activate 61 @Activate
......