You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ea...@apache.org on 2018/11/17 16:43:30 UTC
qpid-dispatch git commit: DISPATCH-1168 Display additional detail on
console's topology page
Repository: qpid-dispatch
Updated Branches:
refs/heads/master e94f12579 -> 342dc04e7
DISPATCH-1168 Display additional detail on console's topology page
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/342dc04e
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/342dc04e
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/342dc04e
Branch: refs/heads/master
Commit: 342dc04e76556d034ac2230b58ec4b22f829f301
Parents: e94f125
Author: Ernest Allen <ea...@redhat.com>
Authored: Sat Nov 17 11:43:14 2018 -0500
Committer: Ernest Allen <ea...@redhat.com>
Committed: Sat Nov 17 11:43:14 2018 -0500
----------------------------------------------------------------------
.../plugin/html/tmplClientDetail.html | 184 ++++++++++++++++++-
console/stand-alone/plugin/js/amqp/utilities.js | 49 ++++-
.../plugin/js/dlgDetailController.js | 140 +++++++++++---
console/stand-alone/plugin/js/topology/map.js | 7 +-
console/stand-alone/plugin/js/topology/nodes.js | 12 +-
.../plugin/js/topology/qdrTopology.js | 8 +-
.../stand-alone/plugin/js/topology/topoUtils.js | 71 +++----
.../stand-alone/plugin/js/topology/traffic.js | 7 +-
8 files changed, 377 insertions(+), 101 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/342dc04e/console/stand-alone/plugin/html/tmplClientDetail.html
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/html/tmplClientDetail.html b/console/stand-alone/plugin/html/tmplClientDetail.html
index 18d985c..1195ab2 100644
--- a/console/stand-alone/plugin/html/tmplClientDetail.html
+++ b/console/stand-alone/plugin/html/tmplClientDetail.html
@@ -19,9 +19,33 @@
<style>
div.details {
- max-height: 20em;
+ max-height: 21em;
overflow: auto;
}
+
+ table td.right {
+ text-align: right;
+ }
+ table td {
+ padding: .4em;
+ border-right: 1px solid #F0F0F0;
+ }
+ table tr.odd {
+ background-color: #F0F0F0;
+ }
+ table td.expander {
+ cursor: pointer;
+ width: 1em;
+ }
+ table tr.hiddenRow {
+ display: none;
+ }
+ div.details {
+ width: 100%;
+ }
+ div.details span.right {
+ float: right;
+ }
</style>
<!--
This is the template for the client detail popup displayed when a group
@@ -29,12 +53,164 @@
-->
<div>
<div class="modal-header">
- <h3 class="modal-title">Detail for {{detail.title | safePlural}}</h3>
+ <h3 class="modal-title">Detail for {{detail.title}}</h3>
</div>
<div class="modal-body">
- <div class="details" ng-bind-html="detail.details"></div>
+ <h4>{{detail.description}}</h4>
+ <div class="details" ng-include="detail.template">
+ </div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="okClick()">Close</button>
</div>
-</div>
\ No newline at end of file
+</div>
+
+<script type="text/ng-template" id="clients.html">
+ <table class="table table-striped table-bordered table-hover dataTable no-footer">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Container</th>
+ <th>Encrypted</th>
+ <th>Host</th>
+ <th>Links</th>
+ </tr>
+ </thead>
+ <tr ng-repeat-start="(key, value) in detail.infoPerId"
+ ng-class="{even: $even, odd: $odd}"
+ ng-click="expandClicked(key)">
+ <td class="expander">
+ <span class="fa"
+ ng-class="expanded(key) ? 'fa-angle-down' : 'fa-angle-right'"
+ ></span>
+ </td>
+ <td>{{key}}</td><!-- Id -->
+ <td class="right">{{value.encrypted}}</td>
+ <td class="right">{{value.host}}</td>
+ <td class="right">{{value.linkCount}}</td>
+ </tr>
+ <tr ng-repeat-end
+ ng-class="{hiddenRow: !expanded(key)}"
+ ng-click="expandClicked(key)"
+ >
+ <td colspan="6">
+ <table class="table table-striped table-bordered dataTable no-footer">
+ <thead>
+ <tr>
+ <td ng-repeat="field in linkFields">
+ {{field | humanify}}
+ </td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="link in value.links">
+ <td ng-repeat="field in linkFields">
+ {{link[field] | pretty }}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </table>
+</script>
+
+<script type="text/ng-template" id="consoles.html">
+ here be console info
+</script>
+
+<script type="text/ng-template" id="edgeRouters.html">
+ <table class="table table-striped table-bordered table-hover dataTable no-footer">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Id</th>
+ <th>Link Routes</th>
+ <th>Auto Links</th>
+ <th>Conns</th>
+ <th>Addrs</th>
+ <th>Accepted</td>
+ </tr>
+ </thead>
+ <tr ng-repeat-start="(key, value) in detail.infoPerId"
+ ng-class="{even: $even, odd: $odd}"
+ ng-click="expandClicked(key)">
+ <td class="expander">
+ <span class="fa"
+ ng-class="expanded(key) ? 'fa-angle-down' : 'fa-angle-right'"
+ ></span>
+ </td>
+ <td>{{key}}</td><!-- Id -->
+ <td class="right">{{value.linkRouteCount}}</td>
+ <td class="right">{{value.autoLinkCount}}</td>
+ <td class="right">{{value.connectionCount}}</td>
+ <td class="right">{{value.addrCount}}</td>
+ <td class="right">{{value.acceptedDeliveries | pretty}}</td>
+ </tr>
+ <tr ng-repeat-end
+ ng-class="{hiddenRow: !expanded(key)}"
+ ng-click="expandClicked(key)"
+ >
+ <td colspan="7">
+ <h4>Edge router details</h4>
+ <table class="table table-striped table-bordered dataTable no-footer">
+ <tr ng-repeat="field in detailFields">
+ <td>{{field | humanify}}</td>
+ <td>{{value[field] | pretty}}</td>
+ </tr>
+ </table>
+ <h4>Link routes</h4>
+ <table class="table table-striped table-bordered dataTable no-footer">
+ <thead>
+ <tr>
+ <td ng-repeat="field in linkRouteFields">
+ {{field | humanify}}
+ </td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="link in value.linkRoutes">
+ <td ng-repeat="field in linkRouteFields">
+ {{link[field] | pretty }}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <h4>Autolinks</h4>
+ <table class="table table-striped table-bordered dataTable no-footer">
+ <thead>
+ <tr>
+ <td ng-repeat="field in autoLinkFields">
+ {{field | humanify}}
+ </td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="link in value.autoLinks">
+ <td ng-repeat="field in autoLinkFields">
+ {{link[field] | pretty }}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <h4>Addresses</h4>
+ <table class="table table-striped table-bordered dataTable no-footer">
+ <thead>
+ <tr>
+ <td ng-repeat="field in addressFields">
+ {{field | humanify}}
+ </td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="link in value.addresses">
+ <td ng-repeat="field in addressFields">
+ {{link[field] | pretty }}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </table>
+</script>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/342dc04e/console/stand-alone/plugin/js/amqp/utilities.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/amqp/utilities.js b/console/stand-alone/plugin/js/amqp/utilities.js
index 3f69002..c092bf4 100644
--- a/console/stand-alone/plugin/js/amqp/utilities.js
+++ b/console/stand-alone/plugin/js/amqp/utilities.js
@@ -46,6 +46,13 @@ var utils = {
});
return flat;
},
+ flattenAll: function (entity) {
+ let results = [];
+ for (let i=0; i<entity.results.length; i++) {
+ results.push(this.flatten(entity.attributeNames, entity.results[i]));
+ }
+ return results;
+ },
copy: function (obj) {
if (obj)
return JSON.parse(JSON.stringify(obj));
@@ -107,15 +114,16 @@ var utils = {
}
return null;
},
- // count the number records with a specific value for a field
- countFor: function (aAr, vAr, key, val) {
- let count = 0;
+ // return a map with unique values and their counts for a field
+ countsFor: function (aAr, vAr, key) {
+ let counts = {};
let idx = aAr.indexOf(key);
for (let i=0; i<vAr.length; i++) {
- if (vAr[idx] === val)
- count++;
+ if (!counts[vAr[i][idx]])
+ counts[vAr[i][idx]] = 0;
+ counts[vAr[i][idx]]++;
}
- return count;
+ return counts;
},
// extract the name of the router from the router id
nameFromId: function (id) {
@@ -173,6 +181,35 @@ var utils = {
rates[field] = list.length > 1 ? cumulative / (list.length-1) : 0;
}
return rates;
+ },
+ connSecurity: function (conn) {
+ if (!conn.isEncrypted)
+ return 'no-security';
+ if (conn.sasl === 'GSSAPI')
+ return 'Kerberos';
+ return conn.sslProto + '(' + conn.sslCipher + ')';
+ },
+ connAuth: function (conn) {
+ if (!conn.isAuthenticated)
+ return 'no-auth';
+ let sasl = conn.sasl;
+ if (sasl === 'GSSAPI')
+ sasl = 'Kerberos';
+ else if (sasl === 'EXTERNAL')
+ sasl = 'x.509';
+ else if (sasl === 'ANONYMOUS')
+ return 'anonymous-user';
+ if (!conn.user)
+ return sasl;
+ return conn.user + '(' + sasl + ')';
+ },
+ connTenant: function (conn) {
+ if (!conn.tenant) {
+ return '';
+ }
+ if (conn.tenant.length > 1)
+ return conn.tenant.replace(/\/$/, '');
}
+
};
export { utils };
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/342dc04e/console/stand-alone/plugin/js/dlgDetailController.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/dlgDetailController.js b/console/stand-alone/plugin/js/dlgDetailController.js
index 4ada0d8..f95d529 100644
--- a/console/stand-alone/plugin/js/dlgDetailController.js
+++ b/console/stand-alone/plugin/js/dlgDetailController.js
@@ -22,54 +22,137 @@ export class DetailDialogController {
constructor(QDRService, $scope, $timeout, $uibModalInstance, $sce, d) {
this.controllerName = 'QDR.DetailDialogController';
+ let expandedRows = new Set();
$scope.d = d; // the node object
$scope.detail = {
- title: d.normals.length + ' ' + (d.nodeType === 'edge' ? 'edge routers' : 'clients'),
- header: '',
- details: 'loading...'
+ template: 'edgeRouters.html'
};
+ $scope.detailFields = [
+ 'version',
+ 'mode',
+ 'presettledDeliveries',
+ 'droppedPresettledDeliveries',
+ 'acceptedDeliveries',
+ 'rejectedDeliveries',
+ 'releasedDeliveries',
+ 'modifiedDeliveries',
+ 'deliveriesIngress',
+ 'deliveriesEgress',
+ 'deliveriesTransit',
+ 'deliveriesIngressRouteContainer',
+ 'deliveriesEgressRouteContainer'
+ ];
+ $scope.linkFields = [
+ 'linkType',
+ 'owningAddr',
+ 'priority',
+ 'acceptedCount',
+ 'unsettledCount'
+ ];
+ $scope.linkRouteFields = [
+ 'prefix',
+ 'direction',
+ 'containerId'
+ ];
+ $scope.autoLinkFields = [
+ 'addr',
+ 'direction',
+ 'containerId'
+ ];
+ $scope.addressFields = [
+ 'prefix',
+ 'distribution'
+ ];
$scope.okClick = function () {
$uibModalInstance.close(true);
};
+ $scope.expandClicked = function (id) {
+ if (expandedRows.has(id)) {
+ expandedRows.delete(id);
+ } else {
+ expandedRows.add(id);
+ }
+ };
+ $scope.expanded = function (id) {
+ return expandedRows.has(id);
+ };
+
let groupDetail = function () {
- let q_getEdgeInfo = function (n, response, callback) {
+ let q_getEdgeInfo = function (n, infoPerId, callback) {
let nodeId = QDRService.utilities.idFromName(n.container, '_edge');
QDRService.management.topology.fetchEntities(nodeId,
- [{entity: 'connection', attrs: []},
- {entity: 'router.link', attrs: []}],
+ [{entity: 'router', attrs: []},
+ {entity: 'router.link', attrs: []},
+ {entity: 'linkRoute', attrs: $scope.linkRouteFields},
+ {entity: 'autoLink', attrs: $scope.autoLinkFields},
+ {entity: 'address', attrs: []},
+ ],
function (results) {
- response.HTML += '<tr>';
- response.HTML += `<td>${QDRService.utilities.nameFromId(nodeId)}</td>`;
-
- let connection = results[nodeId].connection;
- // count endpoint connections
- let endpoints = QDRService.utilities.countFor(connection.attributeNames, connection.results, 'role', 'endpoint');
- response.HTML += `<td align='right'>${endpoints}</td>`;
-
- //let link = results[nodeId]['router.link'];
- //let conn = QDRService.utilities.flatten(results.attributeNames, )
- response.HTML += '</tr>';
+ let r = results[nodeId].router;
+ infoPerId[n.container] = QDRService.utilities.flatten(r.attributeNames, r.results[0]);
+ infoPerId[n.container].linkRoutes = QDRService.utilities.flattenAll(results[nodeId].linkRoute);
+ infoPerId[n.container].autoLinks = QDRService.utilities.flattenAll(results[nodeId].autoLink);
+ infoPerId[n.container].addresses = QDRService.utilities.flattenAll(results[nodeId].address);
callback(null);
});
};
return new Promise( (function (resolve) {
- let response = {
- header: '<table><tr><td>Id</td><td>Endpoints</td></tr></table>',
- HTML: '<table><tr><td>Id</td><td>endpoints</td></tr>'
- };
+ let infoPerId = {};
if (d.nodeType === 'edge') {
+ $scope.detail.template = 'edgeRouters.html';
+ $scope.detail.title = 'edge router';
let q = d3.queue(10);
for (let n=0; n<d.normals.length; n++) {
- q.defer(q_getEdgeInfo, d.normals[n], response);
+ q.defer(q_getEdgeInfo, d.normals[n], infoPerId);
}
q.await(function () {
- response.HTML += '</table>';
- resolve(response);
+ resolve({
+ description: 'Expand an edge router to see more info',
+ infoPerId: infoPerId
+ });
+ });
+ } else if (d.isConsole) {
+ $scope.detail.template = 'consoles.html';
+ $scope.detail.title = 'console';
+ resolve({
+ description: ''
});
} else {
- response.HTML += '<tr><td>Details for clients go here</td</tr></table>';
- resolve(response);
+ $scope.detail.template = 'clients.html';
+ $scope.detail.title = 'client';
+ QDRService.management.topology.fetchEntities(d.key,
+ [{entity: 'router.link', attrs: []}],
+ function (results) {
+ let links = results[d.key]['router.link'];
+ for (let i=0; i<d.normals.length; i++) {
+ let n = d.normals[i];
+ let conn = {};
+ let connectionIndex = links.attributeNames.indexOf('connectionId');
+ infoPerId[n.container] = conn;
+ conn.container = n.container;
+ conn.encrypted = n.encrypted;
+ conn.host = n.host;
+ conn.links = [];
+ for (let l=0; l<links.results.length; l++) {
+ if (links.results[l][connectionIndex] === n.connectionId) {
+ let link = QDRService.utilities.flatten(links.attributeNames, links.results[l]);
+ link.owningAddr = QDRService.utilities.addr_text(link.owningAddr);
+ conn.links.push(link);
+ }
+ }
+ conn.linkCount = conn.links.length;
+ }
+ let dir = d.cdir === 'in' ? 'inbound' : d.cdir === 'both' ? 'in and outbound' : 'outbound';
+ let count = d.normals.length;
+ let verb = count > 1 ? 'are' : 'is';
+ let preposition = d.cdir === 'in' ? 'to' : d.cdir === 'both' ? 'for' : 'from';
+ let plural = count > 1 ? 's': '';
+ resolve({
+ description: `There ${verb} ${count} ${dir} connection${plural} ${preposition} ${d.routerId} with role ${d.nodeType}`,
+ infoPerId: infoPerId
+ });
+ });
}
}));
};
@@ -77,8 +160,9 @@ export class DetailDialogController {
groupDetail()
.then( function (det) {
$timeout( function () {
- $scope.detail.header = $sce.trustAsHtml(det.header);
- $scope.detail.details = $sce.trustAsHtml(det.HTML);
+ $scope.detail.title = `${d.normals.length} ${$scope.detail.title}${d.normals.length > 1 ? 's' : ''}`;
+ $scope.detail.description = det.description;
+ $scope.detail.infoPerId = det.infoPerId;
});
});
}
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/342dc04e/console/stand-alone/plugin/js/topology/map.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/map.js b/console/stand-alone/plugin/js/topology/map.js
index 9886245..c14008d 100644
--- a/console/stand-alone/plugin/js/topology/map.js
+++ b/console/stand-alone/plugin/js/topology/map.js
@@ -31,7 +31,7 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
this.initialized = false;
this.notify = notifyFn;
$scope.mapOptions = angular.fromJson(localStorage[MAPOPTIONSKEY]) || {areaColor: defaultLandColor, oceanColor: defaultOceanColor};
- initLast(this);
+ this.last = {translate: [0,0], scale: null};
}
updateLandColor(color) {
localStorage[MAPOPTIONSKEY] = JSON.stringify(this.$scope.mapOptions);
@@ -116,7 +116,6 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
.on('dblclick.zoom', null);
// async load of data file. calls resolve when this completes to let caller know
- //d3.json('plugin/data/world-110m.json', function(error, world) {
d3.json('plugin/data/countries.json', function(error, world) {
if (error)
reject(error);
@@ -249,7 +248,3 @@ function getMapBounds(projection, maxlat) {
return [xymin,xymax];
}
-function initLast(map) {
- map.last = {translate: [0,0], scale: null};
-}
-
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/342dc04e/console/stand-alone/plugin/js/topology/nodes.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/nodes.js b/console/stand-alone/plugin/js/topology/nodes.js
index 22ee458..411f942 100644
--- a/console/stand-alone/plugin/js/topology/nodes.js
+++ b/console/stand-alone/plugin/js/topology/nodes.js
@@ -35,9 +35,9 @@ export class Node {
this.isConsole = QDRService.utilities.isConsole(this);
this.isArtemis = QDRService.utilities.isArtemis(this);
}
- title () {
+ title (hide) {
let x = '';
- if (this.normals && this.normals.length > 1)
+ if (this.normals && this.normals.length > 1 && !hide)
x = ' x ' + this.normals.length;
if (this.isConsole)
return 'Dispatch console' + x;
@@ -77,7 +77,7 @@ export class Node {
}
clientTooltip () {
- let type = this.title();
+ let type = this.title(true);
let title = '';
title += `<table class="popupTable"><tr><td>Type</td><td>${type}</td></tr>`;
if (!this.normals || this.normals.length < 2)
@@ -85,8 +85,8 @@ export class Node {
else {
title += `<tr><td>Count</td><td>${this.normals.length}</td></tr>`;
}
- //title += '<tr><td colspan=2 class="more-info">Click circle for more info</td></tr></table>';
- title += '</table>';
+ if (!this.isConsole && !this.isArtemis)
+ title += '<tr><td colspan=2 class="more-info">Click circle for more info</td></tr></table>';
return title;
}
@@ -268,7 +268,7 @@ export class Nodes {
}
// Convert node's x,y coordinates to longitude, lattitude
saveLonLat (backgroundMap, nodes) {
- if (!backgroundMap)
+ if (!backgroundMap || !backgroundMap.initialized)
return;
// didn't pass nodes, use all nodes
if (!nodes)
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/342dc04e/console/stand-alone/plugin/js/topology/qdrTopology.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/qdrTopology.js b/console/stand-alone/plugin/js/topology/qdrTopology.js
index aa5aea6..96a996d 100644
--- a/console/stand-alone/plugin/js/topology/qdrTopology.js
+++ b/console/stand-alone/plugin/js/topology/qdrTopology.js
@@ -495,8 +495,10 @@ export class TopologyController {
d.selected = true;
let updateTooltip = function () {
$timeout(function () {
- $scope.trustedpopoverContent = $sce.trustAsHtml(connectionPopupHTML(d, QDRService));
- displayTooltip(event);
+ if (d.selected) {
+ $scope.trustedpopoverContent = $sce.trustAsHtml(connectionPopupHTML(d, QDRService));
+ displayTooltip(event);
+ }
});
};
// update the contents of the popup tooltip each time the data is polled
@@ -658,7 +660,7 @@ export class TopologyController {
$scope.mousedown_node = null;
if (!$scope.$$phase) $scope.$apply();
// handle clicking on nodes that represent multiple sub-nodes
- if (d.normals) {
+ if (d.normals && !d.isConsole && !d.isArtemis) {
doDialog(d);
}
restart(false);
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/342dc04e/console/stand-alone/plugin/js/topology/topoUtils.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/topoUtils.js b/console/stand-alone/plugin/js/topology/topoUtils.js
index ab77a34..cbed6c0 100644
--- a/console/stand-alone/plugin/js/topology/topoUtils.js
+++ b/console/stand-alone/plugin/js/topology/topoUtils.js
@@ -66,6 +66,7 @@ export function connectionPopupHTML (d, QDRService) {
linkRateHistory = {};
return;
}
+ let utils = QDRService.utilities;
let getConnsArray = function (d, conn) {
let conns = [conn];
if (d.cls === 'small') {
@@ -73,7 +74,7 @@ export function connectionPopupHTML (d, QDRService) {
let normals = d.target.normals ? d.target.normals : d.source.normals;
for (let n=0; n<normals.length; n++) {
if (normals[n].resultIndex !== undefined) {
- conns.push(QDRService.utilities.flatten(onode['connection'].attributeNames,
+ conns.push(utils.flatten(onode['connection'].attributeNames,
onode['connection'].results[normals[n].resultIndex]));
}
}
@@ -97,7 +98,7 @@ export function connectionPopupHTML (d, QDRService) {
let out = '';
out = ar[0];
for (let i=1; i<ar.length; i++) {
- let sep = sepfn(ar[i]);
+ let sep = sepfn(ar[i], i===ar.length-1);
out += (sep[0] + sep[1]);
}
return out;
@@ -111,19 +112,23 @@ export function connectionPopupHTML (d, QDRService) {
let links = [];
let hasAddress = false;
for (let n=0; n<nodeLinks.results.length; n++) {
- let link = QDRService.utilities.flatten(nodeLinks.attributeNames, nodeLinks.results[n]);
+ let link = utils.flatten(nodeLinks.attributeNames, nodeLinks.results[n]);
+ let allZero = true;
if (link.linkType !== 'router-control') {
if (isLinkFor(link.connectionId, conns)) {
if (link.owningAddr)
hasAddress = true;
if (link.name) {
- let rate = QDRService.utilities.rates(link, fields, linkRateHistory, link.name, 1);
+ let rates = utils.rates(link, fields, linkRateHistory, link.name, 1);
// replace the raw value with the rate
for (let i=0; i<fields.length; i++) {
- link[fields[i]] = rate[fields[i]];
+ if (rates[fields[i]] > 0)
+ allZero = false;
+ link[fields[i]] = rates[fields[i]];
}
}
- links.push(link);
+ if (!allZero)
+ links.push(link);
}
}
}
@@ -148,6 +153,8 @@ export function connectionPopupHTML (d, QDRService) {
let td = fields;
th.unshift('dir');
td.unshift('linkDir');
+ th.push('priority');
+ td.push('priority');
// add an address field if any of the links had an owningAddress
if (hasAddress) {
th.unshift('address');
@@ -158,7 +165,7 @@ export function connectionPopupHTML (d, QDRService) {
let rth = th.map( function (t) {
if (t.endsWith('Count'))
t = t.replace('Count', 'Rate');
- return QDRService.utilities.humanify(t);
+ return utils.humanify(t);
});
return rth;
};
@@ -172,16 +179,20 @@ export function connectionPopupHTML (d, QDRService) {
let link = links[l];
let vals = td.map( function (f) {
if (f === 'owningAddr') {
- let identity = QDRService.utilities.identity_clean(link.owningAddr);
- return QDRService.utilities.addr_text(identity);
+ let identity = utils.identity_clean(link.owningAddr);
+ return utils.addr_text(identity);
}
return link[f];
});
- let joinedVals = fnJoin(vals, function (v1) {
- return ['</td><td' + (isNaN(+v1) ? '': ' align="right"') + '>', QDRService.utilities.pretty(v1 || '0', ',.2f')];
+ let joinedVals = fnJoin(vals, function (v1, last) {
+ return [`</td><td${(isNaN(+v1) ? '': ' align="right"')}>`, last ? v1 : utils.pretty(v1 || '0', ',.2f')];
});
HTML += `<tr><td> ${joinedVals} </td></tr>`;
}
+ // no rows were added
+ if (links.length === 0) {
+ HTML += `<tr><td align="center" colspan="${th.length}">Calculating rates, or rates were all zero</td></tr>`;
+ }
HTML += '</table>';
return HTMLHeading + HTML;
};
@@ -190,37 +201,9 @@ export function connectionPopupHTML (d, QDRService) {
// left is the connection with dir 'in'
let right = d.left ? d.target : d.source;
let onode = QDRService.management.topology.nodeInfo()[left.key];
- let connSecurity = function (conn) {
- if (!conn.isEncrypted)
- return 'no-security';
- if (conn.sasl === 'GSSAPI')
- return 'Kerberos';
- return conn.sslProto + '(' + conn.sslCipher + ')';
- };
- let connAuth = function (conn) {
- if (!conn.isAuthenticated)
- return 'no-auth';
- let sasl = conn.sasl;
- if (sasl === 'GSSAPI')
- sasl = 'Kerberos';
- else if (sasl === 'EXTERNAL')
- sasl = 'x.509';
- else if (sasl === 'ANONYMOUS')
- return 'anonymous-user';
- if (!conn.user)
- return sasl;
- return conn.user + '(' + sasl + ')';
- };
- let connTenant = function (conn) {
- if (!conn.tenant) {
- return '';
- }
- if (conn.tenant.length > 1)
- return conn.tenant.replace(/\/$/, '');
- };
// loop through all the connections for left, and find the one for right
let rightIndex = onode['connection'].results.findIndex( function (conn) {
- return QDRService.utilities.valFor(onode['connection'].attributeNames, conn, 'container') === right.routerId;
+ return utils.valFor(onode['connection'].attributeNames, conn, 'container') === right.routerId;
});
if (rightIndex < 0) {
// we have a connection to a client/service
@@ -233,16 +216,16 @@ export function connectionPopupHTML (d, QDRService) {
let HTML = '';
if (rightIndex >= 0) {
let conn = onode['connection'].results[rightIndex];
- conn = QDRService.utilities.flatten(onode['connection'].attributeNames, conn);
+ conn = utils.flatten(onode['connection'].attributeNames, conn);
let conns = getConnsArray(d, conn);
if (conns.length === 1) {
HTML += '<h5>Connection'+(conns.length > 1 ? 's' : '')+'</h5>';
HTML += '<table class="popupTable"><tr class="header"><td>Security</td><td>Authentication</td><td>Tenant</td><td>Host</td>';
for (let c=0; c<conns.length; c++) {
- HTML += ('<tr><td>' + connSecurity(conns[c]) + '</td>');
- HTML += ('<td>' + connAuth(conns[c]) + '</td>');
- HTML += ('<td>' + (connTenant(conns[c]) || '--') + '</td>');
+ HTML += ('<tr><td>' + utils.connSecurity(conns[c]) + '</td>');
+ HTML += ('<td>' + utils.connAuth(conns[c]) + '</td>');
+ HTML += ('<td>' + (utils.connTenant(conns[c]) || '--') + '</td>');
HTML += ('<td>' + conns[c].host + '</td>');
HTML += '</tr>';
}
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/342dc04e/console/stand-alone/plugin/js/topology/traffic.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/traffic.js b/console/stand-alone/plugin/js/topology/traffic.js
index 610e01f..9727f3f 100644
--- a/console/stand-alone/plugin/js/topology/traffic.js
+++ b/console/stand-alone/plugin/js/topology/traffic.js
@@ -449,16 +449,16 @@ class Dots extends TrafficAnimation {
const ioa = links.attributeNames.indexOf('owningAddr');
const ici = links.attributeNames.indexOf('connectionId');
const ild = links.attributeNames.indexOf('linkDir');
- let linkIndex = links.results.findIndex( function (l) {
+ let foundLinks = links.results.filter( function (l) {
return (l[ilt] === 'endpoint' || l[ilt] === 'edge-downlink') &&
address === this.traffic.QDRService.utilities.addr_text(l[ioa]) &&
l[ild] === cdir;
}, this);
- if (linkIndex >= 0) {
+ for (let linkIndex=0; linkIndex<foundLinks.length; linkIndex++) {
let nodeIndex = nodes.findIndex( function (node) {
if (node.normals && node.key === key && (node.cdir === cdir || node.cdir === 'both')) {
let ni = node.normals.findIndex( function (normal) {
- return normal.connectionId === links.results[linkIndex][ici];
+ return normal.connectionId === foundLinks[linkIndex][ici];
});
return ni >= 0;
} else
@@ -471,7 +471,6 @@ class Dots extends TrafficAnimation {
if (!hops[key])
hops[key] = [];
hops[key].push({ val: val, back: !sender, address: address });
- return;
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org