ONOS-1871: Send Topology MastershipEvent info to Topology listeners.
The MastershipEvent info is needed by applications such as the GUI
(via the Websocket client).
NOTE: Previously, the Mastership Events were sent only when there
was any change, but no Mastership Events were sent when a listener
has just subscribed.
The solution is to add a mechanism for creating and sending Topology
Snapshot event to new listeners, and that event also includes
the Mastership Events.
The modifications are:
* Renamed and updated the ITopologyService API for adding/removing
Topology listeners:
OLD: registerTopologyListener() and deregisterTopologyListener()
NEW: addListener() and removeListener()
Also, addListener() has a second argument:
"boolean startFromSnapshot"
If that argument is true, and if the topology is not empty, the first
(expected) event to that listener should be a snapshot of the current
topology.
* Added TopologyEvents() constructor for ADDED events only. Such event
can be used to represent a snapshot of the topology.
* Added new APIs to TopologyInternal:
getAllSwitchEvents(), getAllPortEvents(), get AllLinkEvents(),
getAllHostEvents()
Those APIs are needed for creating a snapshot of the topology.
* Added a mechanism for creating empty (NO-OP) TopologyEvent instance,
and use that mechanism to "wake-up" the EventHandler processing thread
when it needs to send Topology Snapshot to a new listener.
This solution is (kind-of) a hack.
Change-Id: Ie1eb52242f58682aac61f54af29c3b5d291ac0bd
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java b/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
index fcf3caa..a0248b7 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
@@ -4,6 +4,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -364,6 +365,11 @@
}
@Override
+ public Collection<SwitchEvent> getAllSwitchEvents() {
+ return Collections.unmodifiableCollection(switches.values());
+ }
+
+ @Override
public PortEvent getPortEvent(final SwitchPort port) {
ConcurrentMap<PortNumber, PortEvent> portMap = this.ports.get(port.getDpid());
if (portMap != null) {
@@ -373,6 +379,15 @@
}
@Override
+ public Collection<PortEvent> getAllPortEvents() {
+ List<PortEvent> events = new LinkedList<>();
+ for (ConcurrentMap<PortNumber, PortEvent> cm : ports.values()) {
+ events.addAll(cm.values());
+ }
+ return Collections.unmodifiableCollection(events);
+ }
+
+ @Override
public LinkEvent getLinkEvent(final LinkTuple linkId) {
ConcurrentMap<String, LinkEvent> links = this.outgoingLinks.get(linkId.getSrc());
if (links == null) {
@@ -411,10 +426,24 @@
}
@Override
+ public Collection<LinkEvent> getAllLinkEvents() {
+ List<LinkEvent> events = new LinkedList<>();
+ for (ConcurrentMap<String, LinkEvent> cm : outgoingLinks.values()) {
+ events.addAll(cm.values());
+ }
+ return Collections.unmodifiableCollection(events);
+ }
+
+ @Override
public HostEvent getHostEvent(final MACAddress mac) {
return this.mac2Host.get(mac);
}
+ @Override
+ public Collection<HostEvent> getAllHostEvents() {
+ return Collections.unmodifiableCollection(mac2Host.values());
+ }
+
/**
* Puts a SwitchEvent.
*