GUI -- Fixed intent perf GUI styling.

Change-Id: I552d3a50f7f4dd5bb1df7115c15eb6a04f538378
diff --git a/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java b/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java
index 8683f3f..a979b65 100644
--- a/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java
+++ b/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java
@@ -37,10 +37,8 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 
-import static org.onlab.util.Tools.groupedThreads;
+import static org.onlab.util.SharedExecutors.getPoolThreadExecutor;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -78,18 +76,13 @@
     private Map<NodeId, Integer> nodeToIndex;
 
     private NodeId nodeId;
-    private ExecutorService messageHandlingExecutor;
 
     @Activate
     public void activate() {
         nodeId = clusterService.getLocalNode().id();
 
-        // TODO: replace with shared executor
-        messageHandlingExecutor = Executors.newSingleThreadExecutor(
-                groupedThreads("onos/perf", "message-handler"));
-
         communicationService.addSubscriber(SAMPLE, new InternalSampleCollector(),
-                                           messageHandlingExecutor);
+                                           getPoolThreadExecutor());
 
         nodes = clusterService.getNodes().toArray(new ControllerNode[]{});
         Arrays.sort(nodes, (a, b) -> a.id().toString().compareTo(b.id().toString()));
@@ -99,14 +92,13 @@
             nodeToIndex.put(nodes[i].id(), i);
         }
 
-        ui.setHeaders(getSampleHeaders());
         clearSamples();
+        ui.setCollector(this);
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
-        messageHandlingExecutor.shutdown();
         communicationService.removeSubscriber(SAMPLE);
         log.info("Stopped");
     }
diff --git a/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfInstaller.java b/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfInstaller.java
index 96f2b32..909f3a5 100644
--- a/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfInstaller.java
+++ b/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfInstaller.java
@@ -156,7 +156,7 @@
     private ExecutorService workers;
     private ApplicationId appId;
     private Listener listener;
-    private boolean stopped;
+    private boolean stopped = true;
 
     private Timer reportTimer;
 
@@ -247,13 +247,18 @@
     }
 
     public void start() {
-        communicationService.broadcast(new ClusterMessage(nodeId, CONTROL, START.getBytes()));
-        startTestRun();
+        if (stopped) {
+            stopped = false;
+            communicationService.broadcast(new ClusterMessage(nodeId, CONTROL, START.getBytes()));
+            startTestRun();
+        }
     }
 
     public void stop() {
-        communicationService.broadcast(new ClusterMessage(nodeId, CONTROL, STOP.getBytes()));
-        stopTestRun();
+        if (!stopped) {
+            communicationService.broadcast(new ClusterMessage(nodeId, CONTROL, STOP.getBytes()));
+            stopTestRun();
+        }
     }
 
     private void logConfig(String prefix) {
@@ -282,7 +287,6 @@
     }
 
     private void stopTestRun() {
-        stopped = true;
         if (reporterTask != null) {
             reporterTask.cancel();
             reporterTask = null;
@@ -293,6 +297,11 @@
         } catch (InterruptedException e) {
             log.warn("Failed to stop worker", e);
         }
+
+        sampleCollector.recordSample(0, 0);
+        sampleCollector.recordSample(0, 0);
+        stopped = true;
+
         log.info("Stopped test run");
     }
 
diff --git a/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java b/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java
index f50ed3b..5d7132d 100644
--- a/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java
+++ b/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java
@@ -36,9 +36,7 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Random;
 import java.util.Set;
-import java.util.TimerTask;
 
 import static java.util.Collections.synchronizedSet;
 
@@ -58,25 +56,11 @@
     private UiExtension uiExtension = new UiExtension(views, this::newHandlers,
                                                       getClass().getClassLoader());
 
-    private List<String> headers = ImmutableList.of("One", "Two", "Three", "Four", "Five");
-
-    private Random random = new Random();
-    private TimerTask task;
+    private IntentPerfCollector collector;
 
     @Activate
     protected void activate() {
         uiExtensionService.register(uiExtension);
-//        task = new TimerTask() {
-//            @Override
-//            public void run() {
-//                Sample sample = new Sample(System.currentTimeMillis(), headers.size());
-//                for (int i = 0; i < headers.size(); i++) {
-//                    sample.data[i] = 25_000 + random.nextInt(20_000) - 5_000;
-//                }
-//                reportSample(sample);
-//            }
-//        };
-//        SharedExecutors.getTimer().scheduleAtFixedRate(task, 1000, 1000);
     }
 
     @Deactivate
@@ -96,12 +80,12 @@
     }
 
     /**
-     * Sets the headers for the subsequently reported samples.
+     * Binds the sample collector.
      *
-     * @param headers list of headers for future samples
+     * @param collector list of headers for future samples
      */
-    public void setHeaders(List<String> headers) {
-        this.headers = headers;
+    public void setCollector(IntentPerfCollector collector) {
+        this.collector = collector;
     }
 
     // Creates and returns session specific message handler.
@@ -122,22 +106,10 @@
         public void process(ObjectNode message) {
             streamingEnabled = message.path("event").asText("unknown").equals("intentPerfStart");
             if (streamingEnabled) {
-                sendHeaders();
+                sendInitData();
             }
         }
 
-        private void sendHeaders() {
-            ArrayNode an = mapper.createArrayNode();
-            for (String header : headers) {
-                an.add(header);
-            }
-
-            ObjectNode sn = mapper.createObjectNode();
-            sn.set("headers", an);
-
-            connection().sendMessage("intentPerfHeaders", 0, sn);
-        }
-
         @Override
         public void init(UiConnection connection, ServiceDirectory directory) {
             super.init(connection, directory);
@@ -152,18 +124,34 @@
 
         private void send(Sample sample) {
             if (streamingEnabled) {
-                ArrayNode an = mapper.createArrayNode();
-                for (double d : sample.data) {
-                    an.add(d);
-                }
-
-                ObjectNode sn = mapper.createObjectNode();
-                sn.put("time", sample.time);
-                sn.set("data", an);
-
-                connection().sendMessage("intentPerfSample", 0, sn);
+                connection().sendMessage("intentPerfSample", 0, sampleNode(sample));
             }
         }
+
+        private void sendInitData() {
+            ObjectNode rootNode = mapper.createObjectNode();
+            ArrayNode an = mapper.createArrayNode();
+            ArrayNode sn = mapper.createArrayNode();
+            rootNode.set("headers", an);
+            rootNode.set("samples", sn);
+
+            collector.getSampleHeaders().forEach(an::add);
+            collector.getSamples().forEach(s -> sn.add(sampleNode(s)));
+            connection().sendMessage("intentPerfInit", 0, rootNode);
+        }
+
+        private ObjectNode sampleNode(Sample sample) {
+            ObjectNode sampleNode = mapper.createObjectNode();
+            ArrayNode an = mapper.createArrayNode();
+            sampleNode.put("time", sample.time);
+            sampleNode.set("data", an);
+
+            for (double d : sample.data) {
+                an.add(d);
+            }
+            return sampleNode;
+        }
+
     }
 
 }