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/TopologyEvent.java b/src/main/java/net/onrc/onos/core/topology/TopologyEvent.java
index c51a157..82fa6e5 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyEvent.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyEvent.java
@@ -40,6 +40,20 @@
     }
 
     /**
+     * Constructor for creating an empty (NO-OP) Topology Event.
+     *
+     * @param onosInstanceId the ONOS Instance ID that originates the event.
+     */
+    protected TopologyEvent(OnosInstanceId onosInstanceId) {
+        mastershipEvent = null;
+        switchEvent = null;
+        portEvent = null;
+        linkEvent = null;
+        hostEvent = null;
+        this.onosInstanceId = checkNotNull(onosInstanceId);
+    }
+
+    /**
      * Constructor for given Switch Mastership event.
      *
      * @param mastershipEvent the Switch Mastership event to use.
@@ -270,8 +284,13 @@
                 eventStr = hostEvent.toString();
                 break stringLabel;
             }
+            // Test whether this is NO-OP event
+            if (onosInstanceId != null) {
+                eventStr = "NO-OP";
+                break stringLabel;
+            }
             // No event found
-            return "[Empty TopologyEvent]";
+            return "[Unknown TopologyEvent]";
         }
 
         return "[TopologyEvent " + eventStr + " from " +
@@ -319,6 +338,12 @@
                 eventId = hostEvent.getIDasByteBuffer();
                 break idLabel;
             }
+            // Test whether this is NO-OP event
+            if (onosInstanceId != null) {
+                String id = "NO-OP";
+                eventId = ByteBuffer.wrap(id.getBytes(StandardCharsets.UTF_8));
+                break idLabel;
+            }
             // No event found
             throw new IllegalStateException("Invalid TopologyEvent ID");
         }