[SDFAB-753] Improve ONOS cluster event

Main idea of this change is to add an additional parameter
in the event that carries information about the failed instance.

Additionally, prevents several NPE by using hostname as id
when controller hostname cannot be resolved into an ip.

Change-Id: Id9886afe3f1e5ecee0f1414b2722c340680a813e
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 0ef6faf..8ae6e6d 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
@@ -201,13 +201,7 @@
 
     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", state.isActive())
-                .put("ready", state.isReady())
-                .put("uiAttached", isUiAttached)
+        return jsonCommon(member).put("uiAttached", isUiAttached)
                 .put("switches", switchCount);
     }
 
@@ -637,14 +631,26 @@
     }
 
     private ObjectNode json(UiClusterMember member) {
+        return jsonCommon(member).put(GlyphConstants.UI_ATTACHED,
+                clusterService.getLocalNode().equals(member.backingNode()));
+    }
+
+    private ObjectNode jsonCommon(UiClusterMember member) {
         ControllerNode.State state = clusterService.getState(member.id());
+        ControllerNode node = member.backingNode();
+        if (node != null) {
+            IpAddress nodeIp = member.backingNode().ip();
+            return objectNode()
+                    .put("id", member.idAsString())
+                    .put("ip", nodeIp != null ? nodeIp.toString() : node.host())
+                    .put("online", state.isActive())
+                    .put("ready", state.isReady());
+        }
         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()));
+                .put("ip", "NONE")
+                .put("online", false)
+                .put("ready", false);
     }
 
     private ObjectNode jsonClosedRegion(String ridStr, UiRegion region) {