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/05/30 23:35:49 UTC
[02/11] qpid-dispatch git commit: DISPATCH-1001 Removed the
deprecated directories
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/a5e2307f/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.controller.js
----------------------------------------------------------------------
diff --git a/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.controller.js b/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.controller.js
deleted file mode 100644
index 208ff43..0000000
--- a/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.controller.js
+++ /dev/null
@@ -1,1703 +0,0 @@
-/*
-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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function (QDR) {
- 'use strict';
-
- angular
- .module('horizon.dashboard.dispatch.topology')
- .controller('horizon.dashboard.dispatch.topology.TopologyController', TopologyController);
-
- TopologyController.$inject = [
- '$scope',
- '$rootScope',
- 'horizon.dashboard.dispatch.comService',
- '$location',
- '$timeout',
- '$modal',
- ]
-
- var mouseX, mouseY;
- var dontHide = false;
- function hideLinkDetails() {
- d3.select("#link_details").transition()
- .duration(500)
- .style("opacity", 0)
- .each("end", function (d) {
- d3.select("#link_details").style("visibility", "hidden")
- })
- }
-
- function TopologyController(
- $scope,
- $rootScope,
- QDRService,
- $location,
- $timeout,
- $modal) {
-
- var ctrl = this;
- QDRService.addConnectAction( function () {
- Topology($scope, $rootScope, QDRService, $location, $timeout, $modal)
- })
- QDRService.loadConnectOptions(QDRService.connect);
-
- $scope.multiData = []
- $scope.multiDetails = {
- data: 'multiData',
- enableRowSelection: true,
- enableRowHeaderSelection: false,
- multiSelect: false,
- enableColumnResize: true,
- enableColumnReordering: true,
- enableVerticalScrollbar: 0,
- enableHorizontalScrollbar: 0,
- onRegisterApi: function(gridApi){
- gridApi.selection.on.rowSelectionChanged($scope, function(row){
- var detailsDiv = d3.select('#link_details')
- var isVis = detailsDiv.style('visibility') === 'visible';
- if (!dontHide && isVis && $scope.connectionId === row.entity.connectionId) {
- hideLinkDetails();
- return;
- }
- dontHide = false;
- $scope.multiDetails.showLinksList(row)
- });
- },
- showLinksList: function (obj) {
- $scope.linkData = obj.entity.linkData;
- $scope.connectionId = obj.entity.connectionId;
- var visibleLen = Math.min(obj.entity.linkData.length, 10)
- var left = parseInt(d3.select('#multiple_details').style("left"))
- var bounds = $("#topology").position()
- var detailsDiv = d3.select('#link_details')
- detailsDiv
- .style({
- visibility: 'visible',
- opacity: 1,
- left: (left + 20) + "px",
- top: (mouseY + 40 - bounds.top + $(document).scrollTop()) + "px",
- height: ((visibleLen + 1) * 30) + 40 + "px", // +1 for the header row
- 'overflow-y': obj.entity.linkData > 10 ? 'scroll' : 'hidden'})
- },
- columnDefs: [
- {
- field: 'host',
- displayName: 'Connection host'
- },
- {
- field: 'user',
- displayName: 'User'
- },
- {
- field: 'properties',
- displayName: 'Properties'
- },
-/*
- {
- cellClass: 'gridCellButton',
- cellTemplate: '<button title="{{quiesceText(row)}} the links" type="button" ng-class="quiesceClass(row)" class="btn" ng-click="$event.stopPropagation();quiesceConnection(row)" ng-disabled="quiesceDisabled(row)">{{quiesceText(row)}}</button>'
- },
-*/
- ]
- };
- $scope.linkData = [];
- $scope.linkDetails = {
- data: 'linkData',
- enableRowSelection: true,
- enableRowHeaderSelection: false,
- multiSelect: false,
- enableColumnResize: true,
- enableColumnReordering: true,
- enableVerticalScrollbar: 0,
- enableHorizontalScrollbar: 0,
- columnDefs: [
- {
- field: 'adminStatus',
- displayName: 'Admin state'
- },
- {
- field: 'operStatus',
- displayName: 'Oper state'
- },
- {
- field: 'dir',
- displayName: 'dir'
- },
- {
- field: 'owningAddr',
- displayName: 'Address'
- },
- {
- field: 'deliveryCount',
- displayName: 'Delivered',
- cellClass: 'grid-values'
-
- },
- {
- field: 'uncounts',
- displayName: 'Outstanding',
- cellClass: 'grid-values'
- }/*,
- {
- cellClass: 'gridCellButton',
- cellTemplate: '<button title="{{quiesceLinkText(row)}} this link" type="button" ng-class="quiesceLinkClass(row)" class="btn" ng-click="quiesceLink(row)" ng-disabled="quiesceLinkDisabled(row)">{{quiesceLinkText(row)}}</button>'
- }*/
- ]
- }
- }
-
- function Topology(
- $scope,
- $rootScope,
- QDRService,
- $location,
- $timeout,
- $modal) {
-
- $scope.quiesceState = {}
- $scope.quiesceConnection = function (row) {
- // call method to set adminStatus
- }
- $scope.quiesceDisabled = function (row) {
- return false;
- }
- $scope.quiesceText = function (row) {
- return 'Quiesce'
- }
- $scope.quiesceClass = function (row) {
- var stateClassMap = {
- enabled: 'btn-primary',
- quiescing: 'btn-warning',
- reviving: 'btn-warning',
- quiesced: 'btn-danger'
- }
- return 'btn-primary'
- }
- $scope.quiesceLinkClass = function (row) {
- var stateClassMap = {
- enabled: 'btn-primary',
- disabled: 'btn-danger'
- }
- return stateClassMap[row.entity.adminStatus]
- }
- $scope.quiesceLink = function (row) {
- QDRService.quiesceLink(row.entity.nodeId, row.entity.name);
- }
- $scope.quiesceLinkDisabled = function (row) {
- return (row.entity.operStatus !== 'up' && row.entity.operStatus !== 'down')
- }
- $scope.quiesceLinkText = function (row) {
- return row.entity.operStatus === 'down' ? "Revive" : "Quiesce";
- }
-
- // we are currently connected. setup a handler to get notified if we are ever disconnected
- QDRService.addDisconnectAction( function () {
- QDR.log.debug("disconnected from router. show a toast message");
- })
-
- var urlPrefix = $location.absUrl();
- urlPrefix = urlPrefix.split("#")[0]
- QDR.log.debug("started QDR.TopologyController with urlPrefix: " + urlPrefix);
-
- $scope.addingNode = {
- step: 0,
- hasLink: false,
- trigger: ''
- };
-
- $scope.cancel = function () {
- $scope.addingNode.step = 0;
- }
- $scope.editNewRouter = function () {
- $scope.addingNode.trigger = 'editNode';
- }
-
- var NewRouterName = "__NEW__";
- // mouse event vars
- var selected_node = null,
- selected_link = null,
- mousedown_link = null,
- mousedown_node = null,
- mouseup_node = null,
- initial_mouse_down_position = null;
-
- $scope.schema = "Not connected";
-
- $scope.modes = [
- {title: 'Topology view', name: 'Diagram', right: false},
- /* {title: 'Add a new router node', name: 'Add Router', right: true} */
- ];
- $scope.mode = "Diagram";
- $scope.contextNode = null; // node that is associated with the current context menu
-
- $scope.isModeActive = function (name) {
- if ((name == 'Add Router' || name == 'Diagram') && $scope.addingNode.step > 0)
- return true;
- return ($scope.mode == name);
- }
- $scope.selectMode = function (name) {
- if (name == "Add Router") {
- name = 'Diagram';
- if ($scope.addingNode.step > 0) {
- $scope.addingNode.step = 0;
- } else {
- // start adding node mode
- $scope.addingNode.step = 1;
- }
- } else {
- $scope.addingNode.step = 0;
- }
-
- $scope.mode = name;
- }
- $scope.$watch(function () {return $scope.addingNode.step}, function (newValue, oldValue) {
- if (newValue == 0 && oldValue != 0) {
- // we are cancelling the add
-
- // find the New node
- nodes.every(function (n, i) {
- // for the placeholder node, the key will be __internal__
- if (QDRService.nameFromId(n.key) == '__internal__') {
- var newLinks = links.filter(function (e, i) {
- return e.source.id == n.id || e.target.id == n.id;
- })
- // newLinks is an array of links to remove
- newLinks.map(function (e) {
- links.splice(links.indexOf(e), 1);
- })
- // i is the index of the node to remove
- nodes.splice(i, 1);
- force.nodes(nodes).links(links).start();
- restart(false);
- return false; // stop looping
- }
- return true;
- })
- updateForm(Object.keys(QDRService.topology.nodeInfo())[0], 'router', 0);
-
- } else if (newValue > 0) {
- // we are starting the add mode
- $scope.$broadcast('showAddForm')
-
- resetMouseVars();
- selected_node = null;
- selected_link = null;
- // add a new node
- var id = "amqp:/_topo/0/__internal__/$management";
- var x = radiusNormal * 4;
- var y = x;;
- if (newValue > 1) { // add at current mouse position
- var offset = jQuery('#topology').offset();
- x = mouseX - offset.left + $(document).scrollLeft();
- y = mouseY - offset.top + $(document).scrollTop();;
- }
- NewRouterName = genNewName();
- nodes.push( aNode(id, NewRouterName, "inter-router", undefined, nodes.length, x, y, undefined, true) );
- force.nodes(nodes).links(links).start();
- restart(false);
- }
- })
-
- $scope.isRight = function (mode) {
- return mode.right;
- }
-
- // for ng-grid that shows details for multiple consoles/clients
- // generate unique name for router and containerName
- var genNewName = function () {
- var nodeInfo = QDRService.topology.nodeInfo();
- var nameIndex = 1;
- var newName = "R." + nameIndex;
-
- var names = [];
- for (var key in nodeInfo) {
- var node = nodeInfo[key];
- var router = node['.router'];
- var attrNames = router.attributeNames;
- var name = QDRService.valFor(attrNames, router.results[0], 'routerId')
- if (!name)
- name = QDRService.valFor(attrNames, router.results[0], 'name')
- names.push(name);
- }
-
- while (names.indexOf(newName) >= 0) {
- newName = "R." + nameIndex++;
- }
- return newName;
- }
-
- $scope.$watch(function () {return $scope.addingNode.trigger}, function (newValue, oldValue) {
- if (newValue == 'editNode') {
- $scope.addingNode.trigger = "";
- editNode();
- }
- })
-
- function editNode() {
- doAddDialog(NewRouterName);
- };
- $scope.reverseLink = function () {
- if (!mousedown_link)
- return;
- var d = mousedown_link;
- var tmp = d.left;
- d.left = d.right;;
- d.right = tmp;
- restart(false);
- tick();
- }
- $scope.removeLink = function () {
- if (!mousedown_link)
- return;
- var d = mousedown_link;
- links.every( function (l, i) {
- if (l.source.id == d.source.id && l.target.id == d.target.id) {
- links.splice(i, 1);
- force.links(links).start();
- return false; // exit the 'every' loop
- }
- return true;
- });
- restart(false);
- tick();
- }
- $scope.setFixed = function (b) {
- if ($scope.contextNode) {
- $scope.contextNode.fixed = b;
- }
- restart();
- }
- $scope.isFixed = function () {
- if (!$scope.contextNode)
- return false;
- return ($scope.contextNode.fixed & 0b1);
- }
-
- // event handlers for popup context menu
- $(document).mousemove(function (e) {
- mouseX = e.clientX;
- mouseY = e.clientY;
- //console.log("("+mouseX+"," + mouseY+")")
- });
- $(document).mousemove();
- $(document).click(function (e) {
- $scope.contextNode = null;
- $(".contextMenu").fadeOut(200);
- });
-
- // set up SVG for D3
- var colors = {'inter-router': "#EAEAEA", 'normal': "#F0F000", 'on-demand': '#00F000'};
- var radii = {'inter-router': 25, 'normal': 15, 'on-demand': 15};
- var radius = 25;
- var radiusNormal = 15;
- var svg, lsvg;
- var force;
- var animate = false; // should the force graph organize itself when it is displayed
- var path, circle;
- var savedKeys = {};
- var width = 0;
- var height = 0;
-
- var getSizes = function () {
- var legendWidth = 196;
- var gap = 5;
- var width = $('.qdrTopology').width() - gap - legendWidth;
- var top = $('#topology').offset().top
- var tpformHeight = $('#topologyForm').height()
- var height = window.innerHeight - tpformHeight - top - gap;
- if (height < 400)
- height = 400;
-/*
- QDR.log.debug("window.innerHeight:" + window.innerHeight +
- " tpformHeight:" + tpformHeight +
- " top:" + top +
- " gap:" + gap +
- " width:" + width +
- " height:" + height)
-*/
- if (width < 10 || height < 30) {
- QDR.log.info("page width and height are abnormal w:" + width + " height:" + height)
- return [0,0];
- }
- return [width, height]
- }
- var resize = function () {
- var sizes = getSizes();
- width = sizes[0]
- height = sizes[1]
- if (width > 0) {
- // set attrs and 'resume' force
- svg.attr('width', width);
- svg.attr('height', height);
- force.size(sizes).resume();
- }
- }
- window.addEventListener('resize', resize);
- var sizes = getSizes()
- width = sizes[0]
- height = sizes[1]
- height = 300
- if (width <= 0 || height <= 0)
- return
-
- // set up initial nodes and links
- // - nodes are known by 'id', not by index in array.
- // - selected edges are indicated on the node (as a bold red circle).
- // - links are always source < target; edge directions are set by 'left' and 'right'.
- var nodes = [];
- var links = [];
-
- var aNode = function (id, name, nodeType, nodeInfo, nodeIndex, x, y, resultIndex, fixed, properties) {
- properties = properties || {};
- var routerId;
- if (nodeInfo) {
- var node = nodeInfo[id];
- if (node) {
- var router = node['.router'];
- routerId = QDRService.valFor(router.attributeNames, router.results[0], 'id')
- if (!routerId)
- routerId = QDRService.valFor(router.attributeNames, router.results[0], 'routerId')
- }
- }
- return { key: id,
- name: name,
- nodeType: nodeType,
- properties: properties,
- routerId: routerId,
- x: x,
- y: y,
- id: nodeIndex,
- resultIndex: resultIndex,
- fixed: fixed,
- cls: name == NewRouterName ? 'temp' : ''
- };
- };
-
-
- var initForm = function (attributes, results, entityType, formFields) {
-
- while(formFields.length > 0) {
- // remove all existing attributes
- formFields.pop();
- }
-
- for (var i=0; i<attributes.length; ++i) {
- var name = attributes[i];
- var val = results[i];
- var desc = "";
- if (entityType.attributes[name])
- if (entityType.attributes[name].description)
- desc = entityType.attributes[name].description;
-
- formFields.push({'attributeName': name, 'attributeValue': val, 'description': desc});
- }
- }
-
- // initialize the nodes and links array from the QDRService.topology._nodeInfo object
- var initForceGraph = function () {
- nodes = [];
- links = [];
-
- svg = d3.select('#topology')
- .append('svg')
- .attr("id", "SVG_ID")
- .attr('width', width)
- .attr('height', height)
- .on("contextmenu", function(d) {
- if (QDR.isHorizon)
- return;
- if (d3.event.defaultPrevented)
- return;
- d3.event.preventDefault();
- if ($scope.addingNode.step != 0)
- return;
- if (d3.select('#svg_context_menu').style('display') !== 'block')
- $(document).click();
- d3.select('#svg_context_menu')
- .style('left', (mouseX + $(document).scrollLeft()) + "px")
- .style('top', (mouseY + $(document).scrollTop()) + "px")
- .style('display', 'block');
- })
- .on('click', function (d) {
- removeCrosssection()
- });
-
- $(document).keyup(function(e) {
- if (e.keyCode === 27) {
- removeCrosssection()
- }
- });
-
- // the legend
- lsvg = d3.select("#svg_legend")
- .append('svg')
- .attr('id', 'svglegend')
- lsvg = lsvg.append('svg:g')
- .attr('transform', 'translate('+(radii['inter-router']+2)+','+(radii['inter-router']+2)+')')
- .selectAll('g');
-
- // mouse event vars
- selected_node = null;
- selected_link = null;
- mousedown_link = null;
- mousedown_node = null;
- mouseup_node = null;
-
- // initialize the list of nodes
- var yInit = 10;
- var nodeInfo = QDRService.topology.nodeInfo();
- var nodeCount = Object.keys(nodeInfo).length;
- for (var id in nodeInfo) {
- var name = QDRService.nameFromId(id);
- // if we have any new nodes, animate the force graph to position them
- var position = angular.fromJson(localStorage[name]);
- if (!angular.isDefined(position)) {
- animate = true;
- position = {x: width / 4 + ((width / 2)/nodeCount) * nodes.length,
- y: 200 + yInit,
- fixed: false};
- }
- if (position.y > height)
- position.y = 200 - yInit;
- nodes.push( aNode(id, name, "inter-router", nodeInfo, nodes.length, position.x, position.y, undefined, position.fixed) );
- yInit *= -1;
- //QDR.log.debug("adding node " + nodes.length-1);
- }
-
- // initialize the list of links
- var source = 0;
- var client = 1;
- for (var id in nodeInfo) {
- var onode = nodeInfo[id];
- var conns = onode['.connection'].results;
- var attrs = onode['.connection'].attributeNames;
- var parent = getNodeIndex(QDRService.nameFromId(id));
- //QDR.log.debug("external client parent is " + parent);
- var normalsParent = {console: undefined, client: undefined}; // 1st normal node for this parent
-
- for (var j = 0; j < conns.length; j++) {
- var role = QDRService.valFor(attrs, conns[j], "role");
- var properties = QDRService.valFor(attrs, conns[j], "properties") || {};
- var dir = QDRService.valFor(attrs, conns[j], "dir");
- if (role == "inter-router") {
- var connId = QDRService.valFor(attrs, conns[j], "container");
- var target = getContainerIndex(connId);
- if (target >= 0)
- getLink(source, target, dir);
- } else if (role == "normal" || role == "on-demand") {
- // not a router, but an external client
- //QDR.log.debug("found an external client for " + id);
- var name = QDRService.nameFromId(id) + "." + client;
- //QDR.log.debug("external client name is " + name + " and the role is " + role);
-
- // if we have any new clients, animate the force graph to position them
- var position = angular.fromJson(localStorage[name]);
- if (!angular.isDefined(position)) {
- animate = true;
- position = {x: nodes[parent].x + 40 + Math.sin(Math.PI/2 * client),
- y: nodes[parent].y + 40 + Math.cos(Math.PI/2 * client),
- fixed: false};
- }
- if (position.y > height)
- position.y = nodes[parent].y + 40 + Math.cos(Math.PI/2 * client)
- var node = aNode(id, name, role, nodeInfo, nodes.length, position.x, position.y, j, position.fixed, properties)
- var nodeType = QDRService.isAConsole(properties, QDRService.valFor(attrs, conns[j], "identity"), role, node.key)
-
- if (role === 'normal') {
- node.user = QDRService.valFor(attrs, conns[j], "user")
- node.isEncrypted = QDRService.valFor(attrs, conns[j], "isEncrypted")
- node.host = QDRService.valFor(attrs, conns[j], "host")
- node.connectionId = QDRService.valFor(attrs, conns[j], "identity")
-
- if (!normalsParent[nodeType]) {
- normalsParent[nodeType] = node;
- nodes.push( node );
- node.normals = [node];
- // now add a link
- getLink(parent, nodes.length-1, dir);
- client++;
- } else {
- normalsParent[nodeType].normals.push(node)
- }
- } else {
- nodes.push( node)
- // now add a link
- getLink(parent, nodes.length-1, dir);
- client++;
- }
- }
- }
- source++;
- }
-
- $scope.schema = QDRService.schema;
- // init D3 force layout
- force = d3.layout.force()
- .nodes(nodes)
- .links(links)
- .size([width, height])
- .linkDistance(function(d) { return d.target.nodeType === 'inter-router' ? 150 : 65 })
- .charge(-1800)
- .friction(.10)
- .gravity(0.0001)
- .on('tick', tick)
- .start()
-
- svg.append("svg:defs").selectAll('marker')
- .data(["end-arrow", "end-arrow-selected"]) // Different link/path types can be defined here
- .enter().append("svg:marker") // This section adds in the arrows
- .attr("id", String)
- .attr("viewBox", "0 -5 10 10")
- //.attr("refX", 25)
- .attr("markerWidth", 4)
- .attr("markerHeight", 4)
- .attr("orient", "auto")
- .append("svg:path")
- .attr('d', 'M 0 -5 L 10 0 L 0 5 z')
-
- svg.append("svg:defs").selectAll('marker')
- .data(["start-arrow", "start-arrow-selected"]) // Different link/path types can be defined here
- .enter().append("svg:marker") // This section adds in the arrows
- .attr("id", String)
- .attr("viewBox", "0 -5 10 10")
- .attr("refX", 5)
- .attr("markerWidth", 4)
- .attr("markerHeight", 4)
- .attr("orient", "auto")
- .append("svg:path")
- .attr('d', 'M 10 -5 L 0 0 L 10 5 z');
-
- // handles to link and node element groups
- path = svg.append('svg:g').selectAll('path'),
- circle = svg.append('svg:g').selectAll('g');
-
- force.on('end', function() {
- //QDR.log.debug("force end called");
- circle
- .attr('cx', function(d) {
- localStorage[d.name] = angular.toJson({x: d.x, y: d.y, fixed: d.fixed});
- return d.x; });
- });
-
- // app starts here
- restart(false);
- force.start();
- setTimeout(function () {
- updateForm(Object.keys(QDRService.topology.nodeInfo())[0], 'router', 0);
- }, 10)
-
- }
-
- function updateForm (key, entity, resultIndex) {
- var nodeInfo = QDRService.topology.nodeInfo();
- var onode = nodeInfo[key]
- if (onode) {
- var nodeResults = onode['.' + entity].results[resultIndex]
- var nodeAttributes = onode['.' + entity].attributeNames
- var attributes = nodeResults.map( function (row, i) {
- return {
- attributeName: nodeAttributes[i],
- attributeValue: row
- }
- })
- // sort by attributeName
- attributes.sort( function (a, b) { return a.attributeName.localeCompare(b.attributeName) })
-
- // move the Name first
- var nameIndex = attributes.findIndex ( function (attr) {
- return attr.attributeName === 'name'
- })
- if (nameIndex >= 0)
- attributes.splice(0, 0, attributes.splice(nameIndex, 1)[0]);
- // get the list of ports this router is listening on
- if (entity === 'router') {
- var listeners = onode['.listener'].results;
- var listenerAttributes = onode['.listener'].attributeNames;
- var normals = listeners.filter ( function (listener) {
- return QDRService.valFor( listenerAttributes, listener, 'role') === 'normal';
- })
- var ports = []
- normals.forEach (function (normalListener) {
- ports.push(QDRService.valFor( listenerAttributes, normalListener, 'port'))
- })
- // add as 2nd row
- if (ports.length)
- attributes.splice(1, 0, {attributeName: 'Listening on', attributeValue: ports, description: 'The port on which this router is listening for connections'});
- }
-
- $scope.$broadcast('showEntityForm', {entity: entity, attributes: attributes})
- }
- if (!$scope.$$phase) $scope.$apply()
- }
-
- function getContainerIndex(_id) {
- var nodeIndex = 0;
- var nodeInfo = QDRService.topology.nodeInfo();
- for (var id in nodeInfo) {
- var node = nodeInfo[id]['.router'];
- // there should be only one router entity for each node, so using results[0] should be fine
- if (QDRService.valFor( node.attributeNames, node.results[0], "id") === _id)
- return nodeIndex;
- if (QDRService.valFor( node.attributeNames, node.results[0], "routerId") === _id)
- return nodeIndex;
- nodeIndex++
- }
- // there was no router.id that matched, check deprecated router.routerId
- nodeIndex = 0;
- for (var id in nodeInfo) {
- var node = nodeInfo[id]['.container'];
- if (node) {
- if (QDRService.valFor ( node.attributeNames, node.results[0], "containerName") === _id)
- return nodeIndex;
- }
- nodeIndex++
- }
- //QDR.log.warn("unable to find containerIndex for " + _id);
- return -1;
- }
-
- function getNodeIndex (_id) {
- var nodeIndex = 0;
- var nodeInfo = QDRService.topology.nodeInfo();
- for (var id in nodeInfo) {
- if (QDRService.nameFromId(id) == _id) return nodeIndex;
- nodeIndex++
- }
- QDR.log.warn("unable to find nodeIndex for " + _id);
- return -1;
- }
-
- function getLink (_source, _target, dir, cls) {
- for (var i=0; i < links.length; i++) {
- var s = links[i].source, t = links[i].target;
- if (typeof links[i].source == "object") {
- s = s.id;
- t = t.id;
- }
- if (s == _source && t == _target) {
- return i;
- }
- // same link, just reversed
- if (s == _target && t == _source) {
- return -i;
- }
- }
-
- //QDR.log.debug("creating new link (" + (links.length) + ") between " + nodes[_source].name + " and " + nodes[_target].name);
- var link = {
- source: _source,
- target: _target,
- left: dir != "out",
- right: dir == "out",
- cls: cls
- };
- return links.push(link) - 1;
- }
-
-
- function resetMouseVars() {
- mousedown_node = null;
- mouseup_node = null;
- mousedown_link = null;
- }
-
- // update force layout (called automatically each iteration)
- function tick() {
- circle.attr('transform', function (d) {
- var cradius;
- if (d.nodeType == "inter-router") {
- cradius = d.left ? radius + 8 : radius;
- } else {
- cradius = d.left ? radiusNormal + 18 : radiusNormal;
- }
- d.x = Math.max(d.x, radiusNormal * 2);
- d.y = Math.max(d.y, radiusNormal * 2);
- d.x = Math.max(0, Math.min(width-cradius, d.x))
- d.y = Math.max(0, Math.min(height-cradius, d.y))
- return 'translate(' + d.x + ',' + d.y + ')';
- });
-
- // draw directed edges with proper padding from node centers
- path.attr('d', function (d) {
- //QDR.log.debug("in tick for d");
- //console.dump(d);
- var sourcePadding, targetPadding, r;
-
- if (d.target.nodeType == "inter-router") {
- r = radius;
- // right arrow left line start
- sourcePadding = d.left ? radius + 8 : radius;
- // left arrow right line start
- targetPadding = d.right ? radius + 16 : radius;
- } else {
- r = radiusNormal - 18;
- sourcePadding = d.left ? radiusNormal + 18 : radiusNormal;
- targetPadding = d.right ? radiusNormal + 16 : radiusNormal;
- }
- var dtx = Math.max(targetPadding, Math.min(width-r, d.target.x)),
- dty = Math.max(targetPadding, Math.min(height-r, d.target.y)),
- dsx = Math.max(sourcePadding, Math.min(width-r, d.source.x)),
- dsy = Math.max(sourcePadding, Math.min(height-r, d.source.y));
-
- var deltaX = dtx - dsx,
- deltaY = dty - dsy,
- dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY),
- normX = deltaX / dist,
- normY = deltaY / dist;
- var sourceX = dsx + (sourcePadding * normX),
- sourceY = dsy + (sourcePadding * normY),
- targetX = dtx - (targetPadding * normX),
- targetY = dty - (targetPadding * normY);
- sourceX = Math.max(0, Math.min(width, sourceX))
- sourceY = Math.max(0, Math.min(width, sourceY))
- targetX = Math.max(0, Math.min(width, targetX))
- targetY = Math.max(0, Math.min(width, targetY))
-
- return 'M' + sourceX + ',' + sourceY + 'L' + targetX + ',' + targetY;
- });
-
- if (!animate) {
- animate = true;
- force.stop();
- }
- }
-
- // highlight the paths between the selected node and the hovered node
- function findNextHopNode(from, d) {
- // d is the node that the mouse is over
- // from is the selected_node ....
- if (!from)
- return null;
-
- if (from == d)
- return selected_node;
-
- //QDR.log.debug("finding nextHop from: " + from.name + " to " + d.name);
- var sInfo = QDRService.topology.nodeInfo()[from.key];
-
- if (!sInfo) {
- QDR.log.warn("unable to find topology node info for " + from.key);
- return null;
- }
-
- // find the hovered name in the selected name's .router.node results
- if (!sInfo['.router.node'])
- return null;
- var aAr = sInfo['.router.node'].attributeNames;
- var vAr = sInfo['.router.node'].results;
- for (var hIdx=0; hIdx<vAr.length; ++hIdx) {
- var addrT = QDRService.valFor(aAr, vAr[hIdx], "id" );
- if (addrT == d.name) {
- //QDR.log.debug("found " + d.name + " at " + hIdx);
- var nextHop = QDRService.valFor(aAr, vAr[hIdx], "nextHop");
- //QDR.log.debug("nextHop was " + nextHop);
- return (nextHop == null) ? nodeFor(addrT) : nodeFor(nextHop);
- }
- }
- return null;
- }
-
- function nodeFor(name) {
- for (var i=0; i<nodes.length; ++i) {
- if (nodes[i].name == name)
- return nodes[i];
- }
- return null;
- }
-
- function linkFor(source, target) {
- for (var i=0; i<links.length; ++i) {
- if ((links[i].source == source) && (links[i].target == target))
- return links[i];
- if ((links[i].source == target) && (links[i].target == source))
- return links[i];
- }
- // the selected node was a client/broker
- //QDR.log.debug("failed to find a link between ");
- //console.dump(source);
- //QDR.log.debug(" and ");
- //console.dump(target);
- return null;
- }
-
- function clearPopups() {
- d3.select("#crosssection").style("display", "none");
- $('.hastip').empty();
- d3.select("#multiple_details").style("visibility", "hidden")
- d3.select("#link_details").style("visibility", "hidden")
- d3.select('#node_context_menu').style('display', 'none');
- }
- function removeCrosssection() {
- setTimeout(function () {
- //d3.select("[id^=tooltipsy]").remove()
- $('.hastip').empty();
- }, 1010);
- d3.select("#crosssection svg g").transition()
- .duration(1000)
- .attr("transform", "scale(0)")
- .style("opacity", 0)
- .each("end", function (d) {
- d3.select("#crosssection svg").remove();
- d3.select("#crosssection").style("display","none");
- });
- d3.select("#multiple_details").transition()
- .duration(500)
- .style("opacity", 0)
- .each("end", function (d) {
- d3.select("#multiple_details").style("visibility", "hidden")
- stopUpdateConnectionsGrid();
- })
- hideLinkDetails();
- }
-
- // takes the nodes and links array of objects and adds svg elements for everything that hasn't already
- // been added
- function restart(start) {
- circle.call(force.drag);
-
- // path (link) group
- path = path.data(links);
-
- // update existing links
- path.classed('selected', function(d) { return d === selected_link; })
- .classed('highlighted', function(d) { return d.highlighted; } )
- .classed('temp', function(d) { return d.cls == 'temp'; } )
- .attr('marker-start', function(d) {
- var sel = d===selected_link ? '-selected' : '';
- return d.left ? 'url('+urlPrefix+'#start-arrow' + sel + ')' : ''; })
- .attr('marker-end', function(d) {
- var sel = d===selected_link ? '-selected' : '';
- return d.right ? 'url('+urlPrefix+'#end-arrow' + sel +')' : ''; })
-
-
- // add new links. if links[] is longer than the existing paths, add a new path for each new element
- path.enter().append('svg:path')
- .attr('class', 'link')
- .attr('marker-start', function(d) {
- var sel = d===selected_link ? '-selected' : '';
- return d.left ? 'url('+urlPrefix+'#start-arrow' + sel + ')' : ''; })
- .attr('marker-end', function(d) {
- var sel = d===selected_link ? '-selected' : '';
- return d.right ? 'url('+urlPrefix+'#end-arrow' + sel + ')' : ''; })
- .classed('temp', function(d) { return d.cls == 'temp'; } )
- // mouseover a line
- .on('mouseover', function (d) {
- if($scope.addingNode.step > 0) {
- if (d.cls == 'temp') {
- d3.select(this).classed('over', true);
- }
- return;
- }
- //QDR.log.debug("showing connections form");
- var resultIndex = 0; // the connection to use
- var left = d.left ? d.target : d.source;
- // right is the node that the arrow points to, left is the other node
- var right = d.left ? d.source : d.target;
- var onode = QDRService.topology.nodeInfo()[left.key];
- // loop through all the connections for left, and find the one for right
- if (!onode || !onode['.connection'])
- return;
- // update the info dialog for the link the mouse is over
- if (!selected_node && !selected_link) {
- for (resultIndex=0; resultIndex < onode['.connection'].results.length; ++resultIndex) {
- var conn = onode['.connection'].results[resultIndex];
- /// find the connection whose container is the right's name
- var name = QDRService.valFor(onode['.connection'].attributeNames, conn, "container");
- if (name == right.routerId) {
- break;
- }
- }
- // did not find connection. this is a connection to a non-interrouter node
- if (resultIndex === onode['.connection'].results.length) {
- // use the non-interrouter node's connection info
- left = d.target;
- resultIndex = left.resultIndex;
- }
- if (resultIndex)
- updateForm(left.key, 'connection', resultIndex);
- }
-
- mousedown_link = d;
- selected_link = mousedown_link;
- restart();
- })
- // mouseout a line
- .on('mouseout', function (d) {
- if($scope.addingNode.step > 0) {
- if (d.cls == 'temp') {
- d3.select(this).classed('over', false);
- }
- return;
- }
- //QDR.log.debug("showing connections form");
- selected_link = null;
- restart();
- })
- // contextmenu for a line
- .on("contextmenu", function(d) {
- $(document).click();
- d3.event.preventDefault();
- if (d.cls !== "temp")
- return;
-
- mousedown_link = d;
- d3.select('#link_context_menu')
- .style('left', (mouseX + $(document).scrollLeft()) + "px")
- .style('top', (mouseY + $(document).scrollTop()) + "px")
- .style('display', 'block');
- })
- // clicked on a line
- .on("click", function (d) {
- var clickPos = d3.mouse(this);
- d3.event.stopPropagation();
- clearPopups();
- var diameter = 400;
- var format = d3.format(",d");
- var pack = d3.layout.pack()
- .size([diameter - 4, diameter - 4])
- .padding(-10)
- .value(function(d) { return d.size; });
-
- d3.select("#crosssection svg").remove();
- var svg = d3.select("#crosssection").append("svg")
- .attr("width", diameter)
- .attr("height", diameter)
- var svgg = svg.append("g")
- .attr("transform", "translate(2,2)");
-
- var root = {
- name: " Links between " + d.source.name + " and " + d.target.name,
- children: []
- }
- var nodeInfo = QDRService.topology.nodeInfo();
- var connections = nodeInfo[d.source.key]['.connection'];
- var containerIndex = connections.attributeNames.indexOf('container');
- connections.results.some ( function (connection) {
- if (connection[containerIndex] == d.target.routerId) {
- root.attributeNames = connections.attributeNames;
- root.obj = connection;
- root.desc = "Connection";
- return true; // stop looping after 1 match
- }
- return false;
- })
-
- // find router.links where link.remoteContainer is d.source.name
- var links = nodeInfo[d.source.key]['.router.link'];
- var identityIndex = connections.attributeNames.indexOf('identity')
- var roleIndex = connections.attributeNames.indexOf('role')
- var connectionIdIndex = links.attributeNames.indexOf('connectionId');
- var linkTypeIndex = links.attributeNames.indexOf('linkType');
- var nameIndex = links.attributeNames.indexOf('name');
- var linkDirIndex = links.attributeNames.indexOf('linkDir');
-
- if (roleIndex < 0 || identityIndex < 0 || connectionIdIndex < 0
- || linkTypeIndex < 0 || nameIndex < 0 || linkDirIndex < 0)
- return;
- links.results.forEach ( function (link) {
- if (root.obj && link[connectionIdIndex] == root.obj[identityIndex] && link[linkTypeIndex] == root.obj[roleIndex])
- root.children.push (
- { name: " " + link[linkDirIndex] + " ",
- size: 100,
- obj: link,
- desc: "Link",
- attributeNames: links.attributeNames
- })
- })
- if (root.children.length == 0)
- return;
- var node = svgg.datum(root).selectAll(".node")
- .data(pack.nodes)
- .enter().append("g")
- .attr("class", function(d) { return d.children ? "parent node hastip" : "leaf node hastip"; })
- .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")" + (!d.children ? "scale(0.9)" : ""); })
- .attr("title", function (d) {
- var title = "<h4>" + d.desc + "</h4><table class='tiptable'><tbody>";
- if (d.attributeNames)
- d.attributeNames.forEach( function (n, i) {
- title += "<tr><td>" + n + "</td><td>";
- title += d.obj[i] != null ? d.obj[i] : '';
- title += '</td></tr>';
- })
- title += "</tbody></table>"
- return title
- })
- node.append("circle")
- .attr("r", function(d) { return d.r; });
-
-// node.filter(function(d) { return !d.children; }).append("text")
- node.append("text")
- .attr("dy", function (d) { return d.children ? "-10em" : ".5em"})
- .style("text-anchor", "middle")
- .text(function(d) {
- return d.name.substring(0, d.r / 3);
- });
- //$('.hastip').tooltipsy({ alignTo: 'cursor'});
- svgg.attr("transform", "translate(2,2) scale(0.01)")
-
- var bounds = $("#topology").position()
- d3.select("#crosssection")
- .style("display", "block")
- .style("left", (clickPos[0] + bounds.left) + "px")
- .style("top", (clickPos[1] + bounds.top) + "px")
-
- svgg.transition()
- .attr("transform", "translate(2,2) scale(1)")
- .each("end", function () {
- d3.selectAll("#crosssection g.leaf text").attr("dy", ".3em")
- })
- })
-
- // remove old links
- path.exit().remove();
-
-
- // circle (node) group
- // nodes are known by id
- circle = circle.data(nodes, function (d) {
- return d.id;
- });
-
- // update existing nodes visual states
- circle.selectAll('circle')
- .classed('selected', function (d) { return (d === selected_node) })
- .classed('fixed', function (d) { return (d.fixed & 0b1) })
-
- // add new circle nodes. if nodes[] is longer than the existing paths, add a new path for each new element
- var g = circle.enter().append('svg:g')
- .classed('multiple', function(d) { return (d.normals && d.normals.length > 1) } )
-
- var appendCircle = function (g) {
- // add new circles and set their attr/class/behavior
- return g.append('svg:circle')
- .attr('class', 'node')
- .attr('r', function (d) { return radii[d.nodeType] } )
- .classed('fixed', function (d) {return d.fixed})
- .classed('temp', function(d) { return QDRService.nameFromId(d.key) == '__internal__'; } )
- .classed('normal', function(d) { return d.nodeType == 'normal' } )
- .classed('inter-router', function(d) { return d.nodeType == 'inter-router' } )
- .classed('on-demand', function(d) { return d.nodeType == 'on-demand' } )
- .classed('console', function(d) { return QDRService.isConsole(d) } )
- .classed('artemis', function(d) { return QDRService.isArtemis(d) } )
- .classed('qpid-cpp', function(d) { return QDRService.isQpid(d) } )
- .classed('client', function(d) { return d.nodeType === 'normal' && !d.properties.console_identifier } )
- }
- appendCircle(g)
- .on('mouseover', function (d) { // mouseover a circle
- if ($scope.addingNode.step > 0) {
- d3.select(this).attr('transform', 'scale(1.1)');
- return;
- }
- if (!selected_node) {
- if (d.nodeType === 'inter-router') {
- //QDR.log.debug("showing general form");
- updateForm(d.key, 'router', 0);
- } else if (d.nodeType === 'normal' || d.nodeType === 'on-demand') {
- //QDR.log.debug("showing connections form");
- updateForm(d.key, 'connection', d.resultIndex);
- }
- }
-
- if (d === mousedown_node)
- return;
- //if (d === selected_node)
- // return;
- // enlarge target node
- d3.select(this).attr('transform', 'scale(1.1)');
- // highlight the next-hop route from the selected node to this node
- mousedown_node = null;
- if (!selected_node) {
- return;
- }
- setTimeout(nextHop, 1, selected_node, d);
- })
- .on('mouseout', function (d) { // mouseout a circle
- // unenlarge target node
- d3.select(this).attr('transform', '');
- for (var i=0; i<links.length; ++i) {
- links[i]['highlighted'] = false;
- }
- restart();
- })
- .on('mousedown', function (d) { // mousedown a circle
- if (d3.event.button !== 0) { // ignore all but left button
- return;
- }
- mousedown_node = d;
- // mouse position relative to svg
- initial_mouse_down_position = d3.mouse(this.parentElement.parentElement.parentElement).slice();
- })
- .on('mouseup', function (d) { // mouseup a circle
- if (!mousedown_node)
- return;
-
- selected_link = null;
- // unenlarge target node
- d3.select(this).attr('transform', '');
-
- // check for drag
- mouseup_node = d;
- var mySvg = this.parentElement.parentElement.parentElement;
- // if we dragged the node, make it fixed
- var cur_mouse = d3.mouse(mySvg);
- if (cur_mouse[0] != initial_mouse_down_position[0] ||
- cur_mouse[1] != initial_mouse_down_position[1]) {
- console.log("mouse pos changed. making this node fixed")
- d3.select(this).classed("fixed", d.fixed = true);
- resetMouseVars();
- return;
- }
-
- // we didn't drag, we just clicked on the node
- if ($scope.addingNode.step > 0) {
- if (d.nodeType !== 'inter-router')
- return;
- if (QDRService.nameFromId(d.key) == '__internal__')
- return;
-
- // add a link from the clicked node to the new node
- getLink(d.id, nodes.length-1, "in", "temp");
- $scope.addingNode.hasLink = true;
- if (!$scope.$$phase) $scope.$apply()
- // add new elements to the svg
- force.links(links).start();
- restart();
- return;
- }
-
- // if this node was selected, unselect it
- if (mousedown_node === selected_node) {
- selected_node = null;
- }
- else {
- if (d.nodeType !== 'normal' && d.nodeType !== 'on-demand')
- selected_node = mousedown_node;
- }
- for (var i=0; i<links.length; ++i) {
- links[i]['highlighted'] = false;
- }
- mousedown_node = null;
- if (!$scope.$$phase) $scope.$apply()
- restart(false);
- })
- .on("dblclick", function (d) { // dblclick a circle
- if (d.fixed) {
- d3.select(this).classed("fixed", d.fixed = false);
- force.start(); // let the nodes move to a new position
- }
- if (QDRService.nameFromId(d.key) == '__internal__') {
- editNode();
- if (!$scope.$$phase) $scope.$apply()
- }
- })
- .on("contextmenu", function(d) { // rightclick a circle
- $(document).click();
- d3.event.preventDefault();
- $scope.contextNode = d;
- if (!$scope.$$phase) $scope.$apply() // we just changed a scope valiable during an async event
- var bounds = $(QDR.offsetParent).offset()
- d3.select('#node_context_menu')
- .style('left', (mouseX - bounds.left + $(document).scrollLeft()) + "px")
- .style('top', (mouseY - bounds.top + $(document).scrollTop()) + "px")
- .style('display', 'block');
- })
- .on("click", function (d) { // leftclick a circle
- var clickPos = d3.mouse(this);
- clearPopups();
- if (!d.normals) {
- // circle was a router or a broker
- if ( QDRService.isArtemis(d) && Core.ConnectionName === 'Artemis' ) {
- $location.path('/jmx/attributes?tab=artemis&con=Artemis')
- }
- return;
- }
- // circle was a client or console
- d3.event.stopPropagation();
- startUpdateConnectionsGrid(d, clickPos);
- })
-
- var appendContent = function (g) {
- // show node IDs
- g.append('svg:text')
- .attr('x', 0)
- .attr('y', function (d) {
- var y = 6;
- if (QDRService.isArtemis(d))
- y = 8;
- else if (QDRService.isQpid(d))
- y = 9;
- else if (d.nodeType === 'inter-router')
- y = 4;
- return y;})
- .attr('class', 'id')
- .classed('console', function(d) { return QDRService.isConsole(d) } )
- .classed('normal', function(d) { return d.nodeType === 'normal' } )
- .classed('on-demand', function(d) { return d.nodeType === 'on-demand' } )
- .classed('artemis', function(d) { return QDRService.isArtemis(d) } )
- .classed('qpid-cpp', function(d) { return QDRService.isQpid(d) } )
- .text(function (d) {
- if (QDRService.isConsole(d)) {
- return '\uf108'; // icon-desktop for this console
- }
- if (QDRService.isArtemis(d)) {
- return '\ue900'
- }
- if (QDRService.isQpid(d)) {
- return '\ue901';
- }
- if (d.nodeType === 'normal')
- return '\uf109'; // icon-laptop for clients
- return d.name.length>7 ? d.name.substr(0,6)+'...' : d.name;
- });
- }
- appendContent(g)
-
- var appendTitle = function (g) {
- g.append("svg:title").text(function (d) {
- var x = '';
- if (d.normals && d.normals.length > 1)
- x = " x " + d.normals.length;
- if (QDRService.isConsole(d)) {
- return 'Dispatch console' + x
- }
- if (d.properties.product == 'qpid-cpp') {
- return 'Broker - qpid-cpp' + x
- }
- if ( QDRService.isArtemis(d) ) {
- return 'Broker - Artemis' + x
- }
- return d.nodeType == 'normal' ? 'client' + x : (d.nodeType == 'on-demand' ? 'broker' : 'Router ' + d.name)
- })
- }
- appendTitle(g);
-
- // remove old nodes
- circle.exit().remove();
-
- // add subcircles
- svg.selectAll('.subcircle').remove();
- var multiples = svg.selectAll('.multiple')
- multiples.each( function (d) {
- d.normals.forEach( function (n, i) {
- if (i<d.normals.length-1 && i<3) // only show a few shadow circles
- this.insert('svg:circle', ":first-child")
- .attr('class', 'subcircle node')
- .attr('r', 15 - i)
- .attr('transform', "translate("+ 4 * (i+1) +", 0)")
- }, d3.select(this))
- })
-
- // dynamically create the legend based on which node types are present
- var legendNodes = [];
- legendNodes.push(aNode("Router", "", "inter-router", undefined, 0, 0, 0, 0, false, {}))
-
- if (!svg.selectAll('circle.console').empty()) {
- legendNodes.push(aNode("Dispatch console", "", "normal", undefined, 1, 0, 0, 0, false, {console_identifier: 'Dispatch console'}))
- }
- if (!svg.selectAll('circle.client').empty()) {
- legendNodes.push(aNode("Client", "", "normal", undefined, 2, 0, 0, 0, false, {}))
- }
- if (!svg.selectAll('circle.qpid-cpp').empty()) {
- legendNodes.push(aNode("Qpid cpp broker", "", "on-demand", undefined, 3, 0, 0, 0, false, {product: 'qpid-cpp'}))
- }
- if (!svg.selectAll('circle.artemis').empty()) {
- legendNodes.push(aNode("Artemis broker", "", "on-demand", undefined, 4, 0, 0, 0, false, {}))
- }
- lsvg = lsvg.data(legendNodes, function (d) {
- return d.id;
- });
- var lg = lsvg.enter().append('svg:g')
- .attr('transform', function (d, i) {
- // 45px between lines and add 10px space after 1st line
- return "translate(0, "+(45*i+(i>0?10:0))+")"
- })
-
- appendCircle(lg)
- appendContent(lg)
- appendTitle(lg)
- lg.append('svg:text')
- .attr('x', 35)
- .attr('y', 6)
- .attr('class', "label")
- .text(function (d) {return d.key })
- lsvg.exit().remove();
- var svgEl = document.getElementById('svglegend')
- if (svgEl) {
- var bb;
- // firefox can throw an exception on getBBox on an svg element
- try {
- bb = svgEl.getBBox();
- } catch (e) {
- bb = {y: 0, height: 200, x: 0, width: 200}
- }
- svgEl.style.height = (bb.y + bb.height) + 'px';
- svgEl.style.width = (bb.x + bb.width) + 'px';
- }
-
- if (!mousedown_node || !selected_node)
- return;
-
- if (!start)
- return;
- // set the graph in motion
- //QDR.log.debug("mousedown_node is " + mousedown_node);
- force.start();
- }
-
- // show the links popup and update it periodically
- var startUpdateConnectionsGrid = function (d, clickPos) {
- // called every update tick
- var extendConnections = function () {
- $scope.multiData = []
- var normals = d.normals;
- // find updated normals for d
- d3.selectAll('.normal')
- .each(function(newd) {
- if (newd.id == d.id && newd.name == d.name) {
- normals = newd.normals;
- }
- });
- if (normals) {
- normals.forEach( function (n) {
- var nodeInfo = QDRService.topology.nodeInfo();
- var links = nodeInfo[n.key]['.router.link'];
- var linkTypeIndex = links.attributeNames.indexOf('linkType');
- var connectionIdIndex = links.attributeNames.indexOf('connectionId');
- n.linkData = [];
- links.results.forEach( function (linkArray) {
- var link = QDRService.flatten(links.attributeNames, linkArray)
- if (link.linkType === 'endpoint' && link.connectionId === n.connectionId) {
- var l = {};
- l.owningAddr = link.owningAddr;
- l.dir = link.linkDir;
- if (l.owningAddr && l.owningAddr.length > 2)
- if (l.owningAddr[0] === 'M')
- l.owningAddr = l.owningAddr.substr(2)
- else
- l.owningAddr = l.owningAddr.substr(1)
-
- l.deliveryCount = QDRService.pretty(link.deliveryCount);
- l.uncounts = QDRService.pretty(link.undeliveredCount + link.unsettledCount)
- l.adminStatus = link.adminStatus;
- l.operStatus = link.operStatus;
- l.identity = link.identity
- l.connectionId = link.connectionId
- l.nodeId = n.key
- l.type = link.type
- l.name = link.name
-
- //QDR.log.debug("pushing link state for " + l.owningAddr + " status: "+ l.adminStatus)
- n.linkData.push(l)
- }
- })
- $scope.multiData.push(n)
- if (n.connectionId == $scope.connectionId)
- $scope.linkData = n.linkData;
- })
- }
- $scope.$apply();
-
- d3.select('#multiple_details')
- .style({
- height: ((normals.length + 1) * 30) + 40 + "px",
- 'overflow-y': normals.length > 10 ? 'scroll' : 'hidden'
- })
-
- }
-
- // call extendConnections whenever the background data is updated
- QDRService.addUpdatedAction("normalsStats", extendConnections)
- extendConnections();
- clearPopups();
- var visibility = 'visible'
- var left = mouseX + $(document).scrollLeft()
- var bounds = $("#topology").position()
- if (d.normals.length === 1) {
- visibility = 'hidden'
- left = left - 30;
- mouseY = mouseY - 20
- }
- d3.select('#multiple_details')
- .style({
- visibility: visibility,
- opacity: 1,
- left: (clickPos[0] + bounds.left) + "px",
- top: (clickPos[1] + bounds.top) + "px"})
- if (d.normals.length === 1) {
- // simulate a click on the connection to popup the link details
- $scope.multiDetails.showLinksList( {entity: d} )
- }
- }
-
- var stopUpdateConnectionsGrid = function () {
- QDRService.delUpdatedAction("normalsStats");
- }
-
- function nextHop(thisNode, d) {
- if ((thisNode) && (thisNode != d)) {
- var target = findNextHopNode(thisNode, d);
- //QDR.log.debug("highlight link from node ");
- //console.dump(nodeFor(selected_node.name));
- //console.dump(target);
- if (target) {
- var hlLink = linkFor(nodeFor(thisNode.name), target);
- //QDR.log.debug("need to highlight");
- //console.dump(hlLink);
- if (hlLink)
- hlLink['highlighted'] = true;
- else
- target = null;
- }
- setTimeout(nextHop, 1, target, d);
- }
- restart();
- }
-
-
- function mousedown() {
- // prevent I-bar on drag
- //d3.event.preventDefault();
-
- // because :active only works in WebKit?
- svg.classed('active', true);
- }
-
- QDRService.addUpdatedAction("topology", function() {
- //QDR.log.debug("Topology controller was notified that the model was updated");
- if (hasChanged()) {
- QDR.log.info("svg graph changed")
- saveChanged();
- // TODO: update graph nodes instead of rebuilding entire graph
- d3.select("#SVG_ID").remove();
- d3.select("#svg_legend svg").remove();
- animate = true;
- initForceGraph();
- //if ($location.path().startsWith("/topology"))
- // Core.notification('info', "Qpid dispatch router topology changed");
-
- } else {
- //QDR.log.debug("no changes")
- }
- });
-
- function hasChanged () {
- // Don't update the underlying topology diagram if we are adding a new node.
- // Once adding is completed, the topology will update automatically if it has changed
- if ($scope.addingNode.step > 0)
- return false;
- var nodeInfo = QDRService.topology.nodeInfo();
- if (Object.keys(nodeInfo).length != Object.keys(savedKeys).length)
- return true;
- for (var key in nodeInfo) {
- // if this node isn't in the saved node list
- if (!savedKeys.hasOwnProperty(key))
- return true;
- // if the number of connections for this node chaanged
- if (nodeInfo[key]['.connection'].results.length != savedKeys[key]) {
- /*
- QDR.log.debug("number of connections changed for " + key);
- QDR.log.debug("QDRService.topology._nodeInfo[key]['.connection'].results.length");
- console.dump(QDRService.topology._nodeInfo[key]['.connection'].results.length);
- QDR.log.debug("savedKeys[key]");
- console.dump(savedKeys[key]);
- */
- return true;
- }
- }
- return false;
- };
- function saveChanged () {
- savedKeys = {};
- var nodeInfo = QDRService.topology.nodeInfo();
- // save the number of connections per node
- for (var key in nodeInfo) {
- savedKeys[key] = nodeInfo[key]['.connection'].results.length;
- }
- //QDR.log.debug("saving current keys");
- //console.dump(savedKeys);
- };
- // we are about to leave the page, save the node positions
- $rootScope.$on('$locationChangeStart', function(event, newUrl, oldUrl) {
- //QDR.log.debug("locationChangeStart");
- nodes.forEach( function (d) {
- localStorage[d.name] = angular.toJson({x: d.x, y: d.y, fixed: d.fixed});
- });
- $scope.addingNode.step = 0;
-
- });
- // When the DOM element is removed from the page,
- // AngularJS will trigger the $destroy event on
- // the scope
- $scope.$on("$destroy", function( event ) {
- //QDR.log.debug("scope on destroy");
- QDRService.stopUpdating();
- QDRService.delUpdatedAction("topology");
- d3.select("#SVG_ID").remove();
- window.removeEventListener('resize', resize);
- });
-
- initForceGraph();
- saveChanged();
- QDRService.startUpdating();
-
- function doAddDialog(NewRouterName) {
- var d = $modal.dialog({
- dialogClass: "modal dlg-large",
- backdrop: true,
- keyboard: true,
- backdropClick: true,
- controller: 'QDR.NodeDialogController',
- templateUrl: 'node-config-template.html',
- resolve: {
- newname: function () {
- return NewRouterName;
- }
- }
- });
- d.open().then(function (result) {
- if (result)
- doDownloadDialog(result);
- });
- };
-
- function doDownloadDialog(result) {
- d = modal.dialog({
- backdrop: true,
- keyboard: true,
- backdropClick: true,
- controller: 'QDR.DownloadDialogController',
- templateUrl: 'download-dialog-template.html',
- resolve: {
- results: function () {
- return result;
- }
- }
- });
- d.open().then(function (result) {
- //QDR.log.debug("download dialog done")
- })
- if (!$scope.$$phase) $scope.$apply()
- };
- };
-
- return QDR;
-}(QDR || {}));
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/a5e2307f/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.download-controller.js
----------------------------------------------------------------------
diff --git a/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.download-controller.js b/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.download-controller.js
deleted file mode 100644
index 2eb812f..0000000
--- a/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.download-controller.js
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function (QDR) {
- 'use strict';
-
- angular
- .module('horizon.dashboard.dispatch.topology')
- .controller('horizon.dashboard.dispatch.topology.TopologyDownloadController', TopologyDownloadController);
-
- TopologyDownloadController.$inject = [
- '$scope',
- 'horizon.dashboard.dispatch.comService'
- ]
-
- function TopologyDownloadController($scope, QDRService, dialog, results) {
- var result = results.entities;
- var annotations = results.annotations;
- var annotationKeys = Object.keys(annotations);
- var annotationSections = {};
-
- // use the router's name as the file name if present
- $scope.newRouterName = 'router';
- result.forEach( function (e) {
- if (e.actualName == 'router') {
- e.attributes.forEach( function (a) {
- if (a.name == 'name') {
- $scope.newRouterName = a.value;
- }
- })
- }
- })
- $scope.newRouterName = $scope.newRouterName + ".conf";
-
- var template = $templateCache.get('config-file-header.html');
- $scope.verbose = true;
- $scope.$watch('verbose', function (newVal) {
- if (newVal !== undefined) {
- // recreate output using current verbose setting
- getOutput();
- }
- })
-
- var getOutput = function () {
- $scope.output = template + '\n';
- $scope.parts = [];
- var commentChar = '#'
- result.forEach(function (entity) {
- // don't output a section for annotations, they get flattened into the entities
- var section = "";
- if (entity.icon) {
- section += "##\n## Add to " + entity.link.__data__.source.name + "'s configuration file\n##\n";
- }
- section += "##\n## " + QDRService.humanify(entity.actualName) + " - " + entity.description + "\n##\n";
- section += entity.actualName + " {\n";
- entity.attributes.forEach(function (attribute) {
- if (attribute.input == 'select')
- attribute.value = attribute.selected;
-
- // treat values with all spaces and empty strings as undefined
- attribute.value = String(attribute.value).trim();
- if (attribute.value === 'undefined' || attribute.value === '')
- attribute.value = undefined;
-
- if ($scope.verbose) {
- commentChar = attribute.required || attribute.value != attribute['default'] ? ' ' : '#';
- if (!attribute.value) {
- commentChar = '#';
- attribute.value = '';
- }
- section += commentChar + " "
- + attribute.name + ":" + Array(Math.max(20 - attribute.name.length, 1)).join(" ")
- + attribute.value
- + Array(Math.max(20 - ((attribute.value)+"").length, 1)).join(" ")
- + '# ' + attribute.description
- + "\n";
- } else {
- if (attribute.value) {
- if (attribute.value != attribute['default'] || attribute.required)
- section += " "
- + attribute.name + ":" + Array(20 - attribute.name.length).join(" ")
- + attribute.value + "\n";
-
- }
- }
- })
- section += "}\n\n";
- // if entity.icon is true, this is a connector intended for another router
- if (entity.icon)
- $scope.parts.push({output: section,
- link: entity.link,
- name: entity.link.__data__.source.name,
- references: entity.references});
- else
- $scope.output += section;
-
- // if this section is actually an annotation
- if (annotationKeys.indexOf(entity.actualName) > -1) {
- annotationSections[entity.actualName] = section;
- }
- })
- // go back and add annotation sections to the parts
- $scope.parts.forEach (function (part) {
- for (var section in annotationSections) {
- if (part.references.indexOf(section) > -1) {
- part.output += annotationSections[section];
- }
- }
- })
- QDR.log.debug($scope.output);
- }
-
- // handle the download button click
- $scope.download = function () {
- var output = $scope.output + "\n\n"
- var blob = new Blob([output], { type: 'text/plain;charset=utf-16' });
- saveAs(blob, $scope.newRouterName);
- }
-
- $scope.downloadPart = function (part) {
- var linkName = part.link.__data__.source.name + 'additional.conf';
- var blob = new Blob([part.output], { type: 'text/plain;charset=utf-16' });
- saveAs(blob, linkName);
- }
-
- $scope.done = function () {
- dialog.close();
- }
- };
-
- return QDR;
-}(QDR || {}));
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/a5e2307f/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.form-controller.js
----------------------------------------------------------------------
diff --git a/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.form-controller.js b/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.form-controller.js
deleted file mode 100644
index 19af366..0000000
--- a/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.form-controller.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function (QDR) {
- 'use strict';
-
- angular
- .module('horizon.dashboard.dispatch.topology')
- .controller('horizon.dashboard.dispatch.topology.TopologyFormController', TopologyFormController);
-
- TopologyFormController.$inject = [
- '$scope',
- 'horizon.dashboard.dispatch.comService'
- ];
-
- function TopologyFormController($scope, QDRService) {
- var fctrl = this;
- $scope.attributes = []
- var nameTemplate = '<div title="{{row.entity.description}}" class="ngCellText"><span>{{row.entity.attributeName}}</span></div>';
- var valueTemplate = '<div title="{{row.entity.attributeValue}}" class="ngCellText"><span>{{row.entity.attributeValue}}</span></div>';
- $scope.topoGridOptions = {
- data: 'attributes',
- enableColumnResize: true,
- multiSelect: false,
- columnDefs: [
- {
- field: 'attributeName',
-// cellTemplate: nameTemplate,
- displayName: 'Attribute'
- },
- {
- field: 'attributeValue',
-// cellTemplate: valueTemplate,
- displayName: 'Value'
- }
- ]
- };
- $scope.form = ''
- $scope.$on('showEntityForm', function (event, args) {
- var attributes = args.attributes;
- var entityTypes = QDRService.schema.entityTypes[args.entity].attributes;
- attributes.forEach( function (attr) {
- if (entityTypes[attr.attributeName] && entityTypes[attr.attributeName].description)
- attr.description = entityTypes[attr.attributeName].description
- })
- $scope.attributes = attributes;
- $scope.form = args.entity;
- })
- $scope.$on('showAddForm', function (event) {
- $scope.form = 'add';
- })
- }
-
- return QDR;
-}(QDR || {}));
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/a5e2307f/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.module.js
----------------------------------------------------------------------
diff --git a/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.module.js b/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.module.js
deleted file mode 100644
index e5a5242..0000000
--- a/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/topology/topology.module.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed 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.
- */
-(function () {
- 'use strict';
-
- angular
- .module('horizon.dashboard.dispatch.topology', [])
- .config(config)
- .run(addTemplates)
-
- config.$inject = [
- '$provide',
- '$windowProvider'
- ];
-
- addTemplates.$inject = [
- '$templateCache',
- ];
-
- /**
- * @name config
- * @param {Object} $provide
- * @param {Object} $windowProvider
- * @description Base path for the overview code
- * @returns {undefined} No return value
- */
- function config($provide, $windowProvider) {
- var path = $windowProvider.$get().STATIC_URL + 'dashboard/dispatch/topology/';
- $provide.constant('horizon.dashboard.dispatch.topology.basePath', path);
- }
-
- function addTemplates($templateCache) {
- $templateCache.put("dispatch/topology.html",
- "<div class=\"qdrTopology\" ng-controller=\"horizon.dashboard.dispatch.topology.TopologyController as ctrl\">" +
- " <div>" +
- "<!--" +
- " <ul class=\"nav nav-tabs ng-scope qdrTopoModes\">" +
- " <li ng-repeat=\"mode in modes\" ng-class=\"{active : isModeActive(mode.name), 'pull-right' : isRight(mode)}\" ng-click=\"selectMode('{{mode.name}}')\" >" +
- " <a data-placement=\"bottom\" class=\"ng-binding\"> {{mode.name}} </a></li>" +
- " </ul>" +
- "-->" +
- " <div id=\"topology\" ng-show=\"mode == 'Diagram'\"><!-- d3 toplogy here --></div>" +
- " <div id=\"geology\" ng-show=\"mode == 'Globe'\"><!-- d3 globe here --></div>" +
- " <div id=\"crosssection\"><!-- d3 pack here --></div>" +
- " <!-- <div id=\"addRouter\" ng-show=\"mode == 'Add Node'\"></div> -->" +
- " <div id=\"node_context_menu\" class=\"contextMenu\">" +
- " <ul>" +
- " <li class=\"na\" ng-class=\"{new: contextNode.cls == 'temp'}\" ng-click=\"addingNode.trigger = 'editNode'\">Edit...</li>" +
- " <li class=\"na\" ng-class=\"{adding: addingNode.step > 0}\" ng-click=\"addingNode.step = 0\">Cancel add</li>" +
- " <li class=\"context-separator\"></li>" +
- " <li class=\"na\" ng-class=\"{'force-display': !isFixed()}\" ng-click=\"setFixed(true)\">Freeze in place</li>" +
- " <li class=\"na\" ng-class=\"{'force-display': isFixed()}\" ng-click=\"setFixed(false)\">Unfreeze</li>" +
- " </ul>" +
- " </div>" +
- " <div id=\"svg_context_menu\" class=\"contextMenu\">" +
- " <ul>" +
- " <li ng-click=\"addingNode.step = 2\">Add a new router</li>" +
- " </ul>" +
- " </div>" +
- " <div id=\"link_context_menu\" class=\"contextMenu\">" +
- " <ul>" +
- " <li ng-click=\"reverseLink()\">Reverse connection direction</li>" +
- " <li ng-click=\"removeLink()\">Remove connection</li>" +
- " </ul>" +
- " </div>" +
- " <div id=\"svg_legend\"></div>" +
- " <div id=\"multiple_details\">" +
- " <h4 class=\"grid-title\">Connections</h4>" +
- " <div class=\"grid\" ui-grid=\"multiDetails\" ui-grid-selection></div>" +
- " </div>" +
- " <div id=\"link_details\">" +
- " <h4 class=\"grid-title\">Links</h4>" +
- " <div class=\"grid\" ui-grid=\"linkDetails\" ui-grid-selection></div>" +
- " </div>" +
- " </div>" +
- " <div ng-controller=\"horizon.dashboard.dispatch.topology.TopologyFormController as fctrl\">" +
- " <div id=\"topologyForm\" ng-class=\"{selected : isSelected()}\">" +
- " <!-- <div ng-repeat=\"form in forms\" ng-show=\"isVisible(form)\" ng-class='{selected : isSelected(form)}'> -->" +
- " <div ng-if=\"form == 'router'\">" +
- " <h3>Router Info</h3>" +
- " <div class=\"grid\" ui-grid=\"topoGridOptions\"></div>" +
- " </div>" +
- " <div ng-if=\"form == 'connection'\">" +
- " <h3>Connection Info</h3>" +
- " <div class=\"grid\" ui-grid=\"topoGridOptions\"></div>" +
- " </div>" +
- " <div id=\"addNodeForm\" ng-show=\"form == 'add'\">" +
- " <h3>Add a new router</h3>" +
- " <ul>" +
- " <li>Click on an existing router to create a connection to the new router</li>" +
- " <li>Double-click on the new router to <button ng-click=\"editNewRouter()\">edit</button> its properties</li>" +
- " <li ng-show=\"addingNode.hasLink\" >Right-click on a new connection to edit its properties</li>" +
- " </ul>" +
- " <button ng-click=\"cancel()\">Cancel</button>" +
- " </div>" +
- " </div>" +
- " </div>" +
- "</div>"
- );
- }
-})();
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org