GUI Topo -- added NodeBadge field to NodeHighlight.
 - updated TopoJson to include device badge in JSON output.

Change-Id: I7fc0ec226c378a0395cd1eec765cb7bc867f9100
diff --git a/core/api/src/main/java/org/onosproject/ui/topo/DeviceHighlight.java b/core/api/src/main/java/org/onosproject/ui/topo/DeviceHighlight.java
index 0ce6592..0cc1547 100644
--- a/core/api/src/main/java/org/onosproject/ui/topo/DeviceHighlight.java
+++ b/core/api/src/main/java/org/onosproject/ui/topo/DeviceHighlight.java
@@ -17,16 +17,16 @@
 package org.onosproject.ui.topo;
 
 /**
- * Denotes the highlighting to apply to a device.
+ * Denotes the highlighting to be applied to a device.
  */
 public class DeviceHighlight extends NodeHighlight {
 
+    /**
+     * Constructs a device highlight entity.
+     *
+     * @param deviceId the device identifier
+     */
     public DeviceHighlight(String deviceId) {
         super(TopoElementType.DEVICE, deviceId);
     }
-
-    // TODO: implement device highlighting:
-    //   - visual highlight
-    //   - badging
-
 }
diff --git a/core/api/src/main/java/org/onosproject/ui/topo/NodeHighlight.java b/core/api/src/main/java/org/onosproject/ui/topo/NodeHighlight.java
index 61e10c5..6923508 100644
--- a/core/api/src/main/java/org/onosproject/ui/topo/NodeHighlight.java
+++ b/core/api/src/main/java/org/onosproject/ui/topo/NodeHighlight.java
@@ -20,7 +20,34 @@
  * Parent class of {@link DeviceHighlight} and {@link HostHighlight}.
  */
 public abstract class NodeHighlight extends AbstractHighlight {
+
+    private NodeBadge badge;
+
+    /**
+     * Constructs a node highlight entity.
+     *
+     * @param type element type
+     * @param elementId element identifier
+     */
     public NodeHighlight(TopoElementType type, String elementId) {
         super(type, elementId);
     }
+
+    /**
+     * Sets the badge for this node.
+     *
+     * @param badge badge to apply
+     */
+    public void setBadge(NodeBadge badge) {
+        this.badge = badge;
+    }
+
+    /**
+     * Returns the badge for this node, if any.
+     *
+     * @return badge, or null
+     */
+    public NodeBadge badge() {
+        return badge;
+    }
 }
diff --git a/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java b/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java
index 8df0316..d4990f3 100644
--- a/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java
+++ b/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java
@@ -37,6 +37,8 @@
     static final String ID = "id";
     static final String LABEL = "label";
     static final String CSS = "css";
+    static final String BADGE = "badge";
+    static final String MSG = "msg";
 
     static final String TITLE = "title";
     static final String TYPE = "type";
@@ -103,6 +105,13 @@
         if (dh.subdued()) {
             n.put(SUBDUE, true);
         }
+        NodeBadge badge = dh.badge();
+        if (badge != null) {
+            ObjectNode b = objectNode()
+                    .put(TYPE, badge.type().code())
+                    .put(MSG, badge.message());
+            n.set(BADGE, b);
+        }
         return n;
     }
 
diff --git a/core/api/src/test/java/org/onosproject/ui/topo/TopoJsonTest.java b/core/api/src/test/java/org/onosproject/ui/topo/TopoJsonTest.java
index ac0051c..3b572a97 100644
--- a/core/api/src/test/java/org/onosproject/ui/topo/TopoJsonTest.java
+++ b/core/api/src/test/java/org/onosproject/ui/topo/TopoJsonTest.java
@@ -23,12 +23,17 @@
 import org.onosproject.ui.topo.Highlights.Amount;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 /**
  * Unit tests for {@link TopoJson}.
  */
 public class TopoJsonTest {
 
+    private static final String DEV1 = "device-1";
+    private static final String DEV2 = "device-2";
+    private static final String BADGE_MSG = "Hello there";
+
     private ObjectNode payload;
 
     private void checkArrayLength(String key, int expLen) {
@@ -68,4 +73,38 @@
         String subdue = JsonUtils.string(payload, TopoJson.SUBDUE);
         assertEquals("not max", "max", subdue);
     }
+
+    @Test
+    public void badgedDevice() {
+        Highlights h = new Highlights();
+        DeviceHighlight dh = new DeviceHighlight(DEV1);
+        dh.setBadge(NodeBadge.info(BADGE_MSG));
+        h.add(dh);
+
+        dh = new DeviceHighlight(DEV2);
+        dh.setBadge(NodeBadge.number(7));
+        h.add(dh);
+
+        payload = TopoJson.json(h);
+        System.out.println(payload);
+
+        // dig into the payload, and verify the badges are set on the devices
+        ArrayNode a = (ArrayNode) payload.get(TopoJson.DEVICES);
+
+        ObjectNode d = (ObjectNode) a.get(0);
+        assertEquals("wrong device id", DEV1, d.get(TopoJson.ID).asText());
+
+        ObjectNode b = (ObjectNode) d.get(TopoJson.BADGE);
+        assertNotNull("missing badge", b);
+        assertEquals("wrong type code", "i", b.get(TopoJson.TYPE).asText());
+        assertEquals("wrong message", BADGE_MSG, b.get(TopoJson.MSG).asText());
+
+        d = (ObjectNode) a.get(1);
+        assertEquals("wrong device id", DEV2, d.get(TopoJson.ID).asText());
+
+        b = (ObjectNode) d.get(TopoJson.BADGE);
+        assertNotNull("missing badge", b);
+        assertEquals("wrong type code", "n", b.get(TopoJson.TYPE).asText());
+        assertEquals("wrong message", "7", b.get(TopoJson.MSG).asText());
+    }
 }