Server-side GUI: handle ClusterEvent JSON encoding and posting.

Change-Id: I7c9c155b86740ea1d8fd7d418666d47013c3c27c
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/Topo2Jsonifier.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/Topo2Jsonifier.java
index 214553e..606d175 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/topo/Topo2Jsonifier.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/Topo2Jsonifier.java
@@ -24,6 +24,7 @@
 import org.onlab.osgi.ServiceDirectory;
 import org.onlab.packet.IpAddress;
 import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ControllerNode;
 import org.onosproject.cluster.NodeId;
 import org.onosproject.incubator.net.PortStatisticsService;
 import org.onosproject.incubator.net.tunnel.TunnelService;
@@ -41,6 +42,7 @@
 import org.onosproject.net.region.Region;
 import org.onosproject.net.statistic.StatisticService;
 import org.onosproject.net.topology.TopologyService;
+import org.onosproject.ui.GlyphConstants;
 import org.onosproject.ui.JsonUtils;
 import org.onosproject.ui.UiExtensionService;
 import org.onosproject.ui.UiPreferencesService;
@@ -202,11 +204,12 @@
 
     private ObjectNode json(UiClusterMember member, boolean isUiAttached) {
         int switchCount = mastershipService.getDevicesOf(member.id()).size();
+        ControllerNode.State state = clusterService.getState(member.id());
         return objectNode()
                 .put("id", member.id().toString())
                 .put("ip", member.ip().toString())
-                .put("online", member.isOnline())
-                .put("ready", member.isReady())
+                .put("online", state.isActive())
+                .put("ready", state.isReady())
                 .put("uiAttached", isUiAttached)
                 .put("switches", switchCount);
     }
@@ -397,8 +400,9 @@
         if (element instanceof UiLink) {
             return json((UiLink) element);
         }
-
-        // TODO: UiClusterMember
+        if (element instanceof UiClusterMember) {
+            return json((UiClusterMember) element);
+        }
 
         // Unrecognized UiElement class
         return objectNode()
@@ -634,6 +638,16 @@
         return data;
     }
 
+    private ObjectNode json(UiClusterMember member) {
+        ControllerNode.State state = clusterService.getState(member.id());
+        return objectNode()
+                .put("id", member.idAsString())
+                .put("ip", member.ip().toString())
+                .put("online", state.isActive())
+                .put("ready", state.isReady())
+                .put(GlyphConstants.UI_ATTACHED,
+                     member.backingNode().equals(clusterService.getLocalNode()));
+    }
 
     private ObjectNode jsonClosedRegion(String ridStr, UiRegion region) {
         ObjectNode node = objectNode()