ONOS-3182 Adding device badges and bug fixes

Change-Id: I84a0e8ec4e968ad80d08d086fa951cc4800aa70b
diff --git a/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java b/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java
index ca9d668..de7826c 100644
--- a/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java
+++ b/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java
@@ -30,7 +30,10 @@
 import org.onosproject.ui.RequestHandler;
 import org.onosproject.ui.UiConnection;
 import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.topo.DeviceHighlight;
 import org.onosproject.ui.topo.Highlights;
+import org.onosproject.ui.topo.HostHighlight;
+import org.onosproject.ui.topo.NodeBadge;
 import org.onosproject.ui.topo.TopoJson;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -54,6 +57,11 @@
 
     private static final String ID = "id";
     private static final String MODE = "mode";
+    private static final String TYPE = "type";
+    private static final String SWITCH = "switch";
+    private static final String ENDSTATION = "endstation";
+    public static final String DST = "Dst";
+    public static final String SRC = "Src";
 
     private Set<Link> allPathLinks;
 
@@ -66,6 +74,7 @@
     private PathService pathService;
 
     private ElementId src, dst;
+    private String srcType, dstType;
     private Mode currentMode = Mode.SHORTEST;
     private List<Path> paths;
     private int pathIndex;
@@ -96,6 +105,7 @@
     // === Handler classes
 
     private final class SetSrcHandler extends RequestHandler {
+
         public SetSrcHandler() {
             super(PAINTER_SET_SRC);
         }
@@ -104,10 +114,15 @@
         public void process(long sid, ObjectNode payload) {
             String id = string(payload, ID);
             src = elementId(id);
+            srcType = string(payload, TYPE);
             if (src.equals(dst)) {
                 dst = null;
             }
-            findAndSendPaths();
+            sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(),
+                                                            srcType,
+                                                            src.toString(),
+                                                            SRC)));
+            findAndSendPaths(currentMode);
         }
     }
 
@@ -120,10 +135,16 @@
         public void process(long sid, ObjectNode payload) {
             String id = string(payload, ID);
             dst = elementId(id);
+            dstType = string(payload, TYPE);
             if (src.equals(dst)) {
                 src = null;
             }
-            findAndSendPaths();
+
+            sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(),
+                                                            dstType,
+                                                            dst.toString(),
+                                                            DST)));
+            findAndSendPaths(currentMode);
         }
     }
 
@@ -137,7 +158,10 @@
             ElementId temp = src;
             src = dst;
             dst = temp;
-            findAndSendPaths();
+            String s = srcType;
+            srcType = dstType;
+            dstType = s;
+            findAndSendPaths(currentMode);
         }
     }
 
@@ -177,11 +201,7 @@
                     Mode.SHORTEST : (mode.equals("disjoint") ?
                     Mode.DISJOINT : Mode.SRLG));
             //TODO: add support for SRLG
-            if (currentMode.equals(Mode.SHORTEST)) {
-                findAndSendPaths();
-            } else {
-                findAndSendDisjointPaths();
-            }
+            findAndSendPaths(currentMode);
         }
     }
 
@@ -195,40 +215,40 @@
         }
     }
 
