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;
+ }
+
}
}
diff --git a/apps/test/intent-perf/src/main/resources/app/view/intentPerf/Xdata.csv b/apps/test/intent-perf/src/main/resources/app/view/intentPerf/Xdata.csv
deleted file mode 100644
index 1673d26..0000000
--- a/apps/test/intent-perf/src/main/resources/app/view/intentPerf/Xdata.csv
+++ /dev/null
@@ -1,19 +0,0 @@
-date,value,node
-00:55:15,68.38,node1
-00:55:15,55.61,node2
-00:55:15,74.00,node3
-00:55:30,74.20,node1
-00:55:30,77.60,node2
-00:55:30,74.80,node3
-00:55:45,74.60,node1
-00:55:45,72.80,node2
-00:55:45,77.00,node3
-00:56:00,73.60,node1
-00:56:00,75.00,node2
-00:56:00,76.98,node3
-00:56:15,75.82,node1
-00:56:15,75.40,node2
-00:56:15,76.00,node3
-00:56:30,75.60,node1
-00:56:30,74.59,node2
-00:56:30,74.01,node3
\ No newline at end of file
diff --git a/apps/test/intent-perf/src/main/resources/app/view/intentPerf/data.csv b/apps/test/intent-perf/src/main/resources/app/view/intentPerf/data.csv
deleted file mode 100644
index f8f9938..0000000
--- a/apps/test/intent-perf/src/main/resources/app/view/intentPerf/data.csv
+++ /dev/null
@@ -1,19 +0,0 @@
-key,value,date
-Group1,37,00:23:00
-Group2,12,00:23:00
-Group3,46,00:23:00
-Group1,32,00:23:05
-Group2,19,00:23:05
-Group3,42,00:23:05
-Group1,45,00:23:10
-Group2,16,00:23:10
-Group3,44,00:23:10
-Group1,24,00:23:15
-Group2,52,00:23:15
-Group3,64,00:23:15
-Group1,34,00:23:20
-Group2,62,00:23:20
-Group3,74,00:23:20
-Group1,34,00:23:25
-Group2,62,00:23:25
-Group3,74,00:23:25
\ No newline at end of file
diff --git a/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.css b/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.css
index d98b620..15e95d5 100644
--- a/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.css
+++ b/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.css
@@ -22,9 +22,8 @@
font: 12px sans-serif;
}
-.line {
+.line,.lineTotal {
fill: none;
- stroke: #000;
stroke-width: 2px;
}
@@ -37,16 +36,20 @@
.light .axis path,
.light .axis line,
+.light .lineTotal {
+ stroke: #333;
+}
+
.light .axis text {
- stroke: #999;
+ fill: #333;
}
.dark .axis path,
.dark .axis line,
-.dark .axis text {
+.dark .lineTotal {
stroke: #eee;
}
-.axis text {
- stroke-width: 0.3;
-}
\ No newline at end of file
+.dark .axis text {
+ fill: #eee;
+}
diff --git a/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.js b/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.js
index b578163..94304c7 100644
--- a/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.js
+++ b/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.js
@@ -31,7 +31,7 @@
// ==========================
- function createGraph(h) {
+ function createGraph(h, samples) {
var stopped = false,
n = 243,
duration = 750,
@@ -75,7 +75,27 @@
headers.forEach(function (h, li) {
// Prime the data to match the headers and zero it out.
data[li] = d3.range(n).map(function() { return 0 });
- theSample[li] = 0;
+
+ if (li < headers.length - 1) {
+ samples.forEach(function (s, i) {
+ var di = dataIndex(s.time);
+ if (di >= 0) {
+ data[li][di] = s.data[li];
+ }
+ });
+
+ data[li].forEach(function (d, i) {
+ if (!d && i > 0) {
+ data[li][i] = data[li][i - 1];
+ }
+ });
+ } else {
+ data[li].forEach(function (t, i) {
+ for (var si = 0; si < headers.length - 1; si++) {
+ data[li][i] = data[si][i];
+ }
+ });
+ }
// Create the lines
lines[li] = d3.svg.line()
@@ -88,15 +108,24 @@
.attr("clip-path", "url(#intent-perf-clip)")
.append("path")
.datum(function () { return data[li]; })
- .attr("id", "line" + li)
- .style("stroke", lineColor(li))
- .attr("class", "line");
+ .attr("id", "line" + li);
+
+ if (li < headers.length - 1) {
+ paths[li].attr("class", "line").style("stroke", lineColor(li));
+ } else {
+ paths[li].attr("class", "lineTotal");
+ }
});
+ function dataIndex(time) {
+ var delta = now.getTime() - time;
+ var di = Math.round(n - 2 - (delta / duration));
+ // $log.info('now=' + now.getTime() + '; then=' + time + '; delta=' + delta + '; di=' + di + ';');
+ return di >= n || di < 0 ? -1 : di;
+ }
+
function lineColor(li) {
- return li < headers.length - 1 ?
- sus.cat7().getColor(li, false, ts.theme()) :
- ts.theme() === 'light' ? '#333' : '#eee';
+ return sus.cat7().getColor(li, false, ts.theme());
}
function tick() {
@@ -130,13 +159,17 @@
function start() {
stopped = false;
headers.forEach(function (h, li) {
- theSample[li] = 0;
+ theSample[li] = data[li][n-1];
});
tick();
}
function stop() {
- stopped = true;
+ headers.forEach(function (h, li) {
+ theSample[li] = 0;
+ });
+ // Schedule delayed stop to allow 0s to render.
+ setTimeout(function () { stopped = true; }, 1000);
}
function resize(dim) {
@@ -190,7 +223,7 @@
function createAndInitGraph(d) {
if (!graph) {
d.headers.push("total");
- graph = createGraph(d.headers);
+ graph = createGraph(d.headers, d.samples);
}
graph.start();
}
@@ -213,7 +246,7 @@
function createHandlerMap() {
handlerMap = {
- intentPerfHeaders: createAndInitGraph,
+ intentPerfInit: createAndInitGraph,
intentPerfSample: recordSample
};
}
diff --git a/apps/test/intent-perf/src/main/resources/sliding.html b/apps/test/intent-perf/src/main/resources/sliding.html
deleted file mode 100644
index 8dc501b..0000000
--- a/apps/test/intent-perf/src/main/resources/sliding.html
+++ /dev/null
@@ -1,205 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<style>
-
- svg {
- font: 10px sans-serif;
- }
-
- .line {
- fill: none;
- stroke: darkgreen;
- stroke-width: 2px;
- }
-
- .axis path,
- .axis line {
- fill: none;
- stroke: #999;
- stroke-width: 2px;
- shape-rendering: crispEdges;
- }
-
-</style>
-<body>
-<script src="http://d3js.org/d3.v3.min.js"></script>
-<script>
- (function () {
- var cs = 0,
- samples = [
- 89.53,
- 37515.81,
- 104609.6,
- 113105.11,
- 103194.74,
- 122151.63,
- 128623.9,
- 137325.33,
- 154897.31,
- 161235.07,
- 162025.4,
- 164902.64,
- 158196.26,
- 161072.44,
- 160792.54,
- 164692.44,
- 161979.74,
- 162137.4,
- 159325.19,
- 170465.44,
- 168186.46,
- 171152.34,
- 168221.02,
- 167440.73,
- 165003.39,
- 166855.18,
- 157268.79,
- 164087.54,
- 162265.21,
- 165990.16,
- 176364.01,
- 172064.07,
- 184872.24,
- 183249.8,
- 182282.47,
- 171475.11,
- 158880.58,
- 166016.69,
- 168233.16,
- 177759.92,
- 179742.87,
- 170819.44,
- 167577.73,
- 169479.9,
- 175544.89,
- 183792.01,
- 184689.52,
- 178503.87,
- 173219.27,
- 179085.49,
- 179700.54,
- 174281.17,
- 181353.08,
- 180173.14,
- 184093.16,
- 186011.5,
- 176952.79,
- 175319.2,
- 169001.05,
- 174545.12,
- 169156.29,
- 171804.3,
- 159155.54,
- 154709.96,
- 157263.97
- ],
- theSample,
- headers = [ "Whole", "Half", "Third" ];
-
- var n = 243,
- duration = 750,
- now = new Date(Date.now() - duration),
- data = [];
-
- headers.forEach(function (d, li) {
- data[li] = d3.range(n).map(function () { return 0; });
- });
-
- var margin = {top: 20, right: 100, bottom: 20, left: 100},
- width = 960 - margin.right,
- height = 512 - margin.top - margin.bottom;
-
- var x = d3.time.scale()
- .domain([now - (n - 2) * duration, now - duration])
- .range([0, width]);
-
- var y = d3.scale.linear()
- .domain([0, 200000])
- .range([height, 0]);
-
- var svg = d3.select("body").append("p").append("svg")
- .attr("width", width + margin.left + margin.right)
- .attr("height", height + margin.top + margin.bottom)
- .append("g")
- .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
-
- svg.append("defs").append("clipPath")
- .attr("id", "clip")
- .append("rect")
- .attr("width", width)
- .attr("height", height);
-
- var axis = svg.append("g")
- .attr("class", "x axis")
- .attr("transform", "translate(0," + height + ")")
- .call(x.axis = d3.svg.axis().scale(x).orient("bottom"));
-
- svg.append("g")
- .attr("class", "y axis")
- .call(d3.svg.axis().scale(y).orient("left"));
-
- svg.append("g")
- .attr("class", "y axis")
- .attr("transform", "translate(" + width + " ,0)")
- .call(d3.svg.axis().scale(y).orient("right"));
-
- var lines = [], paths = [];
- data.forEach(function (p, li) {
- lines[li]= d3.svg.line()
- .interpolate("basis")
- .x(function (d, i) {
- return x(now - (n - 1 - i) * duration);
- })
- .y(function (d, i) {
- return y(d);
- });
-
- paths[li] = svg.append("g")
- .attr("clip-path", "url(#clip)")
- .append("path")
- .datum(function () { return data[li]; })
- .attr("id", "line" + li)
- .attr("class", "line");
- });
-
- var transition = d3.select({}).transition()
- .duration(750)
- .ease("linear");
-
- function tick() {
- transition = transition.each(function () {
- // update the domains
- now = new Date();
- x.domain([now - (n - 2) * duration, now - duration]);
-
- data.forEach(function (d, li) {
- // push the new most recent sample onto the back
- d.push(theSample[li]);
-
- // redraw the line and slide it left
- paths[li].attr("d", lines[li]).attr("transform", null);
- paths[li].transition().attr("transform", "translate(" + x(now - (n - 1) * duration) + ")");
-
- // pop the old data point off the front
- d.shift();
- });
-
- // slide the x-axis left
- axis.call(x.axis);
-
- }).transition().each("start", tick);
- }
-
- function setSample() {
- var v = samples[cs++];
- theSample = [ v, v/2, v/3 ];
- }
-
- setSample();
- setInterval(setSample, 1000);
- tick();
-
- })()
-</script>
-</body>
-</html>