You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by jd...@apache.org on 2020/09/17 14:38:24 UTC

[qpid-dispatch] branch master updated: DISPATCH-1775 Restore console tests added in DISPATCH-1049 and removed in DISPATCH-1358 (#846)

This is an automated email from the ASF dual-hosted git repository.

jdanek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/master by this push:
     new 5b7779f  DISPATCH-1775 Restore console tests added in DISPATCH-1049 and removed in DISPATCH-1358 (#846)
5b7779f is described below

commit 5b7779f5a8097b5a6a88357af0f3f7e895970164
Author: Jiri Daněk <jd...@redhat.com>
AuthorDate: Thu Sep 17 16:38:13 2020 +0200

    DISPATCH-1775 Restore console tests added in DISPATCH-1049 and removed in DISPATCH-1358 (#846)
---
 console/react/src/chord/filters.test.js         |   74 ++
 console/react/src/chord/matrix.test.js          |   48 +
 console/react/src/common/amqp/utilities.test.js |  211 +++++
 console/react/src/topology/links.test.js        |  105 ++
 console/react/test_data/nodes-edge.json         | 1156 +++++++++++++++++++++++
 console/react/test_data/nodes.json              |    1 +
 6 files changed, 1595 insertions(+)

diff --git a/console/react/src/chord/filters.test.js b/console/react/src/chord/filters.test.js
new file mode 100644
index 0000000..9fc2828
--- /dev/null
+++ b/console/react/src/chord/filters.test.js
@@ -0,0 +1,74 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import {aggregateAddresses, separateAddresses} from './filters.js';
+
+describe('Filters', function() {
+  const MIN_VALUE = 1,
+    MAX_VALUE = 2;
+  const values = [
+    {ingress: 'A', egress: 'B', address: 'toB', messages: MIN_VALUE, key: 'BAtoB'},
+    {ingress: 'B', egress: 'A', address: 'toA', messages: MAX_VALUE, key: 'ABtoA'}
+  ];
+
+  describe('#aggregateAddresses', function() {
+    let m = aggregateAddresses(values, []);
+    it('should create a matrix', function() {
+      expect(m.hasValues()).toBeTruthy();
+    });
+    it('that has two rows', function() {
+      expect(m.rows.length).toEqual(2);
+    });
+    it('and has 1 chord per router', function() {
+      expect(m.getChordList().length).toEqual(2);
+    });
+    it('and contains all addresses when there is no filter', function () {
+      let minmax = m.getMinMax();
+      expect(minmax[0]).toEqual(MIN_VALUE);
+      expect(minmax[1]).toEqual(MAX_VALUE);
+    });
+    it('should filter out an address', function () {
+      let m = aggregateAddresses(values, ['toB']);
+      // if the toB address was filtered, the min value in the matrix should be 2 (for the toA address)
+      expect(m.getMinMax()[0]).toEqual(MAX_VALUE);
+    });
+  });
+  describe('#separateAddresses', function() {
+    let m = separateAddresses(values, []);
+    it('should create a matrix', function() {
+      expect(m.hasValues()).toBeTruthy();
+    });
+    it('that has a row per router/address combination', function() {
+      expect(m.rows.length).toEqual(4);
+    });
+    it('and has 1 chord per router/address combination', function() {
+      expect(m.getChordList().length).toEqual(4);
+    });
+    it('and contains all addresses when there is no filter', function () {
+      let minmax = m.getMinMax();
+      expect(minmax[0]).toEqual(MIN_VALUE);
+      expect(minmax[1]).toEqual(MAX_VALUE);
+    });
+    it('should filter out an address', function () {
+      let m = separateAddresses(values, ['toB']);
+      // if the toB address was filtered, the min value in the matrix should be 2 (for the toA address)
+      expect(m.getMinMax()[0]).toEqual(MAX_VALUE);
+    });
+  });
+});
diff --git a/console/react/src/chord/matrix.test.js b/console/react/src/chord/matrix.test.js
new file mode 100644
index 0000000..c1b8dd5
--- /dev/null
+++ b/console/react/src/chord/matrix.test.js
@@ -0,0 +1,48 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import {valuesMatrix} from './matrix.js';
+
+describe('Matrix', function() {
+  describe('#zeroInit', function() {
+    const ROW_COUNT = 10;
+    let matrix = new valuesMatrix(false);
+    matrix.zeroInit(ROW_COUNT);
+    it('should create the requested number of rows', function() {
+      expect(matrix.rows.length).toEqual(ROW_COUNT);
+    });
+    it('should create the requested number of cols per row', function() {
+      matrix.rows.forEach( function (row) {
+        expect(row.cols.length).toEqual(ROW_COUNT);
+      });
+    });
+  });
+  describe('#hasValues', function () {
+    it('should not have any values to start', function () {
+      let matrix = new valuesMatrix(false);
+      expect(matrix.hasValues()).toBeFalsy();
+    });
+    it('should have a value after adding one', function () {
+      let matrix = new valuesMatrix(false);
+      matrix.addRow('chordName', 'ingress', 'egress', 'address');
+      matrix.addValue(0, 0, {messages: 1234, address: 'address'});
+      expect(matrix.hasValues()).toBeTruthy();
+    });
+  });
+});
diff --git a/console/react/src/common/amqp/utilities.test.js b/console/react/src/common/amqp/utilities.test.js
new file mode 100644
index 0000000..8997713
--- /dev/null
+++ b/console/react/src/common/amqp/utilities.test.js
@@ -0,0 +1,211 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import {utils} from './utilities';
+
+describe('Management utilities', function() {
+  describe('#nameFromId', function() {
+    it('should extract name from id', function() {
+      let name = utils.nameFromId('amqp:/topo/0/routerName/$management');
+      expect(name).toEqual('routerName');
+    });
+    it('should extract name with / from id', function() {
+      let name = utils.nameFromId('amqp:/topo/0/router/Name/$management');
+      expect(name).toEqual('router/Name');
+    });
+    it('should extract from edge router id', function() {
+      let name = utils.nameFromId('amqp:/_edge/edgeName/$management');
+      expect(name).toEqual('edgeName');
+    });
+    it('should extract name with / from edge router id', function() {
+      let name = utils.nameFromId('amqp:/_edge/edge/Name/$management');
+      expect(name).toEqual('edge/Name');
+    });
+    it('should extract name with multiple /s from router id', function() {
+      let name = utils.nameFromId('amqp:/_topo/0/router/Name/here/$management');
+      expect(name).toEqual('router/Name/here');
+    });
+    it('should extract name with multiple /s from edge router id', function() {
+      let name = utils.nameFromId('amqp:/_edge/edge/Name/here/$management');
+      expect(name).toEqual('edge/Name/here');
+    });
+  });
+  describe('#valFor', function() {
+    let aAr = ['name', 'value'];
+    let vAr = [['mary', 'lamb']];
+    it('should return correct value for key', function() {
+      let name = utils.valFor(aAr, vAr[0], 'name');
+      expect(name).toEqual('mary');
+    });
+    it('should return null if key is not found', function() {
+      let name = utils.valFor(aAr, vAr, 'address');
+      expect(name).toEqual(null);
+    });
+  });
+  describe('#pretty', function() {
+    it('should return unchanged if not a number', function() {
+      let val = utils.pretty('foo');
+      expect(val).toEqual('foo');
+    });
+    it('should add commas to numbers', function() {
+      let val = utils.pretty('1234');
+      expect(val).toEqual('1,234');
+    });
+  });
+  describe('#humanify', function() {
+    it('should handle empty strings', function() {
+      let val = utils.humanify('');
+      expect(val).toEqual('');
+    });
+    it('should handle undefined input', function() {
+      let val = utils.humanify();
+      expect(val).toEqual(undefined);
+    });
+    it('should capitalize the first letter', function() {
+      let val = utils.humanify('foo');
+      expect(val).toEqual('Foo');
+    });
+    it('should split on all capital letters', function() {
+      let val = utils.humanify('fooBarBaz');
+      expect(val).toEqual('Foo Bar Baz');
+    });
+  });
+  describe('#addr_class', function() {
+    it('should handle unknown address types', function() {
+      let val = utils.addr_class(' ');
+      expect(val).toEqual('unknown:  ');
+    });
+    it('should handle undefined input', function() {
+      let val = utils.addr_class();
+      expect(val).toEqual('-');
+    });
+    it('should identify mobile addresses', function() {
+      let val = utils.addr_class('Mfoo');
+      expect(val).toEqual('mobile');
+    });
+    it('should identify router addresses', function() {
+      let val = utils.addr_class('Rfoo');
+      expect(val).toEqual('router');
+    });
+    it('should identify area addresses', function() {
+      let val = utils.addr_class('Afoo');
+      expect(val).toEqual('area');
+    });
+    it('should identify local addresses', function() {
+      let val = utils.addr_class('Lfoo');
+      expect(val).toEqual('local');
+    });
+    it('should identify link-incoming C addresses', function() {
+      let val = utils.addr_class('Cfoo');
+      expect(val).toEqual('link-incoming');
+    });
+    it('should identify link-incoming E addresses', function() {
+      let val = utils.addr_class('Efoo');
+      expect(val).toEqual('link-incoming');
+    });
+    it('should identify link-outgoing D addresses', function() {
+      let val = utils.addr_class('Dfoo');
+      expect(val).toEqual('link-outgoing');
+    });
+    it('should identify link-outgoing F addresses', function() {
+      let val = utils.addr_class('Dfoo');
+      expect(val).toEqual('link-outgoing');
+    });
+    it('should identify topo addresses', function() {
+      let val = utils.addr_class('Tfoo');
+      expect(val).toEqual('topo');
+    });
+  });
+  describe('#addr_text', function() {
+    it('should handle undefined input', function() {
+      let val = utils.addr_text();
+      expect(val).toEqual('-');
+    });
+    it('should identify mobile addresses', function() {
+      let val = utils.addr_text('M0foo');
+      expect(val).toEqual('foo');
+    });
+    it('should identify non-mobile addresses', function() {
+      let val = utils.addr_text('Rfoo');
+      expect(val).toEqual('foo');
+    });
+  });
+  describe('#identity_clean', function() {
+    it('should handle undefined input', function() {
+      let val = utils.identity_clean();
+      expect(val).toEqual('-');
+    });
+    it('should handle identities with no /', function() {
+      let val = utils.identity_clean('foo');
+      expect(val).toEqual('foo');
+    });
+    it('should return everything after the 1st /', function() {
+      let val = utils.identity_clean('foo/bar');
+      expect(val).toEqual('bar');
+    });
+  });
+  describe('#copy', function() {
+    it('should handle undefined input', function() {
+      let val = utils.copy();
+      expect(val).toEqual(undefined);
+    });
+    it('should copy all object values instead making references', function() {
+      let input = {a: 'original value'};
+      let output = utils.copy(input);
+      input.a = 'changed value';
+      expect(output.a).toEqual('original value');
+    });
+  });
+  describe('#flatten', function() {
+    it('should return an object when passed undefined input', function() {
+      let val = utils.flatten();
+      expect(typeof val).toEqual('object');
+    });
+    it('and the returned object should be empty', function() {
+      let val = utils.flatten();
+      expect(Object.keys(val).length).toEqual(0);
+    });
+    it('should flatten the arrays into an object', function() {
+      let attributes = ['first', 'second'];
+      let value = ['1st', '2nd'];
+      let val = utils.flatten(attributes, value);
+      expect(val.second).toEqual('2nd');
+    });
+  });
+  describe('#flattenAll', function() {
+    let vals = [];
+    let attributes = ['first', 'second'];
+    let values = [['1st', '2nd'], ['3rd', '4th']];
+    it('should flatten the router entity into an array of objects', function() {
+      vals = utils.flattenAll({attributeNames: attributes, results: values});
+      expect(vals.length).toEqual(2);
+    });
+    it('should correctly create the objects', function() {
+      expect(vals[1].second).toEqual('4th');
+    });
+    it('should filter out objects', function() {
+      vals = utils.flattenAll({attributeNames: attributes, results: values}, function (f) {
+        return f.first === '1st' ? {first: 'first', second: 'second'} : null;
+      });
+      expect(vals.length).toEqual(1);
+      expect(vals[0].second).toEqual('second');
+    });
+  });
+
+});
diff --git a/console/react/src/topology/links.test.js b/console/react/src/topology/links.test.js
new file mode 100644
index 0000000..e88b05b
--- /dev/null
+++ b/console/react/src/topology/links.test.js
@@ -0,0 +1,105 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import {default as fs} from 'fs';
+import {Links} from './links.js';
+import {Nodes} from './nodes.js';
+
+class Log {
+  log(msg) { console.log(msg); }
+  debug(msg) { console.log(`Debug: ${msg}`); }
+  error(msg) { console.log(`Error: ${msg}`); }
+  info(msg) { console.log(`Info: ${msg}`); }
+  warn(msg) { console.log(`Warning: ${msg}`); }
+}
+
+const log = new Log();
+const links = new Links(log);
+const edgeLinks = new Links(log);
+const nodes = new Nodes(log);
+const edgeNodes = new Nodes(log);
+const width = 1024;
+const height = 768;
+
+let nodeInfo;
+let edgeInfo;
+
+beforeEach(function (done) {
+  let src = '';
+  let LAST_PARAM = process.argv[process.argv.length - 1];
+
+  let PARAM_NAME = LAST_PARAM.split('=')[0].replace('--', '');
+  let PARAM_VALUE = LAST_PARAM.split('=')[1];
+  if (PARAM_NAME === 'src') {
+    src = PARAM_VALUE;
+  }
+
+  fs.readFile(src + 'test_data/nodes.json', 'utf8', function (err, fileContents) {
+    if (err) throw err;
+    nodeInfo = JSON.parse(fileContents);
+  });
+  fs.readFile(src + 'test_data/nodes-edge.json', 'utf8', function (err, fileContents) {
+    if (err) throw err;
+    edgeInfo = JSON.parse(fileContents);
+    done();
+  });
+});
+
+describe('Nodes', function () {
+  describe('#exists', function () {
+    it('should exist', function () {
+      expect(nodes).toBeDefined();
+    });
+  });
+  describe('#initializes', function () {
+    it('should initialize', function () {
+      nodes.initialize(nodeInfo, width, height, {});
+      expect(nodes.nodes.length).toEqual(6);
+    });
+    it('should initialize edge nodes', function () {
+      edgeNodes.initialize(edgeInfo, width, height, {});
+      expect(edgeNodes.nodes.length).toEqual(2);
+    });
+  });
+
+});
+describe('Links', function () {
+  describe('#exists', function () {
+    it('should exist', function () {
+      expect(links).toBeDefined();
+    });
+  });
+  describe('#initializes', function () {
+    const separateContainers = new Set();
+    const unknowns = [];
+    const localStorage = {};
+    it('should initialize', function () {
+      links.initialize(nodeInfo, nodes, separateContainers, unknowns, height, localStorage);
+      expect(links.links.length).toEqual(10);
+    });
+    it('should initialize edge links', function () {
+      edgeLinks.initialize(edgeInfo, edgeNodes, separateContainers, unknowns, height, localStorage);
+      expect(edgeLinks.links.length).toEqual(6);
+    });
+    it('should add nodes for edge router groups', function () {
+      expect(edgeNodes.nodes.length).toEqual(6);
+    });
+  });
+
+});
diff --git a/console/react/test_data/nodes-edge.json b/console/react/test_data/nodes-edge.json
new file mode 100644
index 0000000..6fb6d31
--- /dev/null
+++ b/console/react/test_data/nodes-edge.json
@@ -0,0 +1,1156 @@
+{
+  "amqp:/_topo/0/INT.A/$management": {
+    "connection": {
+      "attributeNames": [
+        "name",
+        "identity",
+        "host",
+        "role",
+        "dir",
+        "container",
+        "sasl",
+        "isAuthenticated",
+        "user",
+        "isEncrypted",
+        "sslProto",
+        "sslCipher",
+        "properties",
+        "sslSsf",
+        "tenant",
+        "type",
+        "ssl",
+        "opened",
+        "active"
+      ],
+      "results": [
+        [
+          "connection/127.0.0.1:52392",
+          "4",
+          "127.0.0.1:52392",
+          "edge",
+          "in",
+          "EDGE-3.0",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 1
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:45762",
+          "134",
+          "127.0.0.1:45762",
+          "edge",
+          "in",
+          "EDGE-4.0",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 1
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:38384",
+          "187",
+          "127.0.0.1:38384",
+          "edge",
+          "in",
+          "EDGE-13.2",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 1
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:38404",
+          "192",
+          "127.0.0.1:38404",
+          "edge",
+          "in",
+          "EDGE-13.7",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 1
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:38420",
+          "194",
+          "127.0.0.1:38420",
+          "edge",
+          "in",
+          "EDGE-13.9",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 1
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:52104",
+          "506",
+          "127.0.0.1:52104",
+          "inter-router",
+          "in",
+          "Interior Router B",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 1
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:52138",
+          "533",
+          "127.0.0.1:52138",
+          "edge",
+          "in",
+          "EDGE-8.0",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 1
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:52140",
+          "534",
+          "127.0.0.1:52140",
+          "edge",
+          "in",
+          "EDGE-8.1",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 1
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1",
+          "538",
+          "127.0.0.1",
+          "normal",
+          "in",
+          "111ea22b-e14b-db47-bcf9-5a747beb4d26",
+          null,
+          false,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "console_identifier": "Dispatch console"
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ]
+      ],
+      "timestamp": "2018-12-03T17:54:29.989Z"
+    },
+    "router.node": {
+      "results": [
+        [
+          "INT.A",
+          "(self)"
+        ],
+        [
+          "Interior Router B",
+          null
+        ]
+      ],
+      "attributeNames": [
+        "id",
+        "nextHop"
+      ],
+      "timestamp": "2018-12-03T17:54:29.987Z"
+    },
+    "router.link": {
+      "attributeNames": [
+        "linkType",
+        "connectionId",
+        "linkDir",
+        "owningAddr"
+      ],
+      "results": [
+        [
+          "endpoint",
+          "4",
+          "in",
+          null
+        ],
+        [
+          "edge-downlink",
+          "4",
+          "out",
+          "HEDGE-3.0"
+        ],
+        [
+          "endpoint",
+          "4",
+          "out",
+          "M0$qd.edge_addr_tracking"
+        ],
+        [
+          "endpoint",
+          "4",
+          "in",
+          "M0$management"
+        ],
+        [
+          "endpoint",
+          "4",
+          "out",
+          "Ltemp.7acuL0visoOXABp"
+        ],
+        [
+          "endpoint",
+          "134",
+          "in",
+          null
+        ],
+        [
+          "edge-downlink",
+          "134",
+          "out",
+          "HEDGE-4.0"
+        ],
+        [
+          "endpoint",
+          "134",
+          "out",
+          "M0$qd.edge_addr_tracking"
+        ],
+        [
+          "endpoint",
+          "134",
+          "in",
+          "M0$management"
+        ],
+        [
+          "endpoint",
+          "134",
+          "out",
+          "Ltemp.Hnh+MyiiosvTRBK"
+        ],
+        [
+          "endpoint",
+          "4",
+          "in",
+          "M0to60"
+        ],
+        [
+          "endpoint",
+          "187",
+          "in",
+          null
+        ],
+        [
+          "edge-downlink",
+          "187",
+          "out",
+          "HEDGE-13.2"
+        ],
+        [
+          "endpoint",
+          "187",
+          "out",
+          "M0$qd.edge_addr_tracking"
+        ],
+        [
+          "endpoint",
+          "187",
+          "in",
+          "M0$management"
+        ],
+        [
+          "endpoint",
+          "187",
+          "out",
+          "Ltemp.luHTmRfBYvfmhcR"
+        ],
+        [
+          "endpoint",
+          "192",
+          "in",
+          null
+        ],
+        [
+          "edge-downlink",
+          "192",
+          "out",
+          "HEDGE-13.7"
+        ],
+        [
+          "endpoint",
+          "192",
+          "out",
+          "M0$qd.edge_addr_tracking"
+        ],
+        [
+          "endpoint",
+          "192",
+          "in",
+          "M0$management"
+        ],
+        [
+          "endpoint",
+          "192",
+          "out",
+          "Ltemp.c3j7PMiCRFT_T3P"
+        ],
+        [
+          "endpoint",
+          "194",
+          "in",
+          null
+        ],
+        [
+          "edge-downlink",
+          "194",
+          "out",
+          "HEDGE-13.9"
+        ],
+        [
+          "endpoint",
+          "194",
+          "out",
+          "M0$qd.edge_addr_tracking"
+        ],
+        [
+          "endpoint",
+          "194",
+          "in",
+          "M0$management"
+        ],
+        [
+          "endpoint",
+          "194",
+          "out",
+          "Ltemp.xxbXf7d+Bd5xfvs"
+        ],
+        [
+          "router-control",
+          "506",
+          "out",
+          "Lqdhello"
+        ],
+        [
+          "router-control",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "506",
+          "in",
+          null
+        ],
+        [
+          "endpoint",
+          "533",
+          "in",
+          null
+        ],
+        [
+          "edge-downlink",
+          "533",
+          "out",
+          "HEDGE-8.0"
+        ],
+        [
+          "endpoint",
+          "533",
+          "out",
+          "M0$qd.edge_addr_tracking"
+        ],
+        [
+          "endpoint",
+          "533",
+          "in",
+          "M0$management"
+        ],
+        [
+          "endpoint",
+          "533",
+          "out",
+          "Ltemp.5lr4JT4g7J2PxEy"
+        ],
+        [
+          "endpoint",
+          "534",
+          "in",
+          null
+        ],
+        [
+          "edge-downlink",
+          "534",
+          "out",
+          "HEDGE-8.1"
+        ],
+        [
+          "endpoint",
+          "534",
+          "out",
+          "M0$qd.edge_addr_tracking"
+        ],
+        [
+          "endpoint",
+          "534",
+          "in",
+          "M0$management"
+        ],
+        [
+          "endpoint",
+          "534",
+          "out",
+          "Ltemp.9bbwgPssAa8rg6U"
+        ],
+        [
+          "endpoint",
+          "538",
+          "out",
+          "Ltemp.b73RFCgwEmMwxuu"
+        ],
+        [
+          "endpoint",
+          "538",
+          "in",
+          null
+        ]
+      ],
+      "timestamp": "2018-12-03T17:54:29.993Z"
+    }
+  },
+  "amqp:/_topo/0/Interior Router B/$management": {
+    "connection": {
+      "attributeNames": [
+        "name",
+        "identity",
+        "host",
+        "role",
+        "dir",
+        "container",
+        "sasl",
+        "isAuthenticated",
+        "user",
+        "isEncrypted",
+        "sslProto",
+        "sslCipher",
+        "properties",
+        "sslSsf",
+        "tenant",
+        "type",
+        "ssl",
+        "opened",
+        "active"
+      ],
+      "results": [
+        [
+          "connection/127.0.0.1:22004",
+          "1",
+          "127.0.0.1:22004",
+          "inter-router",
+          "out",
+          "INT.A",
+          "ANONYMOUS",
+          true,
+          null,
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 506
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:48078",
+          "2",
+          "127.0.0.1:48078",
+          "edge",
+          "in",
+          "EDGE-4.0",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 37
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:48080",
+          "3",
+          "127.0.0.1:48080",
+          "edge",
+          "in",
+          "EDGE-13.9",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 7
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:48090",
+          "7",
+          "127.0.0.1:48090",
+          "edge",
+          "in",
+          "EDGE-13.2",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 7
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:48084",
+          "6",
+          "127.0.0.1:48084",
+          "edge",
+          "in",
+          "EDGE-13.7",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 7
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:48086",
+          "5",
+          "127.0.0.1:48086",
+          "edge",
+          "in",
+          "EDGE-3.0",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 764
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:48092",
+          "8",
+          "127.0.0.1:48092",
+          "edge",
+          "in",
+          "EDGE-6.0",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 35
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:41250",
+          "9",
+          "127.0.0.1:41250",
+          "edge",
+          "in",
+          "EDGE-10.0",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 1
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ],
+        [
+          "connection/127.0.0.1:41252",
+          "10",
+          "127.0.0.1:41252",
+          "edge",
+          "in",
+          "EDGE-10.1",
+          "ANONYMOUS",
+          true,
+          "anonymous",
+          false,
+          null,
+          null,
+          {
+            "product": "qpid-dispatch-router",
+            "version": "1.5.0-SNAPSHOT",
+            "qd.conn-id": 1
+          },
+          0,
+          null,
+          "org.apache.qpid.dispatch.connection",
+          false,
+          true,
+          true
+        ]
+      ],
+      "timestamp": "2018-12-03T17:54:29.993Z"
+    },
+    "router.node": {
+      "results": [
+        [
+          "Interior Router B",
+          "(self)"
+        ],
+        [
+          "INT.A",
+          null
+        ]
+      ],
+      "attributeNames": [
+        "id",
+        "nextHop"
+      ],
+      "timestamp": "2018-12-03T17:54:29.990Z"
+    },
+    "router.link": {
+      "attributeNames": [
+        "linkType",
+        "connectionId",
+        "linkDir",
+        "owningAddr"
+      ],
+      "results": [
+        [
+          "router-control",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "router-control",
+          "1",
+          "out",
+          "Lqdhello"
+        ],
+        [
+          "inter-router",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "out",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "in",
+          null
+        ],
+        [
+          "inter-router",
+          "1",
+          "out",
+          null
+        ],
+        [
+          "endpoint",
+          "8",
+          "in",
+          null
+        ],
+        [
+          "edge-downlink",
+          "8",
+          "out",
+          "HEDGE-6.0"
+        ],
+        [
+          "endpoint",
+          "8",
+          "out",
+          "M0$qd.edge_addr_tracking"
+        ],
+        [
+          "endpoint",
+          "8",
+          "out",
+          "M0to60"
+        ],
+        [
+          "endpoint",
+          "8",
+          "in",
+          "M0to61"
+        ],
+        [
+          "endpoint",
+          "8",
+          "in",
+          "M0$management"
+        ],
+        [
+          "endpoint",
+          "8",
+          "out",
+          "Ltemp.h1XzTsSzGVWKnCq"
+        ],
+        [
+          "endpoint",
+          "9",
+          "in",
+          null
+        ],
+        [
+          "edge-downlink",
+          "9",
+          "out",
+          "HEDGE-10.0"
+        ],
+        [
+          "endpoint",
+          "9",
+          "out",
+          "M0$qd.edge_addr_tracking"
+        ],
+        [
+          "endpoint",
+          "9",
+          "in",
+          "M0$management"
+        ],
+        [
+          "endpoint",
+          "9",
+          "out",
+          "Ltemp.kKv6kw5BDhsC3yo"
+        ],
+        [
+          "endpoint",
+          "10",
+          "in",
+          null
+        ],
+        [
+          "edge-downlink",
+          "10",
+          "out",
+          "HEDGE-10.1"
+        ],
+        [
+          "endpoint",
+          "10",
+          "out",
+          "M0$qd.edge_addr_tracking"
+        ],
+        [
+          "endpoint",
+          "10",
+          "in",
+          "M0$management"
+        ],
+        [
+          "endpoint",
+          "10",
+          "out",
+          "Ltemp.4vyZk5C_Qo11yyw"
+        ]
+      ],
+      "timestamp": "2018-12-03T17:54:29.994Z"
+    }
+  }
+}
\ No newline at end of file
diff --git a/console/react/test_data/nodes.json b/console/react/test_data/nodes.json
new file mode 100644
index 0000000..7aa7631
--- /dev/null
+++ b/console/react/test_data/nodes.json
@@ -0,0 +1 @@
+{"amqp:/_topo/0/D/$management":{"router.node":{"results":[["D","(self)"],["C",null],["A","C"],["B","C"],["E",null],["F",null]],"attributeNames":["id","nextHop"]},"connection":{"attributeNames":["name","identity","host","role","dir","container","sasl","isAuthenticated","user","isEncrypted","sslProto","sslCipher","properties","sslSsf","tenant","type","ssl","opened"],"results":[["connection/127.0.0.1:43430","3","127.0.0.1:43430","inter-router","in","C","ANONYMOUS",true,"anonymous",false,nul [...]
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org