-    private void findAndSendPaths() {
-        if (src != null && dst != null) {
-            paths = ImmutableList.copyOf(pathService.getPaths(src, dst));
-            pathIndex = 0;
-
-            ImmutableSet.Builder<Link> builder = ImmutableSet.builder();
-            paths.forEach(path -> path.links().forEach(builder::add));
-            allPathLinks = builder.build();
-        } else {
-            paths = ImmutableList.of();
-            allPathLinks = ImmutableSet.of();
-        }
-        hilightAndSendPaths();
-    }
-
-    private void findAndSendDisjointPaths() {
+    private void findAndSendPaths(Mode mode) {
         log.info("src={}; dst={}; mode={}", src, dst, currentMode);
         if (src != null && dst != null) {
-            log.info("test" + src + dst);
-            paths = ImmutableList.copyOf(pathService.getDisjointPaths(src, dst));
             pathIndex = 0;
-
             ImmutableSet.Builder<Link> builder = ImmutableSet.builder();
-            paths.forEach(path -> {
-                DisjointPath dp = (DisjointPath) path;
-                builder.addAll(dp.primary().links());
-                builder.addAll(dp.backup().links());
-            });
-            allPathLinks = builder.build();
+            if (mode.equals(Mode.SHORTEST)) {
+                paths = ImmutableList.copyOf(pathService.getPaths(src, dst));
+                allPathLinks = buildPaths(builder).build();
+            } else if (mode.equals(Mode.DISJOINT)) {
+                paths = ImmutableList.copyOf(pathService.getDisjointPaths(src, dst));
+                allPathLinks = buildDisjointPaths(builder).build();
+            } else {
+                log.info("Unsupported MODE");
+            }
         } else {
             paths = ImmutableList.of();
             allPathLinks = ImmutableSet.of();
         }
         hilightAndSendPaths();
+
+    }
+
+    private ImmutableSet.Builder<Link> buildPaths(ImmutableSet.Builder<Link> pathBuilder) {
+        paths.forEach(path -> path.links().forEach(pathBuilder::add));
+        return pathBuilder;
+    }
+
+    private ImmutableSet.Builder<Link> buildDisjointPaths(ImmutableSet.Builder<Link> pathBuilder) {
+        paths.forEach(path -> {
+            DisjointPath dp = (DisjointPath) path;
+            pathBuilder.addAll(dp.primary().links());
+            pathBuilder.addAll(dp.backup().links());
+        });
+        return pathBuilder;
     }
 
     private void hilightAndSendPaths() {
@@ -240,9 +260,9 @@
         // Prepare two working sets; one containing selected path links and
         // the other containing all paths links.
         if (currentMode.equals(Mode.DISJOINT)) {
-            DisjointPath dp = (DisjointPath)  paths.get(pathIndex);
+            DisjointPath dp = (DisjointPath) paths.get(pathIndex);
             selectedPathLinks = paths.isEmpty() ?
-                ImmutableSet.of() : Sets.newHashSet(dp.primary().links());
+                    ImmutableSet.of() : Sets.newHashSet(dp.primary().links());
             selectedPathLinks.addAll(dp.backup().links());
         } else {
             selectedPathLinks = paths.isEmpty() ?
@@ -253,23 +273,40 @@
             plink.computeHilight(selectedPathLinks, allPathLinks);
             highlights.add(plink.highlight(null));
         }
-
+        if (src != null) {
+            highlights = addBadge(highlights, srcType, src.toString(), SRC);
+        }
+        if (dst != null) {
+            highlights = addBadge(highlights, dstType, dst.toString(), DST);
+        }
         sendMessage(TopoJson.highlightsMessage(highlights));
     }
 
-    /*
-    private void addDeviceBadge(Highlights h, DeviceId devId, int n) {
-        DeviceHighlight dh = new DeviceHighlight(devId.toString());
-        dh.setBadge(createBadge(n));
-        h.add(dh);
+    private Highlights addBadge(Highlights highlights, String type, String elemId, String src) {
+        if (SWITCH.equals(type)) {
+            highlights = addDeviceBadge(highlights, elemId, src);
+        } else if (ENDSTATION.equals(type)) {
+            highlights = addHostBadge(highlights, elemId, src);
+        }
+        return highlights;
     }
 
-    private NodeBadge createBadge(int n) {
-        Status status = n > 3 ? Status.ERROR : Status.WARN;
-        String noun = n > 3 ? "(critical)" : "(problematic)";
-        String msg = "Egress links: " + n + " " + noun;
-        return NodeBadge.number(status, n, msg);
+    private Highlights addDeviceBadge(Highlights h, String elemId, String type) {
+        DeviceHighlight dh = new DeviceHighlight(elemId);
+        dh.setBadge(createBadge(type));
+        h.add(dh);
+        return h;
     }
-   */
+
+    private Highlights addHostBadge(Highlights h, String elemId, String type) {
+        HostHighlight hh = new HostHighlight(elemId);
+        hh.setBadge(createBadge(type));
+        h.add(hh);
+        return h;
+    }
+
+    private NodeBadge createBadge(String type) {
+        return NodeBadge.text(type);
+    }
 
 }
\ No newline at end of file
diff --git a/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js b/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js
index d0d1667..213d9c5 100644
--- a/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js
+++ b/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js
@@ -47,14 +47,16 @@
 
     function setSrc(node) {
         wss.sendEvent(srcMessage, {
-            id: node.id
+            id: node.id,
+            type: node.type
         });
         flash.flash('Source node: ' + node.id);
     }
 
     function setDst(node) {
         wss.sendEvent(dstMessage, {
-            id: node.id
+            id: node.id,
+            type: node.type
         });
         flash.flash('Destination node: ' + node.id);
     }
