Added Topology WebSocket server implementation.
It allows remote applications (e.g., the GUI) to subscribe
for Topology-related events.
The URL is:
ws://hostname:8081/ws/onos/topology

When a new client opens a socket, the server transmits the whole topology.
From that moment on, the server sends topology events (deltas) if there
are any changes in the topology. Currently, all objects are encoded in JSON.

The default WebSocket port number is set to 8081
(configurable in conf/onos.properties)

NOTE: In the current implementation, the initial fetching of the topology,
and adding topology events for transmission are done by two different threads.
Hence, when a new client opens a socket, there is a small window of time
when some of the added events are "moving back in time".
The final result of applying all events will be technically correct, but
those "moving back in time" events are semantically incorrect.
This issue will be addressed in later iterations / refactoring of the
implementation.

Change-Id: Id2cbf72d1384208201d916e0aa1e5926659878ee
diff --git a/src/main/java/net/onrc/onos/apps/websocket/WebSocketModule.java b/src/main/java/net/onrc/onos/apps/websocket/WebSocketModule.java
new file mode 100644
index 0000000..d50458b
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/websocket/WebSocketModule.java
@@ -0,0 +1,72 @@
+package net.onrc.onos.apps.websocket;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.onrc.onos.core.topology.ITopologyService;
+
+/**
+ * The WebSocket module class.
+ */
+public class WebSocketModule implements IFloodlightModule, IWebSocketService {
+    private WebSocketManager webSocketManager;
+    private static final int DEFAULT_WEBSOCKET_PORT = 8081;
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        List<Class<? extends IFloodlightService>> services =
+                new ArrayList<Class<? extends IFloodlightService>>();
+        services.add(IWebSocketService.class);
+        return services;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+    getServiceImpls() {
+        Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
+                new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+        impls.put(IWebSocketService.class, this);
+        return impls;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+        List<Class<? extends IFloodlightService>> dependencies =
+                new ArrayList<Class<? extends IFloodlightService>>();
+        dependencies.add(ITopologyService.class);
+        return dependencies;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context)
+            throws FloodlightModuleException {
+        ITopologyService topologyService =
+            context.getServiceImpl(ITopologyService.class);
+
+        //
+        // Read the configuration options
+        //
+        int webSocketPort = DEFAULT_WEBSOCKET_PORT;
+        Map<String, String> configOptions = context.getConfigParams(this);
+        String port = configOptions.get("port");
+        if (port != null) {
+            webSocketPort = Integer.parseInt(port);
+        }
+
+        // Initialize the WebSocketManager
+        webSocketManager = new WebSocketManager(topologyService,
+                                                webSocketPort);
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        webSocketManager.startup();
+    }
+}