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

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


The following commit(s) were added to refs/heads/eallen-DISPATCH-1385 by this 
push:
     new ad6919d  Fix address legend
ad6919d is described below

commit ad6919d40de426ee03fd9702bf7e53234f50b7c2
Author: Ernest Allen <eal...@redhat.com>
AuthorDate: Mon Sep 30 17:58:35 2019 -0400

    Fix address legend
---
 console/react/src/App.css                 |   5 +-
 console/react/src/amqp/management.js      |  33 +++----
 console/react/src/amqp/topology.js        | 143 +++++++++++++++++++-----------
 console/react/src/qdrService.js           |  12 +--
 console/react/src/topology/qdrTopology.js |  50 +++++++----
 console/react/src/topology/traffic.js     |  43 ++-------
 6 files changed, 154 insertions(+), 132 deletions(-)

diff --git a/console/react/src/App.css b/console/react/src/App.css
index e018298..6782444 100644
--- a/console/react/src/App.css
+++ b/console/react/src/App.css
@@ -490,6 +490,10 @@ path.hittarget {
   stroke-width: 15px;
   stroke: transparent;
 }
+path.hittarget.highlighted {
+  stroke: #6f6;
+  opacity: 0.5;
+}
 
 path.link.small {
   stroke-width: 2.5;
@@ -525,7 +529,6 @@ circle.node.reflexive {
 circle.node.selected {
   stroke: #6f6 !important;
   stroke-width: 2px;
-  fill: #e0e0ff !important;
 }
 circle.node.highlighted {
   stroke: #6f6;
diff --git a/console/react/src/amqp/management.js 
b/console/react/src/amqp/management.js
index 4b3bb32..0bdb748 100644
--- a/console/react/src/amqp/management.js
+++ b/console/react/src/amqp/management.js
@@ -16,45 +16,46 @@
 
 /* global Promise */
 
-import { ConnectionManager } from './connection.js';
-import Topology from './topology.js';
+import { ConnectionManager } from "./connection.js";
+import Topology from "./topology.js";
 
 export class Management {
-  constructor(protocol) {
+  constructor(protocol, interval) {
     this.connection = new ConnectionManager(protocol);
-    this.topology = new Topology(this.connection);
+    this.topology = new Topology(this.connection, interval);
   }
   getSchema(callback) {
     var self = this;
-    return new Promise(function (resolve, reject) {
-      self.connection.sendMgmtQuery('GET-SCHEMA')
-        .then(function (responseAndContext) {
+    return new Promise(function(resolve, reject) {
+      self.connection.sendMgmtQuery("GET-SCHEMA").then(
+        function(responseAndContext) {
           var response = responseAndContext.response;
           for (var entityName in response.entityTypes) {
             var entity = response.entityTypes[entityName];
             if (entity.deprecated) {
               // deprecated entity
               delete response.entityTypes[entityName];
-            }
-            else {
+            } else {
               for (var attributeName in entity.attributes) {
                 var attribute = entity.attributes[attributeName];
                 if (attribute.deprecated) {
                   // deprecated attribute
-                  delete 
response.entityTypes[entityName].attributes[attributeName];
+                  delete response.entityTypes[entityName].attributes[
+                    attributeName
+                  ];
                 }
               }
             }
           }
           self.connection.setSchema(response);
-          if (callback)
-            callback(response);
+          if (callback) callback(response);
           resolve(response);
-        }, function (error) {
-          if (callback)
-            callback(error);
+        },
+        function(error) {
+          if (callback) callback(error);
           reject(error);
-        });
+        }
+      );
     });
   }
   schema() {
diff --git a/console/react/src/amqp/topology.js 
b/console/react/src/amqp/topology.js
index 0e8b2e4..dbbc00f 100644
--- a/console/react/src/amqp/topology.js
+++ b/console/react/src/amqp/topology.js
@@ -22,14 +22,17 @@ class Topology {
   constructor(connectionManager, interval) {
     this.connection = connectionManager;
     this.updatedActions = {};
+    this.changedActions = {};
     this.entities = []; // which entities to request each topology update
     this.entityAttribs = { connection: [] };
     this._nodeInfo = {}; // info about all known nodes and entities
     this.filtering = false; // filter out nodes that don't have connection info
     this.timeout = 5000;
     this.updateInterval = interval;
+    console.log(`topology constructed with interval of ${interval}`);
     this._getTimer = null;
     this.updating = false;
+    this.counter = 0;
   }
   addUpdatedAction(key, action) {
     if (typeof action === "function") {
@@ -59,8 +62,25 @@ class Topology {
       this.entityAttribs[entity] = entityAttribs[i].attrs || [];
     }
   }
+  addChangedAction(key, action) {
+    if (typeof action === "function") {
+      this.changedActions[key] = action;
+    }
+  }
+  delChangedAction(key) {
+    if (key in this.changedActions) delete this.changedActions[key];
+  }
+  executeChangedActions(error) {
+    for (var action in this.changedActions) {
+      this.changedActions[action].apply(this, [error]);
+    }
+  }
   on(eventName, fn, key) {
-    if (eventName === "updated") this.addUpdatedAction(key, fn);
+    if (eventName === "updated") {
+      this.addUpdatedAction(key, fn);
+    } else if (eventName === "changed") {
+      this.addChangedAction(key, fn);
+    }
   }
   unregister(eventName, key) {
     if (eventName === "updated") this.delUpdatedAction(key);
@@ -68,15 +88,12 @@ class Topology {
   nodeInfo() {
     return this._nodeInfo;
   }
-  saveResults(workInfo) {
+  saveResults(workInfo, all) {
+    const changes = { newRouters: [], lostRouters: [], connections: [] };
+    let changed = false;
     let workSet = new Set(Object.keys(workInfo));
     for (let rId in this._nodeInfo) {
-      if (!workSet.has(rId)) {
-        // mark any routers that went away since the last request as removed
-        this._nodeInfo[rId]["removed"] = true;
-      } else {
-        if (this._nodeInfo[rId]["removed"])
-          delete this._nodeInfo[rId]["removed"];
+      if (workSet.has(rId)) {
         // copy entities
         for (let entity in workInfo[rId]) {
           if (
@@ -84,9 +101,30 @@ class Topology {
             workInfo[rId][entity]["timestamp"] + "" >
               this._nodeInfo[rId][entity]["timestamp"] + ""
           ) {
+            // check for changed number of connections
+            if (entity === "connection") {
+              const oldConnections =
+                this._nodeInfo &&
+                this._nodeInfo[rId] &&
+                this._nodeInfo[rId].connection
+                  ? this._nodeInfo[rId].connection.results.length
+                  : 0;
+              const newConnections = workInfo[rId].connection.results.length;
+              if (oldConnections !== newConnections) {
+                changes.connections.push({
+                  router: rId,
+                  from: oldConnections,
+                  to: newConnections
+                });
+                changed = true;
+              }
+            }
             this._nodeInfo[rId][entity] = utils.copy(workInfo[rId][entity]);
           }
         }
+      } else if (all) {
+        changes.lostRouters.push(rId);
+        changed = true;
       }
     }
     // add any new routers
@@ -94,19 +132,20 @@ class Topology {
     for (let rId in workInfo) {
       if (!nodeSet.has(rId)) {
         this._nodeInfo[rId] = utils.copy(workInfo[rId]);
+        changes.newRouters.push(rId);
+        changed = true;
       }
     }
-  }
-  // remove any nodes that don't have connection info
-  purge() {
-    for (let id in this._nodeInfo) {
-      let node = this._nodeInfo[id];
-      if (node.removed) {
-        delete this._nodeInfo[id];
-      }
+    if (changed) {
+      this.executeChangedActions(changes);
     }
   }
+
   get() {
+    if (typeof this.getCounter === "undefined") {
+      this.getCounter = 0;
+    }
+    console.log(`topology: get - ${this.getCounter++}`);
     return new Promise(
       function(resolve, reject) {
         this.connection.sendMgmtQuery("GET-MGMT-NODES").then(
@@ -122,7 +161,7 @@ class Topology {
                 routerIds.push(parts.join("/"));
               }
               let finish = function(workInfo) {
-                this.saveResults(workInfo);
+                this.saveResults(workInfo, true);
                 this.onDone(this._nodeInfo);
                 resolve(this._nodeInfo);
               };
@@ -194,45 +233,41 @@ class Topology {
     );
   }
   doget(ids) {
-    return new Promise(
-      function(resolve) {
-        let workInfo = {};
-        for (var i = 0; i < ids.length; ++i) {
-          workInfo[ids[i]] = {};
+    return new Promise(resolve => {
+      let workInfo = {};
+      for (var i = 0; i < ids.length; ++i) {
+        workInfo[ids[i]] = {};
+      }
+      var gotResponse = (nodeName, entity, response) => {
+        workInfo[nodeName][entity] = response;
+        workInfo[nodeName][entity]["timestamp"] = new Date();
+      };
+      var q = queue(this.connection.availableQeueuDepth());
+      for (var id in workInfo) {
+        for (var entity in this.entityAttribs) {
+          q.defer(
+            this.q_fetchNodeInfo.bind(this),
+            id,
+            entity,
+            this.entityAttribs[entity],
+            q,
+            gotResponse
+          );
         }
-        var gotResponse = function(nodeName, entity, response) {
-          workInfo[nodeName][entity] = response;
-          workInfo[nodeName][entity]["timestamp"] = new Date();
-        };
-        var q = queue(this.connection.availableQeueuDepth());
-        for (var id in workInfo) {
-          for (var entity in this.entityAttribs) {
-            q.defer(
-              this.q_fetchNodeInfo.bind(this),
-              id,
-              entity,
-              this.entityAttribs[entity],
-              q,
-              gotResponse
-            );
+      }
+      q.await(() => {
+        // filter out nodes that have no connection info
+        if (this.filtering) {
+          for (var id in workInfo) {
+            if (!workInfo[id].connection) {
+              this.flux = true;
+              delete workInfo[id];
+            }
           }
         }
-        q.await(
-          function() {
-            // filter out nodes that have no connection info
-            if (this.filtering) {
-              for (var id in workInfo) {
-                if (!workInfo[id].connection) {
-                  this.flux = true;
-                  delete workInfo[id];
-                }
-              }
-            }
-            resolve(workInfo);
-          }.bind(this)
-        );
-      }.bind(this)
-    );
+        resolve(workInfo);
+      });
+    });
   }
 
   onDone(result) {
@@ -365,7 +400,7 @@ class Topology {
     this.addUpdateEntities(entityAttribs);
     this.doget(nodes).then(
       function(results) {
-        this.saveResults(results);
+        this.saveResults(results, false);
         callback(extra, results);
       }.bind(this)
     );
diff --git a/console/react/src/qdrService.js b/console/react/src/qdrService.js
index 93bb7b5..55a6cc9 100644
--- a/console/react/src/qdrService.js
+++ b/console/react/src/qdrService.js
@@ -20,17 +20,14 @@ Licensed to the Apache Software Foundation (ASF) under one
 import { Management as dm } from "./amqp/management.js";
 import { utils } from "./amqp/utilities.js";
 
-import { QDR_LAST_LOCATION, QDR_INTERVAL } from "./qdrGlobals.js";
+import { QDR_LAST_LOCATION } from "./qdrGlobals.js";
 
 // number of milliseconds between topology updates
 const DEFAULT_INTERVAL = 5000;
 export class QDRService {
   constructor(hooks) {
     const url = utils.getUrlParts(window.location);
-    this.management = new dm(
-      url.protocol,
-      localStorage[QDR_INTERVAL] || DEFAULT_INTERVAL
-    );
+    this.management = new dm(url.protocol, DEFAULT_INTERVAL);
     this.utilities = utils;
     this.hooks = hooks;
   }
@@ -84,10 +81,7 @@ export class QDRService {
   disconnect() {
     this.management.connection.disconnect();
     delete this.management;
-    this.management = new dm(
-      this.$location.protocol(),
-      localStorage[QDR_INTERVAL] || DEFAULT_INTERVAL
-    );
+    this.management = new dm(this.$location.protocol(), DEFAULT_INTERVAL);
   }
 }
 
diff --git a/console/react/src/topology/qdrTopology.js 
b/console/react/src/topology/qdrTopology.js
index 0722c4a..f5eda9e 100644
--- a/console/react/src/topology/qdrTopology.js
+++ b/console/react/src/topology/qdrTopology.js
@@ -143,10 +143,18 @@ class TopologyPage extends Component {
   }
 
   // called only once when the component is initialized
-  componentDidMount() {
+  componentDidMount = () => {
     this.init();
-  }
+    this.props.service.management.topology.startUpdating();
+    this.props.service.management.topology.addChangedAction("topology", () => {
+      this.init();
+    });
+  };
 
+  componentWillUnmount = () => {
+    this.props.service.management.topology.stopUpdating();
+    this.props.service.management.topology.delChangedAction("topology");
+  };
   setFixed = (item, data) => {
     data.setFixed(item.title !== "Unfreeze");
   };
@@ -162,9 +170,7 @@ class TopologyPage extends Component {
     });
     // set the selected attr for this node
     data.selected = item.title === "Select";
-    if (item.title === "Select") {
-      this.selected_node = data;
-    }
+    this.selected_node = data.selected ? data : null;
     this.restart();
   };
   isSelected = data => {
@@ -223,10 +229,8 @@ class TopologyPage extends Component {
       .attr("class", "nodes")
       .selectAll("g");
 
-    /*
-      this.traffic.remove();
+    this.traffic.remove();
     if (this.state.legendOptions.traffic.open) {
-      
       if (this.state.legendOptions.traffic.dots)
         this.traffic.addAnimationType(
           "dots",
@@ -240,7 +244,7 @@ class TopologyPage extends Component {
           Nodes.radius("inter-router")
         );
     }
-*/
+
     // mouse event vars
     this.mousedown_node = null;
 
@@ -535,7 +539,10 @@ class TopologyPage extends Component {
         return !d.right && !d.left;
       });
 
-    enterpath.append("path").attr("class", "hittarget");
+    enterpath
+      .append("path")
+      .attr("class", "hittarget")
+      .attr("id", d => `hitpath-${d.source.uid()}-${d.target.uid()}`);
 
     // remove old links
     this.path.exit().remove();
@@ -757,6 +764,10 @@ class TopologyPage extends Component {
       let link = this.forceData.links.linkFor(selected_node, connected_node);
       if (link) {
         link.highlighted = true;
+        d3.select(`path[id='hitpath-${link.uid}']`).classed(
+          "highlighted",
+          true
+        );
       }
       // start at the router
       selected_node = connected_node;
@@ -771,6 +782,10 @@ class TopologyPage extends Component {
       let link = this.forceData.links.linkFor(d, connected_node);
       if (link) {
         link.highlighted = true;
+        d3.select(`path[id='hitpath-${link.uid}']`).classed(
+          "highlighted",
+          true
+        );
       }
       // end at the router
       d = connected_node;
@@ -784,15 +799,13 @@ class TopologyPage extends Component {
       selected_node,
       (link, fnode, tnode) => {
         link.highlighted = true;
+        d3.select(`path[id='hitpath-${link.uid}']`).classed(
+          "highlighted",
+          true
+        );
         fnode.highlighted = true;
         tnode.highlighted = true;
       }
-      /*
-      function(hlLink, hnode) {
-        hlLink.highlighted = true;
-        hnode.highlighted = true;
-      }
-      */
     );
     let hnode = this.forceData.nodes.nodeFor(d.name);
     hnode.highlighted = true;
@@ -845,6 +858,7 @@ class TopologyPage extends Component {
   clearAllHighlights = () => {
     this.forceData.links.clearHighlighted();
     this.forceData.nodes.clearHighlighted();
+    d3.selectAll(".hittarget").classed("highlighted", false);
   };
 
   saveLegendOptions = legendOptions => {
@@ -920,12 +934,13 @@ class TopologyPage extends Component {
       this.handleLegendOptionsChange(legendOptions, this.addressFilterChanged);
     }
   };
+
   handleUpdateAddressColors = addressColors => {
     const { legendOptions } = this.state;
     let changed = false;
     // set any new keys to the passed in value
     Object.keys(addressColors).forEach(address => {
-      if (typeof legendOptions.traffic.addresses[address] === "undefined") {
+      if (typeof legendOptions.traffic.addressColors[address] === "undefined") 
{
         legendOptions.traffic.addressColors[address] = addressColors[address];
         changed = true;
       }
@@ -971,7 +986,6 @@ class TopologyPage extends Component {
   };
 
   render() {
-    console.log("rendering qdrTopology");
     return (
       <div className="qdrTopology">
         <LegendComponent
diff --git a/console/react/src/topology/traffic.js 
b/console/react/src/topology/traffic.js
index 24a7643..4cc51b0 100644
--- a/console/react/src/topology/traffic.js
+++ b/console/react/src/topology/traffic.js
@@ -334,29 +334,6 @@ class Dots extends TrafficAnimation {
       // set excludedAddresses
       this.updateAddresses();
     });
-    let self = this;
-    // event notification that an address checkbox has changed
-    traffic.$scope.addressFilterChanged = function() {
-      self.updateAddresses();
-      // don't wait for the next polling cycle. update now
-      self.traffic.stop();
-      self.traffic.start();
-    };
-    // called when mouse enters one of the address legends
-    traffic.$scope.enterLegend = function(address) {
-      // fade all flows that aren't for this address
-      self.fadeOtherAddresses(address);
-    };
-    // called when the mouse leaves one of the address legends
-    traffic.$scope.leaveLegend = function() {
-      self.unFadeAll();
-    };
-    // clicked on the address name. toggle the address checkbox
-    traffic.$scope.addressClick = function(address) {
-      self.toggleAddress(address).then(function() {
-        self.updateAddresses();
-      });
-    };
   }
   remove() {
     d3.select("#SVG_ID")
@@ -378,14 +355,6 @@ class Dots extends TrafficAnimation {
       this.chordData.setFilter(this.excludedAddresses);
     }
   }
-  toggleAddress(address) {
-    this.traffic.$scope.addresses[address] = !this.traffic.$scope.addresses[
-      address
-    ];
-    return new Promise(function(resolve) {
-      return resolve();
-    });
-  }
   fadeOtherAddresses(address) {
     d3.selectAll("circle.flow").classed("fade", function(d) {
       return d.address !== address;
@@ -417,8 +386,14 @@ class Dots extends TrafficAnimation {
   }
   render(matrix) {
     if (this.stopped === false) {
-      this.traffic.$scope.addresses = this.chordData.getAddresses();
-      
this.traffic.$scope.handleUpdatedAddresses(this.traffic.$scope.addresses);
+      const addresses = this.chordData.getAddresses();
+      this.traffic.$scope.handleUpdatedAddresses(addresses);
+      const addressColors = {};
+      for (let address in addresses) {
+        this.fillColor(address, addressColors);
+      }
+      this.traffic.$scope.handleUpdateAddressColors(addressColors);
+
       // get the rate of message flow between routers
       let hops = {}; // every hop between routers that is involved in message 
flow
       let matrixMessages = matrix.matrixMessages();
@@ -639,7 +614,7 @@ class Dots extends TrafficAnimation {
     }
   }
   addressIndex(vis, address) {
-    return Object.keys(vis.traffic.$scope.addresses).indexOf(address);
+    return Object.keys(vis.traffic.addresses).indexOf(address);
   }
   // calculate the translation for each dot along the path
   translateDots(radius, path, count, back) {


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

Reply via email to