diff --git a/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js b/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js
index 3552034..171e33e 100644
--- a/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js
+++ b/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js
@@ -26,38 +26,33 @@
         glyphs: {
             src: {
                 vb: '0 0 110 110',
-                d: 'M26.9,57 M27,86c0.5-9.6,5.8-25.3,13.6-35.2c4.2-5.4,6.2-10.6,6.2-13.8' +
-                'c0-11-8.9-20-19.9-20h0C15.9,17,7,26,7,37c0,3.2,1.9,8.4,6.2,13.8c7.8,9.9,13.1,25.5,13.6,35.2H27z M27.7,86.7l0-0.7' +
-                'c0.5-9.3,5.6-24.8,13.4-34.7c4.7-5.9,6.3-11.3,6.3-14.3c0-11.4-9.3-20.7-20.6-20.7C15.5,16.3,6.2,25.6,6.2,37c0,3,1.7,8.3,6.3,14.3' +
-                'c7.8,9.9,13,25.5,13.4,34.7l0,0.7H27.7L27.7,86.7z M26.9,17.8C37.4,17.8,46,26.4,46,37c0,2.6-1.6,7.7-6,13.3' +
-                'c-6.6,8.4-11.4,20.8-13.1,30.2c-1.7-9.4-6.5-21.8-13.1-30.2c-4.4-5.6-6-10.7-6-13.3C7.7,26.4,16.3,17.8,26.9,17.8L26.9,17.8z' +
-                'M87.3,35.5H46.9v2h40.4V35.5z M26.8,27.9c-4.7,0-8.4,3.8-8.4,8.4c0,4.6,3.8,8.4,8.4,8.4s8.4-3.7,8.4-8.4' +
-                'C35.2,31.6,31.4,27.9,26.8,27.9z M87.3,44.9 M87.3,28.1c-0.1,3.1-0.1,12.6,0,16.7c0.1,4.1,13.9-5.5,13.8-8.4' +
-                'C101,33.6,87.3,24.2,87.3,28.1z'
+                d: 'M28.7,59.3 M14.9,53 M8.7,39 M32.4,92.5H25l-0.2-3.6' +
+                'c-0.5-9-5.4-23.9-12.9-33.5c-5.2-6.6-7-12.8-7-16.3c0-13.3,10.7-24,23.8-24c13.1,0,23.8,10.8,23.8,24c0,3.5-1.8,9.7-7,16.3' +
+                'C38,65,33.1,80,32.6,88.9L32.4,92.5z M27.9,89.5h1.7l0-0.7c0.5-9.4,5.7-25.2,13.5-35.2c4.7-6,6.4-11.4,6.4-14.5' +
+                'c0-11.6-9.3-21-20.8-21C17.3,18,7.9,27.5,7.9,39c0,3,1.7,8.4,6.4,14.5c7.9,10.1,13.1,25.8,13.5,35.2L27.9,89.5z M28.7,83.2' +
+                'M28.6,29.8c-4.7,0-8.5,3.8-8.5,8.5c0,4.7,3.8,8.5,8.5,8.5s8.5-3.8,8.5-8.5C37.1,33.6,33.3,29.8,28.6,29.8z M89.6,47 M89.6,29.5' +
+                'c-0.1,3.1-0.1,12.8,0,17c0.1,4.2,14.1-5.5,13.9-8.5C103.4,35.1,89.6,25.6,89.6,29.5z M51,38.1L89.5,38 M89.5,39.5l0-3L51,36.5l0,3' +
+                'L89.5,39.5z'
             },
             dst: {
                 vb: '0 0 110 110',
-                d: 'M80.6,57 M80.7,86c0.5-9.6,5.8-25.3,13.5-35.2c4.2-5.4,6.1-10.6,6.1-13.8' +
-                'c0-11-8.8-20-19.7-20h0C69.7,17,60.8,26,60.8,37c0,3.2,1.9,8.4,6.1,13.8c7.7,9.9,13,25.5,13.5,35.2H80.7z M81.4,86.7l0-0.7' +
-                'c0.5-9.3,5.6-24.8,13.4-34.7c4.6-5.9,6.3-11.3,6.3-14.3c0-11.4-9.2-20.7-20.5-20.7S60.1,25.6,60.1,37c0,3,1.7,8.3,6.3,14.3' +
-                'c7.8,9.9,12.9,25.5,13.4,34.7l0,0.7H81.4L81.4,86.7z M80.6,17.8c10.5,0,19,8.6,19,19.2c0,2.6-1.6,7.7-6,13.3' +
-                'c-6.6,8.4-11.3,20.8-13,30.2c-1.7-9.4-6.4-21.8-13-30.2c-4.4-5.6-6-10.7-6-13.3C61.6,26.4,70.1,17.8,80.6,17.8L80.6,17.8z' +
-                'M46.3,35.2H6.2v2h40.1V35.2z M80.5,27.9c-4.6,0-8.4,3.7-8.4,8.4c0,4.6,3.7,8.4,8.4,8.4s8.4-3.7,8.4-8.4' +
-                'C88.9,31.6,85.1,27.9,80.5,27.9z M46.3,44.6 M46.3,27.9c-0.1,3.1-0.1,12.6,0,16.7c0.1,4.1,13.9-5.5,13.7-8.4' +
-                'C60,33.3,46.3,24,46.3,27.9z'
+                d: 'M80.3,59.8 M85.8,92.5h-7.2L78.4,89c-0.4-8.8-5.2-23.6-12.3-33' +
+                'c-4.9-6.5-6.7-12.5-6.7-16c0-13,10.2-23.7,22.7-23.7c12.5,0,22.7,10.6,22.7,23.7c0,3.5-1.8,9.5-6.7,16C91.2,65.4,86.4,80.1,86,89' +
+                'L85.8,92.5z M81.4,89.5H83l0-0.7c0.5-9.3,5.4-24.8,12.9-34.7c4.5-5.9,6.1-11.2,6.1-14.2c0-11.4-8.9-20.7-19.8-20.7' +
+                'c-10.9,0-19.8,9.3-19.8,20.7c0,3,1.6,8.3,6.1,14.2C76,64,80.9,79.5,81.4,88.8L81.4,89.5z M82.1,30.8c-4.5,0-8.1,3.7-8.1,8.4' +
+                's3.6,8.4,8.1,8.4c4.5,0,8.1-3.7,8.1-8.4S86.6,30.8,82.1,30.8z M47.2,47.5 M45.2,30.8c-0.1,3.1-0.1,12.6,0,16.7' +
+                'c0.1,4.1,13.4-5.4,13.3-8.4C58.4,36.2,45.2,26.9,45.2,30.8z M45.2,39.1L6.7,39.2 M45.2,40.6l0-3L6.7,37.7l0,3L45.2,40.6z'
             },
             jp: {
                 vb: '0 0 110 110',
-                d: 'M27,26.8H7.4V7.6H27V26.8z M102.1,79.5H82.6v19.2h19.5V79.5z M59.3,47.1H39.8v19.2' +
-                'h19.5V47.1z M41.7,47.5L17.1,25.2l-1.3,1.4l24.6,22.3L41.7,47.5z M84.5,89.5L59,64.3l-1.4,1.4l25.4,25.2L84.5,89.5z'
+                d: 'M84.3,89.3L58.9,64.2l-1.4,1.4L83,90.7L84.3,89.3z M27,7.6H7.4v19.2H27V7.6z' +
+                'M59.3,47.1H39.8v19.2h19.5V47.1z M102.1,79.5H82.6v19.2h19.5V79.5z M41.7,47.6L19,25.1l-1.2,1.2l22.7,22.5L41.7,47.6z'
             },
             djp: {
                 vb: '0 0 110 110',
-                d: 'M27.6,28.8H7.7V9h19.9V28.8z M103,37.2H83.1V57H103V37.2z M36.2,84.5H16.3v19.9' +
-                'h19.9V84.5z M27.9,85.7L18.7,28l-2,0.3L25.9,86L27.9,85.7z M92.2,59.1L91,57.4L34.6,96.8l1.1,1.6L92.2,59.1z M28.5,80.7' +
-                'c-0.8,0.2-3.5,0.7-4.6,1c-1.1,0.3,2.2,3.1,3,2.9S29.6,80.5,28.5,80.7z M88.8,57.5c0.5,0.7,2,2.9,2.7,3.8c0.7,0.9,2-3.2,1.5-3.9' +
-                'C92.5,56.8,88.2,56.6,88.8,57.5z M97.7,42.5L27.2,17.9l-0.7,1.9l70.5,24.6L97.7,42.5z M30.7,22.6c0.3-0.8,1.2-3.3,1.5-4.4' +
-                'c0.4-1.1-3.8,0.3-4,1.1C27.9,20.1,30.3,23.7,30.7,22.6z'
+                d: 'M25.8,84l-9.2-57 M27.3,83.8l-9.2-57l-3,0.5l9.2,57L27.3,83.8z M83.2,37.7L26.8,15.5 M83.7,36.1L26.6,14' +
+                'l-1,3.2l57,22.1L83.7,36.1z M34.1,95l61.4-40.6 M96.4,55.7l-1.9-2.5L33.2,93.8l1.9,2.5L96.4,55.7z M26.6,27.6H6.7V7.7h19.9V27.6z' +
+                'M102.1,36H82.2v19.9h19.9V36z M35.3,83.5H15.3v19.9h19.9V83.5z'
             }
 
         },
@@ -70,7 +65,6 @@
         },
 
         // detail panel button definitions
-        // FIXME: new icons for src/dst
         buttons: {
             src: {
                 gid: '*src',
@@ -93,7 +87,6 @@
         // Key bindings for traffic overlay buttons
         // NOTE: fully qual. button ID is derived from overlay-id and key-name
         // FIXME: use into [ and ] instead of 1 and 2
-        // FIXME: new icons for src/dst
         // FIXME: find better keys for shortest paths & disjoint paths modes
         keyBindings: {
             1: {