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 2017/11/29 19:58:29 UTC
[1/4] qpid-dispatch git commit: DISPATCH-886 Use pre-npm css files
Repository: qpid-dispatch
Updated Branches:
refs/heads/master 58ecc97bc -> 55d7bd34b
DISPATCH-886 Use pre-npm css files
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/79ae73f9
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/79ae73f9
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/79ae73f9
Branch: refs/heads/master
Commit: 79ae73f9dd768005f6f8f7d4ecadc4000a97f0ae
Parents: 58ecc97
Author: Ernest Allen <ea...@redhat.com>
Authored: Wed Nov 29 14:54:42 2017 -0500
Committer: Ernest Allen <ea...@redhat.com>
Committed: Wed Nov 29 14:54:42 2017 -0500
----------------------------------------------------------------------
.../src/main/webapp/plugin/css/dispatch.css | 727 +++++++++++++-
.../src/main/webapp/plugin/css/plugin.css | 995 ++++++++++++++++++-
2 files changed, 1720 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/79ae73f9/console/hawtio/src/main/webapp/plugin/css/dispatch.css
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/css/dispatch.css b/console/hawtio/src/main/webapp/plugin/css/dispatch.css
deleted file mode 120000
index f3dbfa0..0000000
--- a/console/hawtio/src/main/webapp/plugin/css/dispatch.css
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/css/dispatch.css
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/css/dispatch.css b/console/hawtio/src/main/webapp/plugin/css/dispatch.css
new file mode 100644
index 0000000..5c946bd
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/css/dispatch.css
@@ -0,0 +1,726 @@
+/*
+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.
+*/
+
+svg {
+ background-color: transparent;
+ cursor: default;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -o-user-select: none;
+ user-select: none;
+}
+
+svg:not(.active):not(.ctrl) {
+ cursor: crosshair;
+}
+#end-arrow-selected, #start-arrow-selected {
+ stroke: #33F;
+ fill: #33F;
+}
+path.link.selected {
+ stroke-dasharray: 10,2;
+ stroke: #33F !important;
+}
+
+path.link {
+ fill: #000;
+ stroke: #000;
+ stroke-width: 4px;
+ cursor: default;
+}
+
+svg:not(.active):not(.ctrl) path.link {
+ cursor: pointer;
+}
+
+path.link.small {
+ stroke-width: 2.5;
+ stroke: darkgray;
+}
+path.link.highlighted {
+ stroke: #6F6 !important;
+}
+marker#start-arrow-highlighted,
+marker#end-arrow-highlighted {
+ fill: #6F6;
+}
+marker#start-arrow-small,
+marker#end-arrow-small {
+ fill: darkgray;
+}
+
+path.link.dragline {
+ pointer-events: none;
+}
+
+path.link.hidden {
+ stroke-width: 0;
+}
+
+circle.node {
+ stroke-width: 1.5px;
+ cursor: pointer;
+ stroke: darkgray;
+}
+
+circle.node.reflexive {
+ stroke: #F00 !important;
+ stroke-width: 2.5px;
+}
+circle.node.selected {
+ stroke: #6F6 !important;
+ stroke-width: 2px;
+ fill: #e0e0ff !important;
+}
+circle.node.highlighted {
+ stroke: #6F6;
+}
+circle.node.inter-router {
+ fill: #EAEAEA;
+}
+circle.node.normal.in {
+ fill: #F0F000;
+}
+circle.node.normal.out {
+ fill: #C0F0C0;
+}
+circle.node.on-demand {
+ fill: #C0FFC0;
+}
+circle.node.on-demand.artemis {
+ fill: #FCC;
+ /*opacity: 0.2; */
+}
+
+circle.node.fixed {
+ stroke-dasharray: 10,2;
+}
+text {
+ font: 12px sans-serif;
+ pointer-events: none;
+ /*font-family: monospace;*/
+
+}
+
+.tooltipsy
+{
+ padding: 10px;
+/* max-width: 320px;*/
+ color: #303030;
+ background-color: #fcfcfe;
+ border: 1px solid #deca7e;
+ border-radius: 5px;
+}
+
+.tiptable {
+
+}
+.tiptable tr {
+ border-bottom: 1px solid #ccc;
+}
+
+.tiptable tr:last-child {
+ border-bottom: 0px;
+}
+
+.tiptable tr:nth-child(even) {
+ background: #fcfcfe;
+}
+.tiptable tr:nth-child(odd) {
+ background: #FFF
+}
+
+text.id {
+ text-anchor: middle;
+ font-weight: bold;
+}
+
+text.label {
+ text-anchor: start;
+ font-weight: bold;
+}
+
+.row-fluid.tertiary {
+ position: relative;
+ left: 20px;
+}
+
+.row-fluid.tertiary.left {
+ float: left;
+}
+
+.row-fluid.tertiary.panel {
+ width: 410px;
+ /*height: 100%; */
+}
+
+div#topologyForm .ngViewport, div#topologyForm .gridStyle {
+ height: auto !important;
+ min-height: initial !important;
+ overflow: initial;
+}
+
+div#multiple_details, div#link_details {
+ height: 300px;
+ width: 700px;
+ display: none;
+ padding: 0.5em;
+ border: 1px solid;
+ position: absolute;
+ background-color: white;
+ max-height: 330px !important;
+ overflow: hidden;
+}
+div#multiple_details div.ngRow.selected {
+ background-color: #c9dde1 !important;
+}
+
+div.grid-values {
+ text-align: right;
+}
+
+div.grid-values.ngCellText span {
+ padding-right: 4px;
+}
+
+.panel-adjacent {
+ margin-left: 430px;
+}
+
+#topologyForm.selected {
+ border: 1px solid blue;
+}
+#topologyForm {
+ border-right: 1px solid lightgray;
+ border-bottom: 1px solid lightgray;
+ /*border: 1px solid white;*/
+ padding: 2px;
+ /* position: relative; */
+ /* top: -8px; */
+}
+div.qdr-topology.pane.left .ngViewport {
+ /* border: 1px solid lightgray; */
+}
+
+#topologyForm > div {
+ width:396px;
+}
+
+/* globe */
+.land {
+ fill: #999;
+ stroke-opacity: 1;
+}
+
+.graticule {
+ fill: none;
+ stroke: black;
+ stroke-width:.5;
+ opacity:.1;
+}
+
+.labels {
+ font: 18px sans-serif;
+ fill: black;
+ opacity: .85;
+ text-anchor: middle;
+}
+
+.noclicks { pointer-events:none; }
+
+.point { opacity:.6; }
+
+.arcs {
+ opacity:.7;
+ stroke: darkgreen;
+ stroke-width: 3;
+}
+.flyers {
+ stroke-width:1;
+ opacity: 0;
+ stroke: darkred;
+}
+.arc, .flyer {
+ stroke-linejoin: round;
+ fill:none;
+}
+.arc { }
+.arc:hover {
+ stroke: darkred;
+}
+.flyer { }
+.flyer:hover {
+ stroke: darkgreen;
+}
+.arc.inter-router {
+ stroke: darkblue;
+}
+
+#addNodeForm {
+ padding: 1em;
+}
+
+
+li.currentStep {
+ font-weight: bold;
+}
+
+.qdrTopology div.panel {
+ position: absolute;
+}
+/*
+.ui-dialog-titlebar {
+ border: 0;
+ background: transparent;
+}
+*/
+
+/*
+.ui-tabs.ui-tabs-vertical {
+ padding: 0;
+ width: 48em;
+}
+.ui-tabs.ui-tabs-vertical .ui-widget-header {
+ border: none;
+}
+.ui-tabs.ui-tabs-vertical .ui-tabs-nav {
+ float: left;
+ width: 10em;
+ background: #CCC;
+ border-radius: 4px 0 0 4px;
+ border-right: 1px solid gray;
+}
+.ui-tabs.ui-tabs-vertical .ui-tabs-nav li {
+ clear: left;
+ width: 100%;
+ margin: 0.1em 0;
+ border: 1px solid gray;
+ border-width: 1px 0 1px 1px;
+ border-radius: 4px 0 0 4px;
+ overflow: hidden;
+ position: relative;
+ right: -2px;
+ z-index: 2;
+}
+.ui-tabs.ui-tabs-vertical .ui-tabs-nav li a {
+ display: block;
+ width: 100%;
+ padding: 0.1em 1em;
+}
+.ui-tabs.ui-tabs-vertical .ui-tabs-nav li a:hover {
+ cursor: pointer;
+}
+.ui-tabs.ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active {
+ margin-bottom: 0.2em;
+ padding-bottom: 0;
+ border-right: 1px solid white;
+}
+.ui-tabs.ui-tabs-vertical .ui-tabs-nav li:last-child {
+ margin-bottom: 10px;
+}
+.ui-tabs.ui-tabs-vertical .ui-tabs-panel {
+ float: left;
+ width: 34em;
+ border-left: 1px solid gray;
+ border-radius: 0;
+ position: relative;
+ left: -1px;
+}
+
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected {
+ right: -3px !important;
+}
+
+.ui-tabs li i.ui-icon {
+ display: inline-block;
+}
+*/
+.ui-tabs .ui-tabs-panel {
+ /* padding-top: 0 !important; */
+}
+
+.ui-widget-content fieldset {
+ float: left;
+ padding: 0 1em 0 0;
+}
+
+.entity-description {
+ color: #960;
+ font-size: 90%;
+}
+
+.attr-description {
+ padding-top: 1.5em;
+ float: right;
+ width: 17em;
+}
+.attr-annotations {
+ padding-top: 2.5em;
+ clear: both;
+}
+.attr-annotations > span {
+ padding-top: 0.5em;
+ border-top: 1px dashed darkgray;
+ display: block;
+}
+
+.attr-type {
+ color: #990;
+ font-size: 85%;
+}
+.attr-required {
+ color: red;
+ font-size: 85%;
+}
+.attr-unique {
+ color: green;
+ font-size: 85%;
+}
+
+#tabs.nodeEntities {
+ border: 0;
+}
+
+#tabs ul.nodeTabs {
+ background: #fff;
+}
+
+#tabs #Container {
+ border-left: 1px solid #aaa;
+}
+
+#tabs.ui-tabs .ui-tabs-nav li {
+ border-bottom: 1px solid #aaa !important;
+}
+
+.entity-fields {
+ /* height: 400px; */
+ overflow-y: scroll;
+ overflow-x: hidden;
+}
+
+div.boolean label:first-child {
+ float: left;
+ margin-right: 1em;
+}
+div.boolean {
+ padding-bottom: 1em;
+}
+
+.entity-fields label {
+ font-weight: 600;
+ margin-top: 0.5em;
+ display: inline;
+}
+
+.aggregate {
+ text-align: right;
+}
+
+.aggregate i {
+ float: right;
+ margin: 3px 3px 3px 8px;
+}
+
+.aggregate .hastip {
+ padding: 5px;
+}
+
+.subTip .tipsy-inner {
+ background-color: white;
+ color: black;
+ font-size: 1.3em;
+ border: 1px solid black;
+}
+
+.subTip .tipsy-arrow-n { border-bottom-color: black; }
+.subTip .tipsy-arrow-s { border-top-color: black; }
+.subTip .tipsy-arrow-e { border-left-color: black; }
+.subTip .tipsy-arrow-w { border-right-color: black; }
+
+
+.contextMenu {
+ display:none;
+ position:absolute;
+ left:30px;
+ top:-30px;
+ z-index:999;
+ /* width:300px; */
+}
+.contextMenu ul {
+ width:300px;
+ margin:0;
+ padding-left:0;
+ list-style:none;
+ background:#fff;
+ color:#333;
+ font-weight: 600;
+ /* -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px; */
+ -moz-box-shadow:5px 5px 5px #ddd; -webkit-box-shadow:5px 5px 5px #999; box-shadow:5px 5px 5px #ddd;
+ border: 1px solid #aaa;
+}
+.contextMenu ul li {
+ padding:5px 10px;
+ /* border-bottom: solid 1px #ccc; */
+}
+.contextMenu ul li:hover {
+ background:#4a90d9; color:#fff;
+}
+.contextMenu ul li:last-child {
+ border:none;
+}
+
+.na {
+ display: none;
+}
+.contextMenu ul li.new {
+ display: block;
+}
+.contextMenu ul li.adding, .contextMenu ul li.adding + li {
+ display: block;
+}
+.contextMenu ul li.force-display {
+ display: block;
+}
+.contextMenu ul li.context-separator {
+ background-color: lightgray;
+ height: 1px;
+ padding: 0;
+}
+
+.ui-tabs.ui-tabs-vertical .ui-tabs-nav li.separated {
+ margin-top: 1em;
+}
+
+#crosssection {
+ display: none;
+ position: absolute;
+ top: 200px;
+ left: 600px;
+}
+
+.node circle {
+/* fill: rgb(31, 119, 180);
+ fill-opacity: .25; */
+ fill: #cfe2f3;
+ fill-opacity: .98;
+ stroke: black;
+ stroke-width: 3px;
+}
+
+circle.subcircle {
+ stroke-width: 1px;
+ /* stroke-dasharray: 2; */
+ fill-opacity: 0;
+ stroke: darkgray;
+}
+
+.leaf circle {
+ fill: #6fa8dc;
+ fill-opacity: 0.95;
+ stroke-width: 3px;
+}
+
+.leaf circle[title] {
+ font-family: monospace;
+
+}
+
+#svg_legend {
+ position: absolute;
+ top: 110px;
+ right: 0;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ background-color: #fcfcfc;
+ margin-right: 1.3em;
+ padding: 1em;
+}
+
+#svg_legend svg {
+ height: 235px;
+ width: 180px;
+}
+
+#multiple_details div.gridStyle {
+/* height: 50em; */
+ min-height: 70px !important;
+ height: auto !important;
+}
+
+#multiple_details .ngViewport {
+ height: auto !important;
+}
+
+#multiple_details .gridCellButton button, #link_details .gridCellButton button {
+ margin: .25em .4em;
+ font-size: 12px;
+ height: 2em;
+ padding-top: .1em;
+}
+
+#linkFilter {
+ display: none;
+ padding: 0.5em;
+ border: 1px solid grey;
+ background-color: #F0F0F0;
+ position: absolute;
+ z-index: 100;
+ right: 1em;
+}
+div.formLine label, div.formLine input {
+ display: inline-block;
+ padding: 0 8px;
+}
+
+span.filter-icon {
+ padding-left: 1em;
+}
+
+button.filter-close {
+ width: 15px;
+ height: 20px;
+ padding: 0;
+ position: absolute;
+ right: 4px;
+ top: 4px;
+}
+
+div.filter-title h6 {
+ margin: 0 0 0.5em 0;
+}
+
+.links button.btn-filter {
+ padding: 0 1em 0 0;
+ margin-left: 1em;
+ font-size: 1em;
+}
+
+button.btn-filter {
+ float: right;
+}
+span.dynatree-expanded button.btn-filter,
+a.dynatree-title:hover button.btn-filter {
+ visibility: visible;
+}
+
+div.hdash-button a {
+ color: white;
+}
+
+.linkDirIn {
+ color: red;
+ background-color: #f3f3f3;
+}
+
+.linkDirOut {
+ color: blue;
+ background-color: white;
+}
+
+div.topoGrid .ui-grid-viewport {
+ overflow: hidden !important;
+}
+
+@-moz-document url-prefix() {
+ .btn {padding: 2px 12px 8px !important;}
+ #overview-controller .btn {padding: 4px 12px !important;}
+ #overview-controller .btn.filter-close {padding: 0 !important;}
+}
+
+.ui-fancytree.fancytree-container {
+ font-size: 14px;
+}
+
+.grid-title {
+ background-color: #FAFAFA;
+ background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));
+ background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2);
+ background-image: -o-linear-gradient(top, #ffffff, #f2f2f2);
+ background-image: linear-gradient(to bottom, #ffffff, #f2f2f2);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#F2F2F2', GradientType=0);
+ border-bottom: 1px solid #d4d4d4;
+ text-shadow: 0 1px 0 #FFFFFF;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+ margin: 0 0 10px 0;
+ padding-bottom: 4px;
+}
+
+.expand-collapse {
+ float: right;
+ margin-right: 0.5em;
+}
+
+.pane-viewport {
+ top: 24px !important;
+}
+.dynatree-node.loading {
+ position: initial;
+}
+
+.hideLeft {
+ position: absolute;
+ right: 0.5em;
+ top: 1em;
+ border: 0;
+}
+
+.showLeft {
+ position: absolute;
+ top: 1em;
+ left: 0.5em;
+ border: 0;
+}
+
+.newChart {
+ float: right;
+}
+
+select.unique, input.unique {
+ border: 2px solid blue;
+}
+select.required, input.required {
+ border: 2px solid black;
+}
+
+.required-indicator {
+ padding-left: 0.5em;
+ font-size: 0.85em;
+ vertical-align: super;
+}
+
+.required-indicator::before {
+ content: '(required)'
+}
+
+.unique-indicator {
+ padding-left: 0.5em;
+ font-size: 0.85em;
+ vertical-align: super;
+}
+
+.unique-indicator::before {
+ content: '(must be unique if supplied)'
+}
+
+.unique-indicator
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/79ae73f9/console/hawtio/src/main/webapp/plugin/css/plugin.css
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/css/plugin.css b/console/hawtio/src/main/webapp/plugin/css/plugin.css
deleted file mode 120000
index b94a926..0000000
--- a/console/hawtio/src/main/webapp/plugin/css/plugin.css
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/css/plugin.css
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/css/plugin.css b/console/hawtio/src/main/webapp/plugin/css/plugin.css
new file mode 100644
index 0000000..20fd0fb
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/css/plugin.css
@@ -0,0 +1,994 @@
+/*
+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.
+*/
+main-display > .span8 {
+ height: 100%;
+ position: relative;
+}
+
+ul.qdrListNodes > li > span {
+ padding: 6px 20px; 6px; 6px;
+ display: block;
+}
+
+.qdrList .gridStyle {
+ width: 20em;
+ margin-right: 0;
+ float: left;
+}
+
+
+.qdrList div.gridDetails {
+ width: auto;
+}
+
+div.gridDetails {
+ margin-left: 1em;
+}
+
+.selectedItems {
+ /* margin-left: 21em; */
+}
+
+.qdrListPane {
+ top: 110px;
+}
+
+.qdrListActions {
+ width: auto;
+ margin-left: 1em;
+}
+
+div.listAttrName {
+ padding-top: 5px;
+}
+
+div.listAttrName i.icon-bar-chart {
+ float: right;
+ margin: 3px 5px;
+}
+
+div.listAttrName i.icon-bar-chart.active, div.hastip i.icon-bar-chart.active, li.haschart i {
+ background-color: #AAFFAA;
+}
+
+div#main div ul.nav li a:not(.btn) {
+ background: initial !important;
+}
+
+div#main div ul.nav li.active a {
+ background-color: #f0f0ff !important;
+}
+
+div#main.qdr {
+ margin-top: 56px !important;
+}
+
+div.charts-header {
+ font-size: 1.2em;
+ color: #666666;
+ margin: 1em 0;
+}
+
+.selectedNode, .selectedAction, .selectedEntity {
+ font-weight: 600;
+ color: #606066;
+}
+
+.okButton {
+ text-align: center;
+ margin: 1em;
+}
+
+span.showChartsLink {
+ border: 1px solid blue;
+ padding: 1px 2px;
+}
+
+div.listGraphs p {
+ margin: 1em 0 2em 2em;
+ text-align: center;
+}
+
+div.centered {
+ text-align: center;
+ margin: 4em;
+}
+
+.modal-body.centered {
+ margin: 0;
+}
+
+/* dialog */
+div.aChart {
+ height: 200px;
+ width: 400px;
+ margin: 1em;
+}
+
+/* dashboard */
+div.aChart.hDash {
+ /* width: 21em; */
+ /* height: 17em; */
+ width: 100%;
+ height: 87%;
+ margin: 0;
+ padding: 0;
+
+}
+div.chartContainer {
+ float: left;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+}
+
+/* the x and y axis lines */
+.d3Chart g.axis path.domain {
+ stroke-width: 1;
+ stroke: black;
+}
+
+/* the line surrounding the area chart */
+div.d3Chart path {
+/* stroke: black; */
+ stroke-width: 0;
+/* opacity: 0.5; */
+}
+
+/* the line above the area chart */
+/* the color gets overridden */
+div.d3Chart path.line {
+ stroke: steelblue;
+ stroke-width: 1.5;
+ fill: none;
+ opacity: 1;
+}
+
+.mo-rect {
+ fill: #ffffdd;
+ stroke: #f0f0f0;
+ stroke-width: 1;
+}
+
+.mo-guide {
+ fill: none;
+ stroke: #d0d0d0;
+ stroke-width: 2;
+ stroke-dasharray: 3,3;
+}
+
+div.d3Chart .title {
+ text-decoration: underline;
+}
+
+
+.axis line, .axis path {
+ fill: none;
+ shape-rendering: crispEdges;
+ stroke-width: 1;
+ stroke: #000000;
+}
+
+.axis line {
+ stroke: #C0C0C0;
+ stroke-dasharray: 1,1;
+ opacity: 0.5;
+}
+
+.y.axis text, .x.axis text, .focus text, div.d3Chart .title {
+ font-size: 12px;
+}
+
+.y.axis path {
+ stroke: #000;
+ }
+
+.overlay {
+ fill: none;
+ pointer-events: all;
+ }
+
+.focus circle {
+ fill: none;
+ stroke: steelblue;
+ }
+.focus .fo-table {
+ /* box-shadow: 2px 2px 3px #EEE; */
+}
+
+div.d3Chart {
+ padding: 1em 0;
+ border: 1px solid #C0C0C0;
+}
+div.d3Chart.hDash {
+ border: 0px;
+}
+
+div.d3Chart .axis path {
+ display: inherit;
+}
+.c3-circle {
+ display: none;
+}
+
+.fo-table {
+ border: 1px solid darkgray;
+ background-color: white;
+ font-size: .85em;
+}
+
+.fo-table td {
+ padding: 4px;
+ border-left: 1px solid darkgray;
+}
+.fo-table tr.detail td {
+ padding: 1px 4px;
+}
+.fo-title {
+ color: white;
+ background-color: darkgray;
+}
+
+.fo-table-legend {
+ width: 8px;
+ height: 8px;
+ border: 1px solid black;
+ margin: 0 4px;
+ display: inline-block;
+}
+
+svg .legend {
+ dominant-baseline: central;
+}
+
+div.chartContainer div.aChart {
+ margin-top: 0.5em;
+}
+
+#list-controller .tree-header {
+ position: absolute;
+ height: auto;
+}
+
+#list-controller select {
+ height: 25px;
+ float: left;
+ padding: 0;
+}
+
+
+div#main.qdr div ul.nav li.active a {
+ background-color: #e0e0ff !important;
+ color: #000000;
+}
+
+div#main.qdr .selected, .box.selected {
+ color: #000000;
+ text-shadow: none;
+}
+
+/* the selected node on the list page */
+div.qdrList li.active, ul.qdrListNodes li.active {
+ background-color: #e0e0ff;
+}
+
+div.qdr-attributes span.dynatree-selected a {
+ background-color: #e0e0ff;
+}
+div.qdr-attributes.pane, div.qdr-topology.pane {
+ position: absolute;
+ margin-left: 10px;
+}
+div.qdr-overview.pane {
+ position: absolute;
+}
+div.qdr-topology.pane.left {
+ width: auto;
+ /*border-right: 1px solid lightgray; */
+}
+
+/* the selected row in the name table */
+div#main.qdr div.qdrList div.selected {
+ background-color: #e0e0ff !important;
+}
+
+#dialogChart, #dialogEditChart {
+ height: 200px;
+}
+
+.chartOptions .modal-body {
+ overflow-y: initial;
+}
+
+div.qdrCharts p.chartLabels button {
+ float: right;
+}
+
+div.qdrCharts p.chartLabels {
+ padding-right: 1em;;
+ }
+
+p.dialogHeader {
+ text-align: center;
+}
+
+p.dialogHeader input {
+ margin-top: 10px;
+ width: 480px;
+}
+
+.ui-slider-tick {
+ position: absolute;
+ background-color: #666;
+ width: 2px;
+ height: 8px;
+ top: 12px;
+ z-index: -1;
+}
+
+label.rateGroup {
+ float: left;
+}
+
+div.chartOptions div.dlg-slider {
+ float: left;
+ width: 28em;
+ font-size: 14px;
+}
+
+div.chartOptions div.duration {
+ width: 35em !important;
+}
+
+div.chartOptions .slider {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+input[type="radio"] {
+ margin-top: 0 !important;
+}
+
+div.chartOptions legend {
+ font-size: 1.2em;
+ font-weight: bold;
+ margin-bottom: 10px;
+}
+
+div.chartOptions tab > div {
+ margin-left: 1em;
+}
+
+div.chartOptions span.minicolors-swatch {
+ width: 14px;
+ height: 14px;
+}
+
+.minicolors-input {
+ width: 4em;
+ padding: 0 0 0 24px !important;
+}
+
+div.colorPicker div.colorText {
+ display: inline-block;
+ width: 10em;
+}
+div.colorPicker div:nth-of-type(1), /* first span under div.colorPicker */
+ div.minicolors{
+ float:left;
+ margin-right: 0.5em;
+}
+
+div.chartOptions p.sep {
+ height: 1em;
+}
+
+ul.nav-tabs {
+ border-bottom: 1px solid #ddd !important;
+}
+
+.chartOptions ul.nav-tabs {
+ margin-bottom: 0px !important;
+}
+
+div.tabbable div.tab-content {
+ overflow: visible;
+}
+
+div.tabbable ul.nav-tabs > .active > a {
+ background-color: #f8f8f8;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+
+
+div.tabbable .tab-pane {
+ background-color: #f8f8f8;
+ padding: 12px;
+ border-right: 1px solid #ddd;
+ border-left: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+}
+div.dlg-large div.tabbable .tab-pane {
+ margin-left: 11em;
+}
+
+div.tabbable ul.nav-tabs {
+ margin-bottom: 0;
+}
+
+ul.qdrTopoModes {
+ position: relative;
+ top: -10px;
+}
+.overview.section {
+ /* width: 35em; */
+}
+.overview.section .ngGrid {
+ height: 12em !important;
+ min-height: 12em !important;
+}
+
+.overview.routers.section .ngGrid {
+ height: 16em !important;
+ min-height: 16em !important;
+}
+.overview.routers.section {
+ /*width: 15em; */
+ }
+
+.grid-align-value {
+ text-align: right;
+}
+
+.grid-align-value .ngCellText {
+ padding-right: 10px;
+}
+
+.overview .ngRow:hover {
+ background:#e0e0ff;
+}
+
+.overview-cell .ngCell:hover {
+ background:#e0e0ff;
+}
+.overview-cell .ngCell.col0:hover, .overview-cell .ngCell.col1:hover {
+ background: initial;
+}
+
+
+.qdr-overview.pane.left, .qdr-attributes.pane.left {
+ top: 104px;
+}
+.qdr-topology.pane.left {
+ top: 104px;
+}
+.qdr-overview.pane.left, .qdr-attributes.pane.left, .qdr-topology.pane.left {
+ left: 10px;
+}
+
+.treeContainer {
+ width: 100%;
+ float: left;
+}
+
+.pane-content {
+ overflow: auto;
+}
+
+#entityNames {
+ width: 20em;
+ float: left;
+}
+
+.treeDetails {
+ margin-left: 260px;
+}
+
+.gridStyle:not(.noHighlight) .ui-grid-row:hover .ui-grid-cell-contents {
+ background-color: #e0e0ff;
+}
+
+.ngCellText {
+ padding: 4px 0 0 4px;
+}
+
+.overview {
+ border-bottom: 1px solid #d4d4d4;
+}
+
+.ui-grid-row.ui-grid-row-selected > [ui-grid-row] > .ui-grid-cell {
+ background-color: #e0e0ff;
+}
+
+.tab-content .tab-pane {
+ background-color: #f8f8f8;
+ padding: 12px;
+ border-right: 1px solid #ddd;
+ border-left: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+}
+
+div.chartOptions ul.nav-tabs > .active > a {
+ background-color: #f8f8f8;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+
+div.chartOptions label:nth-of-type(2) {
+ margin-left: 1em;
+}
+div.chartOptions label {
+ font-weight: normal;
+ display: inline-block;
+}
+
+/*
+.form-horizontal .control-label {
+ float: left;
+ width: 160px;
+ padding-top: 5px;
+ text-align: right;
+}
+
+.form-horizontal .controls {
+ margin-left: 180px;
+}
+
+.form-horizontal input, {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+}
+
+input[type="text"], input[type="number"], input[type="password"] {
+ background-color: #ffffff;
+ border: 1px solid #cccccc;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -o-transition: border linear 0.2s, box-shadow linear 0.2s;
+ transition: border linear 0.2s, box-shadow linear 0.2s;
+}
+
+input[type="text"], input[type="number"], input[type="password"] {
+ display: inline-block;
+ width: 200px;
+ padding: 4px 6px;
+ margin-bottom: 10px;
+ font-size: 14px;
+ line-height: 20px;
+ color: #555555;
+ vertical-align: middle;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.login input[type="checkbox"] {
+ margin-top: 0.75em;
+}
+*/
+
+#dispatch-login-container {
+ /* width: 18.5em; */
+ margin-top: 2em;
+}
+/*
+div.login.container {
+ width: 550px;
+}
+*/
+
+
+#overtree .fancytree-container {
+ border: 0px;
+}
+
+#overtree span.fancytree-alert-icon.ui-icon-refresh {
+ background-position: -64px -80px;
+}
+#overtree span.fancytree-alert-icon.ui-icon-transfer-e-w {
+ background-position: -112px -80px;
+}
+
+#alerts {
+ position: fixed;
+ right: 0;
+ top: 0;
+ z-index: 100;
+}
+
+.alert-enter,
+.alert-leave,
+.alert-move {
+ -webkit-transition: 1s linear all;
+ -moz-transition: 1s linear all;
+ -o-transition: 1s linear all;
+ transition: 1s linear all;
+ position:relative;
+}
+
+.alert-enter {
+ left:-10px;
+ opacity:0;
+}
+.alert-enter.alert-enter-active {
+ left:0;
+ opacity:1;
+}
+
+.alert-leave {
+ left:0;
+ opacity:1;
+}
+.alert-leave.alert-leave-active {
+ left:-10px;
+ opacity:0;
+}
+
+.alert-move {
+ opacity:0.5;
+}
+.alert-move.alert-move-active {
+ opacity:1;
+}
+
+.overview .table-striped tr:hover td {
+ background-color: #e0e0ff !important;
+}
+
+#entityNames div.ngViewport {
+ overflow-x: hidden;
+}
+
+.connect-column.connect-form {
+ width: 20em;
+}
+
+.chartLabels button a {
+ text-decoration: none;
+}
+
+.fancytree-ico-c.router .fancytree-icon {
+
+}
+
+.tabs-left .nav-tabs {
+ float: left;
+}
+.tabs-left .nav-tabs > li {
+/* float: initial; */
+}
+
+div.modal.dlg-large {
+ width: 53em;
+}
+
+button.hdash-button a {
+ text-decoration: none;
+ color: #fff;
+}
+
+div.widget-body > div {
+ height: 100%;
+}
+
+div.qdrCharts {
+ height: 100%;
+}
+
+ul.dispatch-view {
+ margin-bottom: 0 !important;
+}
+
+.qdr-overview.pane.left span:not(.dynatree-has-children) .dynatree-icon:before,
+.qdr-attributes.pane.left span:not(.dynatree-has-children) .dynatree-icon:before {
+ color: green;
+}
+
+span:not(.dynatree-has-children).address .dynatree-icon:before,
+span:not(.dynatree-has-children).router\.address .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f0ac";
+}
+span:not(.dynatree-has-children).address.mobile .dynatree-icon:before,
+span:not(.dynatree-has-children).router\.address.mobile .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f109";
+}
+span:not(.dynatree-has-children).address.internal.mobile .dynatree-icon:before,
+span:not(.dynatree-has-children).router\.address.internal.mobile .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f0ac";
+}
+span:not(.dynatree-has-children).address.router .dynatree-icon:before,
+span:not(.dynatree-has-children).router\.address.router .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f047";
+}
+
+span.address-link .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f0ac";
+}
+
+span:not(.dynatree-has-children).connection.external .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f109";
+}
+span:not(.dynatree-has-children).connection.normal .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f08e";
+}
+span:not(.dynatree-has-children).connection.external.quiesced .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f14c";
+ color: red;
+}
+span:not(.dynatree-has-children).connection.inter-router .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f07e";
+}
+span:not(.dynatree-has-children).connection.router-control .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f013";
+}
+span:not(.dynatree-has-children).no-data .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f05e";
+ color: red !important;
+}
+span:not(.dynatree-has-children).loading .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f254";
+}
+span:not(.dynatree-has-children).connector .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f126";
+}
+span:not(.dynatree-has-children).container .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f16c";
+}
+span:not(.dynatree-has-children).log .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f0f6";
+}
+span:not(.dynatree-has-children).router\.node .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f013";
+}
+span:not(.dynatree-has-children).link.inter-router .dynatree-icon:before,
+span:not(.dynatree-has-children).router\.link.inter-router .dynatree-icon:before{
+ font-family: FontAwesome;
+ content: "\f07e";
+}
+span:not(.dynatree-has-children).link.router-control .dynatree-icon:before,
+span:not(.dynatree-has-children).router\.link.router-control .dynatree-icon:before{
+ font-family: FontAwesome;
+ content: "\f013";
+}
+span:not(.dynatree-has-children).link.endpoint .dynatree-icon:before,
+span:not(.dynatree-has-children).router\.link.endpoint .dynatree-icon:before{
+ font-family: FontAwesome;
+ content: "\f109";
+}
+span:not(.dynatree-has-children).link.console .dynatree-icon:before,
+span:not(.dynatree-has-children).router\.link.console .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f108";
+}
+span:not(.dynatree-has-children).listener .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f025";
+}
+span:not(.dynatree-has-children).connection .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f07e";
+}
+span:not(.dynatree-has-children).connection.console .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f108";
+}
+span:not(.dynatree-has-children).waypoint .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f0ec";
+}
+span:not(.dynatree-has-children).router .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f047";
+}
+span:not(.dynatree-has-children).fixedAddress .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f015";
+}
+span:not(.dynatree-has-children).linkRoutePattern .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f039";
+}
+span:not(.dynatree-has-children).allocator .dynatree-icon:before {
+ font-family: FontAwesome;
+ content: "\f170";
+}
+
+.ngCellText {
+/* color: #333333; */
+}
+
+.changed {
+ color: #339933;
+}
+
+div.dispatch-router div.help {
+ width: auto;
+ padding: 1em;
+ background-color: lavender;
+ border-radius: 6px;
+ margin-top: 1em;
+ text-align: center;
+}
+
+div.operations tr:nth-child(even) {
+ background: #f3f3f3;
+}
+div.operations tr:nth-child(odd), div.operations tr:last-child {
+ background: #fff;
+}
+
+div.operations tr input {
+ margin: 0;
+ padding: 3px 6px;
+}
+div.operations table {
+ width: 100%;
+}
+div.operations th {
+ width: 50%;
+ border-bottom: 1px solid #cccccc;
+ text-align: left;
+}
+div.operations td:nth-child(odd), div.operations th:nth-child(odd) {
+ border-right: 1px solid #cccccc;
+}
+div.operations td:nth-child(odd) {
+ padding-left: 0;
+}
+div.operations td:nth-child(even), div.operations th:nth-child(even) {
+ padding-left: 5px;
+}
+div.operations th {
+ padding: 5px;
+}
+div.operations .tab-pane.active {
+ padding: 12px 12px 12px 0;
+}
+div.operations label {
+ padding-top: 4px;
+ margin-bottom: 4px;
+}
+.qdrListActions .ngGrid {
+ /*min-height: 40em;
+ height: 100%; */
+}
+div.qdrListActions .ngViewport {
+ height: initial !important;
+}
+
+div.operations .boolean {
+ padding-bottom: 0;
+}
+
+table.log-entry {
+ margin-bottom: 1em;
+ border-top: 1px solid black;
+}
+
+table.log-entry pre {
+ background-color: #f5f5f5;
+ color: inherit;
+ margin: 0;
+}
+
+circle.node.normal.console {
+ fill: lightcyan;
+}
+circle.node.artemis {
+ fill: lightgreen;
+}
+circle.node.route-container {
+ fill: orange;
+}
+
+text.console, text.on-demand, text.normal {
+ font-family: FontAwesome;
+ font-weight: normal;
+ font-size: 16px;
+}
+
+@font-face {
+ font-family:"Brokers";
+ src: url("brokers.ttf") /* TTF file for CSS3 browsers */
+}
+
+text.artemis {
+ font-family: Brokers;
+ font-size: 20px;
+ font-weight: bold;
+}
+
+text.qpid-cpp {
+ font-family: Brokers;
+ font-size: 18px;
+ font-weight: bold;
+}
+
+i.red {
+ color: red;
+}
+
+.qdrListActions div.delete {
+ width: 20em;
+ margin: auto;
+ border: 1px solid #eaeaea;
+ height: 5em;
+ padding: 4em;
+ background-color: #fcfcfc;
+}
+
+.btn:focus {
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+}
+
+select:focus, input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus {
+ outline:3px solid rgba(82, 168, 236, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+btn.disabled, .btn[disabled] {
+ opacity: 0.35;
+}
+
+#dispatch-login-container .ng-invalid-range {
+ border-color: #e9322d !important;
+}
+
+div#durationSlider, div#rateSlider {
+ margin-top: 1em;
+}
+
+.list-grid {
+ padding-left: 10px;
+}
+
+.ngViewport.ng-scope {
+ height: auto !important;
+}
+
+div#list-controller {
+ padding-left: 300px;
+}
+
+.listening-on {
+ background-color: #CCFFCC;
+}
\ 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
[4/4] qpid-dispatch git commit: DISPATCH-886 Account for / in router
name and prevent script injections
Posted by ea...@apache.org.
DISPATCH-886 Account for / in router name and prevent script injections
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/55d7bd34
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/55d7bd34
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/55d7bd34
Branch: refs/heads/master
Commit: 55d7bd34bc14aad781754cab3c987bba79a36b5f
Parents: 79ae73f
Author: Ernest Allen <ea...@redhat.com>
Authored: Wed Nov 29 14:57:56 2017 -0500
Committer: Ernest Allen <ea...@redhat.com>
Committed: Wed Nov 29 14:57:56 2017 -0500
----------------------------------------------------------------------
.../main/webapp/plugin/js/qdrChartService.js | 1155 +++++++++++++++-
.../hawtio/src/main/webapp/plugin/js/qdrList.js | 5 +
.../src/main/webapp/plugin/js/qdrOverview.js | 7 +-
.../src/main/webapp/plugin/js/qdrSchema.js | 82 +-
.../src/main/webapp/plugin/js/qdrService.js | 1233 +++++++++++++++++-
.../src/main/webapp/plugin/js/qdrSettings.js | 189 ++-
.../src/main/webapp/plugin/lib/rhea-min.js | 7 +-
7 files changed, 2672 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/55d7bd34/console/hawtio/src/main/webapp/plugin/js/qdrChartService.js
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrChartService.js b/console/hawtio/src/main/webapp/plugin/js/qdrChartService.js
deleted file mode 120000
index dc5df4c..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrChartService.js
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/js/qdrChartService.js
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrChartService.js b/console/hawtio/src/main/webapp/plugin/js/qdrChartService.js
new file mode 100644
index 0000000..cc64981
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/js/qdrChartService.js
@@ -0,0 +1,1154 @@
+/*
+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) {
+
+ // The QDR chart service handles periodic gathering data for charts and displaying the charts
+ QDR.module.factory("QDRChartService", ['$rootScope', 'QDRService', '$http', '$resource', '$location',
+ function($rootScope, QDRService, $http, $resource, $location) {
+
+ var instance = 0; // counter for chart instances
+ var bases = [];
+ var findBase = function(name, attr, request) {
+ for (var i = 0; i < bases.length; ++i) {
+ var base = bases[i];
+ if (base.equals(name, attr, request))
+ return base;
+ }
+ return null;
+ }
+
+ function ChartBase(name, attr, request) {
+ // the base chart attributes
+ this.name = name; // the record's "name" field
+ this.attr = attr; // the record's attr field to chart
+ this.request = request; // the associated request that fetches the data
+
+ // copy the savable properties to an object
+ this.copyProps = function(o) {
+ o.name = this.name;
+ o.attr = this.attr;
+ this.request.copyProps(o);
+ }
+
+ this.equals = function(name, attr, request) {
+ return (this.name == name && this.attr == attr && this.request.equals(request));
+ }
+ };
+
+ // Object that represents a visible chart
+ // There can be multiple of these per ChartBase (eg. one rate and one value chart)
+ function Chart(opts, request) { //name, attr, cinstance, request) {
+
+ var base = findBase(opts.name, opts.attr, request);
+ if (!base) {
+ base = new ChartBase(opts.name, opts.attr, request);
+ bases.push(base);
+ }
+ this.base = base;
+ this.instance = angular.isDefined(opts.instance) ? opts.instance : ++instance;
+ this.dashboard = false; // is this chart on the dashboard page
+ this.hdash = false; // is this chart on the hawtio dashboard page
+ this.hreq = false; // has this hdash chart been requested
+ this.type = opts.type ? opts.type : "value"; // value or rate
+ this.rateWindow = opts.rateWindow ? opts.rateWindow : 1000; // calculate the rate of change over this time interval. higher == smother graph
+ this.areaColor = "#cbe7f3"; // the chart's area color when not an empty string
+ this.lineColor = "#058dc7"; // the chart's line color when not an empty string
+ this.visibleDuration = opts.visibleDuration ? opts.visibleDuration : 10; // number of minutes of data to show (<= base.duration)
+ this.userTitle = null; // user title overrides title()
+
+ // generate a unique id for this chart
+ this.id = function() {
+ var name = this.name()
+ var nameparts = name.split('/');
+ if (nameparts.length == 2)
+ name = nameparts[1];
+ var key = QDRService.nameFromId(this.request().nodeId) + this.request().entity + name + this.attr() + "_" + this.instance + "_" + (this.request().aggregate ? "1" : "0");
+ // remove all characters except letters,numbers, and _
+ return key.replace(/[^\w]/gi, '')
+ }
+ // copy the savable properties to an object
+ this.copyProps = function(o) {
+ o.type = this.type;
+ o.rateWindow = this.rateWindow;
+ o.areaColor = this.areaColor;
+ o.lineColor = this.lineColor;
+ o.visibleDuration = this.visibleDuration;
+ o.userTitle = this.userTitle;
+ o.dashboard = this.dashboard;
+ o.hdash = this.hdash;
+ o.instance = this.instance;
+ this.base.copyProps(o);
+ }
+ this.name = function(_) {
+ if (!arguments.length) return this.base.name;
+ this.base.name = _;
+ return this;
+ }
+ this.attr = function(_) {
+ if (!arguments.length) return this.base.attr;
+ this.base.attr = _;
+ return this;
+ }
+ this.nodeId = function(_) {
+ if (!arguments.length) return this.base.request.nodeId;
+ this.base.request.nodeId = _;
+ return this;
+ }
+ this.entity = function(_) {
+ if (!arguments.length) return this.base.request.entity;
+ this.base.request.entity = _;
+ return this;
+ }
+ this.aggregate = function(_) {
+ if (!arguments.length) return this.base.request.aggregate;
+ this.base.request.aggregate = _;
+ return this;
+ }
+ this.request = function(_) {
+ if (!arguments.length) return this.base.request;
+ this.base.request = _;
+ return this;
+ }
+ this.data = function() {
+ return this.base.request.data(this.base.name, this.base.attr); // refernce to chart's data array
+ }
+ this.interval = function(_) {
+ if (!arguments.length) return this.base.request.interval;
+ this.base.request.interval = _;
+ return this;
+ }
+ this.duration = function(_) {
+ if (!arguments.length) return this.base.request.duration;
+ this.base.request.duration = _;
+ return this;
+ }
+ this.title = function(_) {
+ var name = this.request().aggregate ? 'Aggregate' : QDRService.nameFromId(this.nodeId());
+ var computed = name +
+ " " + QDRService.humanify(this.attr()) +
+ " - " + this.name()
+ if (!arguments.length) return this.userTitle || computed;
+
+ // don't store computed title in userTitle
+ if (_ === computed)
+ _ = null;
+ this.userTitle = _;
+ return this;
+ }
+ this.title_short = function(_) {
+ if (!arguments.length) return this.userTitle || this.name();
+ return this;
+ }
+ this.copy = function() {
+ var chart = self.registerChart({
+ nodeId: this.nodeId(),
+ entity: this.entity(),
+ name: this.name(),
+ attr: this.attr(),
+ interval: this.interval(),
+ forceCreate: true,
+ aggregate: this.aggregate(),
+ hdash: this.hdash
+ })
+ chart.type = this.type;
+ chart.areaColor = this.areaColor;
+ chart.lineColor = this.lineColor;
+ chart.rateWindow = this.rateWindow;
+ chart.visibleDuration = this.visibleDuration;
+ chart.userTitle = this.userTitle;
+ return chart;
+ }
+ // compare to a chart
+ this.equals = function(c) {
+ return (c.instance == this.instance &&
+ c.base.equals(this.base.name, this.base.attr, this.base.request) &&
+ c.type == this.type &&
+ c.rateWindow == this.rateWindow &&
+ c.areaColor == this.areaColor &&
+ c.lineColor == this.lineColor)
+ }
+ }
+
+ // Object that represents the management request to fetch and store data for multiple charts
+ function ChartRequest(opts) { //nodeId, entity, name, attr, interval, aggregate) {
+ this.duration = opts.duration || 10; // number of minutes to keep the data
+ this.nodeId = opts.nodeId; // eg amqp:/_topo/0/QDR.A/$management
+ this.entity = opts.entity; // eg .router.address
+ // sorted since the responses will always be sorted
+ this.aggregate = opts.aggregate; // list of nodeIds for aggregate charts
+ this.datum = {}; // object containing array of arrays for each attr
+ // like {attr1: [[date,value],[date,value]...], attr2: [[date,value]...]}
+
+ this.interval = opts.interval || 1000; // number of milliseconds between updates to data
+ this.setTimeoutHandle = null; // used to cancel the next request
+ // copy the savable properties to an object
+
+ this.data = function(name, attr) {
+ if (this.datum[name] && this.datum[name][attr])
+ return this.datum[name][attr]
+ return null;
+ }
+ this.addAttrName = function(name, attr) {
+ if (Object.keys(this.datum).indexOf(name) == -1) {
+ this.datum[name] = {}
+ }
+ if (Object.keys(this.datum[name]).indexOf(attr) == -1) {
+ this.datum[name][attr] = [];
+ }
+ }
+ this.addAttrName(opts.name, opts.attr)
+
+ this.copyProps = function(o) {
+ o.nodeId = this.nodeId;
+ o.entity = this.entity;
+ o.interval = this.interval;
+ o.aggregate = this.aggregate;
+ o.duration = this.duration;
+ }
+
+ this.removeAttr = function(name, attr) {
+ if (this.datum[name]) {
+ if (this.datum[name][attr]) {
+ delete this.datum[name][attr]
+ }
+ }
+ return this.attrs().length;
+ }
+
+ this.equals = function(r, entity, aggregate) {
+ if (arguments.length == 3) {
+ var o = {
+ nodeId: r,
+ entity: entity,
+ aggregate: aggregate
+ }
+ r = o;
+ }
+ return (this.nodeId === r.nodeId && this.entity === r.entity && this.aggregate == r.aggregate)
+ }
+ this.names = function() {
+ return Object.keys(this.datum)
+ }
+ this.attrs = function() {
+ var attrs = {}
+ Object.keys(this.datum).forEach(function(name) {
+ Object.keys(this.datum[name]).forEach(function(attr) {
+ attrs[attr] = 1;
+ })
+ }, this)
+ return Object.keys(attrs);
+ }
+ };
+
+ // Below here are the properties and methods available on QDRChartService
+ var self = {
+ charts: [], // list of charts to gather data for
+ chartRequests: [], // the management request info (multiple charts can be driven off of a single request
+
+ init: function() {
+ self.loadCharts();
+ QDRService.addDisconnectAction(function() {
+ self.charts.forEach(function(chart) {
+ self.unRegisterChart(chart, true)
+ })
+ QDRService.addConnectAction(self.init);
+ })
+ },
+
+ findChartRequest: function(nodeId, entity, aggregate) {
+ var ret = null;
+ self.chartRequests.some(function(request) {
+ if (request.equals(nodeId, entity, aggregate)) {
+ ret = request;
+ return true;
+ }
+ })
+ return ret;
+ },
+
+ findCharts: function(opts) { //name, attr, nodeId, entity, hdash) {
+ if (!opts.hdash)
+ opts.hdash = false; // rather than undefined
+ return self.charts.filter(function(chart) {
+ return (chart.name() == opts.name &&
+ chart.attr() == opts.attr &&
+ chart.nodeId() == opts.nodeId &&
+ chart.entity() == opts.entity &&
+ chart.hdash == opts.hdash)
+ });
+ },
+
+ delChartRequest: function(request) {
+ for (var i = 0; i < self.chartRequests.length; ++i) {
+ var r = self.chartRequests[i];
+ if (request.equals(r)) {
+ QDR.log.debug("removed request: " + request.nodeId + " " + request.entity);
+ self.chartRequests.splice(i, 1);
+ self.stopCollecting(request);
+ return;
+ }
+ }
+ },
+
+ delChart: function(chart, skipSave) {
+ var foundBases = 0;
+ for (var i = 0; i < self.charts.length; ++i) {
+ var c = self.charts[i];
+ if (c.base === chart.base)
+ ++foundBases;
+ if (c.equals(chart)) {
+ self.charts.splice(i, 1);
+ if (chart.dashboard && !skipSave)
+ self.saveCharts();
+ }
+ }
+ if (foundBases == 1) {
+ var baseIndex = bases.indexOf(chart.base)
+ bases.splice(baseIndex, 1);
+ }
+ },
+
+ registerChart: function(opts) { //nodeId, entity, name, attr, interval, instance, forceCreate, aggregate, hdash) {
+ var request = self.findChartRequest(opts.nodeId, opts.entity, opts.aggregate);
+ if (request) {
+ // add any new attr or name to the list
+ request.addAttrName(opts.name, opts.attr)
+ } else {
+ // the nodeId/entity did not already exist, so add a new request and chart
+ QDR.log.debug("added new request: " + opts.nodeId + " " + opts.entity);
+ request = new ChartRequest(opts); //nodeId, entity, name, attr, interval, aggregate);
+ self.chartRequests.push(request);
+ self.startCollecting(request);
+ }
+ var charts = self.findCharts(opts); //name, attr, nodeId, entity, hdash);
+ var chart;
+ if (charts.length == 0 || opts.forceCreate) {
+ if (!opts.use_instance && opts.instance)
+ delete opts.instance;
+ chart = new Chart(opts, request) //opts.name, opts.attr, opts.instance, request);
+ self.charts.push(chart);
+ } else {
+ chart = charts[0];
+ }
+ return chart;
+ },
+
+ // remove the chart for name/attr
+ // if all attrs are gone for this request, remove the request
+ unRegisterChart: function(chart, skipSave) {
+ // remove the chart
+
+ // TODO: how do we remove charts that were added to the hawtio dashboard but then removed?
+ // We don't get a notification that they were removed. Instead, we could just stop sending
+ // the request in the background and only send the request when the chart's tick() event is triggered
+ //if (chart.hdash) {
+ // chart.dashboard = false;
+ // self.saveCharts();
+ // return;
+ //}
+
+ for (var i = 0; i < self.charts.length; ++i) {
+ var c = self.charts[i];
+ if (chart.equals(c)) {
+ var request = chart.request();
+ self.delChart(chart, skipSave);
+ if (request) {
+ // see if any other charts use this attr
+ for (var i = 0; i < self.charts.length; ++i) {
+ var c = self.charts[i];
+ if (c.attr() == chart.attr() && c.request().equals(chart.request()))
+ return;
+ }
+ // no other charts use this attr, so remove it
+ if (request.removeAttr(chart.name(), chart.attr()) == 0) {
+ self.stopCollecting(request);
+ self.delChartRequest(request);
+ }
+ }
+ }
+ }
+ if (!skipSave)
+ self.saveCharts();
+ },
+
+ stopCollecting: function(request) {
+ if (request.setTimeoutHandle) {
+ clearTimeout(request.setTimeoutHandle);
+ request.setTimeoutHandle = null;
+ }
+ },
+
+ startCollecting: function(request) {
+ // Using setTimeout instead of setInterval because the response may take longer than interval
+ request.setTimeoutHandle = setTimeout(self.sendChartRequest, request.interval, request);
+ },
+ shouldRequest: function(request) {
+ // see if any of the charts associated with this request have either dialog, dashboard, or hreq
+ return self.charts.some(function(chart) {
+ return (chart.dashboard || chart.hreq) || (!chart.dashboard && !chart.hdash);
+ });
+ },
+ // send the request
+ sendChartRequest: function(request, once) {
+ if (!once && !self.shouldRequest(request)) {
+ request.setTimeoutHandle = setTimeout(self.sendChartRequest, request.interval, request)
+ return;
+ }
+
+ // ensure the response has the name field so we can associate the response values with the correct chart
+ var attrs = request.attrs();
+ if (attrs.indexOf("name") == -1)
+ attrs.push("name");
+
+ // this is called when the response is received
+ var saveResponse = function(nodeId, entity, response) {
+ if (!response || !response.attributeNames)
+ return;
+ //QDR.log.debug("got chart results for " + nodeId + " " + entity);
+ // records is an array that has data for all names
+ var records = response.results;
+ if (!records)
+ return;
+
+ var now = new Date();
+ var cutOff = new Date(now.getTime() - request.duration * 60 * 1000);
+ // index of the "name" attr in the response
+ var nameIndex = response.attributeNames.indexOf("name");
+ if (nameIndex < 0)
+ return;
+
+ var names = request.names();
+ // for each record returned, find the name/attr for this request and save the data with this timestamp
+ for (var i = 0; i < records.length; ++i) {
+ var name = records[i][nameIndex];
+ // if we want to store the values for some attrs for this name
+ if (names.indexOf(name) > -1) {
+ attrs.forEach(function(attr) {
+ var data = request.data(name, attr) // get a reference to the data array
+ if (data) {
+ var attrIndex = response.attributeNames.indexOf(attr)
+ if (request.aggregate) {
+ data.push([now, response.aggregates[i][attrIndex].sum, response.aggregates[i][attrIndex].detail])
+ } else {
+ data.push([now, records[i][attrIndex]])
+ }
+ // expire the old data
+ while (data[0][0] < cutOff) {
+ data.shift();
+ }
+ }
+ })
+ }
+ }
+ }
+ if (request.aggregate) {
+ var nodeList = QDRService.nodeIdList()
+ QDRService.getMultipleNodeInfo(nodeList, request.entity, attrs, saveResponse, request.nodeId);
+ } else {
+ QDRService.fetchEntity(request.nodeId, request.entity, attrs, saveResponse);
+ }
+ // it is now safe to schedule another request
+ if (once)
+ return;
+ request.setTimeoutHandle = setTimeout(self.sendChartRequest, request.interval, request)
+ },
+
+ numCharts: function() {
+ return self.charts.filter(function(chart) {
+ return chart.dashboard
+ }).length;
+ //return self.charts.length;
+ },
+
+ isAttrCharted: function(nodeId, entity, name, attr) {
+ var charts = self.findCharts({
+ name: name,
+ attr: attr,
+ nodeId: nodeId,
+ entity: entity
+ })
+ // if any of the matching charts are on the dashboard page, return true
+ return charts.some(function(chart) {
+ return (chart.dashboard)
+ });
+ },
+
+ addHDash: function(chart) {
+ chart.hdash = true;
+ self.saveCharts();
+ },
+ delHDash: function(chart) {
+ chart.hdash = false;
+ self.saveCharts();
+ },
+ addDashboard: function(chart) {
+ chart.dashboard = true;
+ self.saveCharts();
+ },
+ delDashboard: function(chart) {
+ chart.dashboard = false;
+ self.saveCharts();
+ },
+ // save the charts to local storage
+ saveCharts: function() {
+ var charts = [];
+ var minCharts = [];
+
+ self.charts.forEach(function(chart) {
+ var minChart = {};
+ // don't save chart unless it is on the dashboard
+ if (chart.dashboard || chart.hdash) {
+ chart.copyProps(minChart);
+ minCharts.push(minChart);
+ }
+ })
+ localStorage["QDRCharts"] = angular.toJson(minCharts);
+ },
+ loadCharts: function() {
+ var charts = angular.fromJson(localStorage["QDRCharts"]);
+ if (charts) {
+ // get array of known ids
+ var nodeList = QDRService.nodeList().map(function(node) {
+ return node.id;
+ })
+ charts.forEach(function(chart) {
+ // if this chart is not in the current list of nodes, skip
+ if (nodeList.indexOf(chart.nodeId) >= 0) {
+ if (!angular.isDefined(chart.instance)) {
+ chart.instance = ++instance;
+ }
+ if (chart.instance >= instance)
+ instance = chart.instance + 1;
+ if (!chart.duration)
+ chart.duration = 10;
+ if (chart.nodeList)
+ chart.aggregate = true;
+ if (!chart.hdash)
+ chart.hdash = false;
+ if (!chart.dashboard)
+ chart.dashboard = false;
+ if (!chart.hdash && !chart.dashboard)
+ chart.dashboard = true;
+ if (chart.hdash && chart.dashboard)
+ chart.dashboard = false;
+ chart.forceCreate = true;
+ chart.use_instance = true;
+ var newChart = self.registerChart(chart); //chart.nodeId, chart.entity, chart.name, chart.attr, chart.interval, true, chart.aggregate);
+ newChart.dashboard = chart.dashboard;
+ newChart.hdash = chart.hdash;
+ newChart.hreq = false;
+ newChart.type = chart.type;
+ newChart.rateWindow = chart.rateWindow;
+ newChart.areaColor = chart.areaColor ? chart.areaColor : "#cbe7f3";
+ newChart.lineColor = chart.lineColor ? chart.lineColor : "#058dc7";
+ newChart.duration(chart.duration);
+ newChart.visibleDuration = chart.visibleDuration ? chart.visibleDuration : 10;
+ if (chart.userTitle)
+ newChart.title(chart.userTitle);
+ }
+ })
+ }
+ },
+
+ AreaChart: function(chart) {
+ if (!chart)
+ return;
+
+ // if this is an aggregate chart, show it stacked
+ var stacked = chart.request().aggregate;
+ this.chart = chart; // reference to underlying chart
+ this.svgchart = null;
+ this.url = $location.absUrl();
+
+ // callback function. called by svgchart when binding data
+ // the variable 'this' refers to the svg and not the AreaChart,
+ // but since we are still in the scope of the AreaChart we have access to the passed in chart argument
+ this.chartData = function() {
+
+ var now = new Date();
+ var visibleDate = new Date(now.getTime() - chart.visibleDuration * 60 * 1000);
+ var data = chart.data();
+ var nodeList = QDRService.nodeIdList();
+
+ if (chart.type == "rate") {
+ var rateData = [];
+ var datalen = data.length;
+ k = 0; // inner loop optimization
+ for (var i = 0; i < datalen; ++i) {
+ var d = data[i];
+ if (d[0] >= visibleDate) {
+ for (var j = k + 1; j < datalen; ++j) {
+ var d1 = data[j];
+ if (d1[0] - d[0] >= chart.rateWindow) { // rateWindow is the timespan to calculate rates
+ var elapsed = Math.max((d1[0] - d[0]) / 1000, 1); // number of seconds that elapsed
+ var rd = [d1[0], (d1[1] - d[1]) / elapsed]
+ k = j; // start here next time
+ // this is a stacked (aggregate) chart
+ if (stacked) {
+ var detail = [];
+ nodeList.forEach(function(node, nodeIndex) {
+ if (d1[2][nodeIndex] && d[2][nodeIndex])
+ detail.push({
+ node: QDRService.nameFromId(node),
+ val: (d1[2][nodeIndex].val - d[2][nodeIndex].val) / elapsed
+ })
+ })
+ rd.push(detail)
+ }
+ rateData.push(rd);
+ break;
+ }
+ }
+ }
+ }
+ // we need at least a point to chart
+ if (rateData.length == 0) {
+ rateData[0] = [chart.data()[0][0], 0, [{
+ node: '',
+ val: 0
+ }]];
+ }
+ return rateData;
+ }
+ if (chart.visibleDuration != chart.duration()) {
+ return data.filter(function(d) {
+ return d[0] >= visibleDate
+ });
+ } else
+ return data;
+ }
+
+ this.zoom = function(id, zoom) {
+ if (this.svgchart) {
+ this.svgchart.attr("zoom", zoom)
+ d3.select('#' + id)
+ .data([this.chartData()])
+ .call(this.svgchart)
+ }
+ }
+
+ // called by the controller on the page that displays the chart
+ // called whenever the controller wants to redraw the chart
+ // note: the data is collected independently of how often the chart is redrawn
+ this.tick = function(id) {
+
+ // can't draw charts that don't have data yet
+ if (this.chart.data().length == 0) {
+ return;
+ }
+
+ // if we haven't created the svg yet
+ if (!this.svgchart) {
+
+ // make sure the dom element exists on the page
+ var div = angular.element('#' + id);
+ if (!div)
+ return;
+
+ var width = div.width();
+ var height = div.height();
+
+ // make sure the dom element has a size. otherwise we wouldn't see anything anyway
+ if (!width)
+ return;
+
+ var tooltipGenerator;
+ // stacked charts have a different tooltip
+ if (stacked) {
+ tooltipGenerator = function(d, color, format) {
+ var html = "<table class='fo-table'><tbody><tr class='fo-title'>" +
+ "<td align='center' colspan='2' nowrap>Time: " + d[0].toTimeString().substring(0, 8) + "</td></tr>"
+ d[2].forEach(function(detail) {
+ html += "<tr class='detail'><td align='right' nowrap>" + detail.node + "<div class='fo-table-legend' style='background-color: " + color(detail.node) + "'></div>" + "</td><td>" + format(detail.val) + "</td></tr>"
+ })
+ html += "</tbody></table>"
+ return html;
+ }
+ } else {
+ tooltipGenerator = function(d, color, format) {
+ var html = "<table class='fo-table'><tbody><tr class='fo-title'>" +
+ "<td align='center'>Time</td><td align='center'>Value</td></tr><tr><td>" +
+ d[0].toTimeString().substring(0, 8) +
+ "</td><td>" +
+ format(d[1]) +
+ "</td></tr></tbody></table>"
+ return html;
+ }
+ }
+ // create and initialize the chart
+ this.svgchart = self.timeSeriesStackedChart(id, width, height,
+ QDRService.humanify(this.chart.attr()),
+ this.chart.name(),
+ QDRService.nameFromId(this.chart.nodeId()),
+ this.chart.entity(),
+ stacked,
+ this.chart.visibleDuration)
+ .tooltipGenerator(tooltipGenerator);
+
+ }
+ // in case the chart properties have changed, set the new props
+ this.svgchart
+ .attr("type", this.chart.type)
+ .attr("areaColor", this.chart.areaColor)
+ .attr("lineColor", this.chart.lineColor)
+ .attr("url", this.url)
+ .attr("title", this.chart.userTitle);
+
+ // bind the new data and update the chart
+ d3.select('#' + id) // the div id on the page/dialog
+ .data([this.chartData()])
+ .call(this.svgchart); // the charting function
+ }
+ },
+
+ timeSeriesStackedChart: function(id, width, height, attrName, name, node, entity, stacked, visibleDuration) {
+ var margin = {
+ top: 20,
+ right: 18,
+ bottom: 10,
+ left: 15
+ }
+ // attrs that can be changed after the chart is created by using
+ // chart.attr(<attrname>, <attrvalue>);
+ var attrs = {
+ attrName: attrName, // like Deliveries to Container. Put at top of chart
+ name: name, // like router.address/qdrhello Put at bottom of chart with node
+ node: node, // put at bottom of chart with name
+ entity: entity, // like .router.address Not used atm
+ title: "", // user title overrides the node and name at the bottom of the chart
+ url: "", // needed to reference filters and clip because of angular's location service
+ type: "value", // value or rate
+ areaColor: "", // can be set for non-stacked charts
+ lineColor: "", // can be set for non-stacked charts
+ zoom: false, // should the y-axis range start at 0 or the min data value
+ visibleDuration: visibleDuration
+ }
+ var width = width - margin.left - margin.right,
+ height = height - margin.top - margin.bottom,
+ yAxisTransitionDuration = 0
+
+ var x = d3.time.scale()
+ var y = d3.scale.linear()
+ .rangeRound([height, 0]);
+ // The x-accessor for the path generator; xScale * xValue.
+ var X = function(d) {
+ return x(d[0])
+ }
+ // The x-accessor for the path generator; yScale * yValue.
+ var Y = function Y(d) {
+ return y(d[1])
+ }
+
+ var xAxis = d3.svg.axis().scale(x).orient("bottom")
+ .outerTickSize(6)
+ .innerTickSize(-(height - margin.top - margin.bottom))
+ .tickPadding(2)
+ .ticks(d3.time.minutes, 2)
+ var yAxis = d3.svg.axis().scale(y).orient("right")
+ .outerTickSize(8)
+ .innerTickSize(-(width - margin.left - margin.right))
+ .tickPadding(10)
+ .ticks(3)
+ .tickFormat(function(d) {
+ return formatValue(d)
+ })
+
+ var tooltipGenerator = function(d, color, format) {
+ return ""
+ }; // should be overridden to set an appropriate tooltip
+ var formatValue = d3.format(".2s");
+ var formatPrecise = d3.format(",");
+ var bisectDate = d3.bisector(function(d) {
+ return d[0];
+ }).left;
+ var line = d3.svg.line();
+
+ var stack = d3.layout.stack()
+ .offset("zero")
+ .values(function(d) {
+ return d.values;
+ })
+ .x(function(d) {
+ return x(d.date);
+ })
+ .y(function(d) {
+ return d.value;
+ });
+
+ var area = d3.svg.area()
+ if (stacked) {
+ area.interpolate("cardinal")
+ .x(function(d) {
+ return x(d.date);
+ })
+ .y0(function(d) {
+ return y(d.y0);
+ })
+ .y1(function(d) {
+ return y(d.y0 + d.y);
+ });
+ } else {
+ area.interpolate("basis").x(X).y1(Y)
+ line.x(X).y(Y)
+ }
+ var color = d3.scale.category20();
+
+ var sv = d3.select("#" + id).append("svg")
+ .attr("width", width + margin.left + margin.right)
+ .attr("height", height + margin.top + margin.bottom)
+ var svg = sv
+ .append("g")
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
+
+ sv.append("linearGradient")
+ .attr("id", id) //"temperature-gradient")
+ .attr("gradientUnits", "userSpaceOnUse")
+ .attr("x1", 0).attr("y1", height * .5)
+ .attr("x2", 0).attr("y2", height * 1.2)
+ .selectAll("stop")
+ .data([{
+ offset: "0%",
+ opacity: 1
+ }, {
+ offset: "100%",
+ opacity: 0
+ }])
+ .enter().append("stop")
+ .attr("offset", function(d) {
+ return d.offset;
+ })
+ .attr("stop-opacity", function(d) {
+ return d.opacity;
+ })
+ .attr("stop-color", function(d) {
+ return "#cbe7f3"
+ });
+ /*
+ var clip = svg.append("defs").append("svg:clipPath")
+ .attr("id", "clip")
+ .append("svg:rect")
+ .attr("id", "clip-rect")
+ .attr("x", "0")
+ .attr("y", "0")
+ .attr("width", width)
+ .attr("height", height);
+ */
+ // we want all our areas to appear before the axiis
+ svg.append("g")
+ .attr("class", "section-container")
+
+ svg.append("g")
+ .attr("class", "x axis")
+
+ svg.append("g")
+ .attr("class", "y axis")
+
+ svg.append("text").attr("class", "title")
+ .attr("x", (width / 2) - (margin.left + margin.right) / 2)
+ .attr("y", 0 - (margin.top / 2))
+ .attr("text-anchor", "middle")
+ .text(attrs.attrName);
+
+ svg.append("text").attr("class", "legend")
+ .attr("x", (width / 2) - (margin.left + margin.right) / 2)
+ .attr("y", height + (margin.bottom / 2))
+ .attr("text-anchor", "middle")
+ .text(!stacked ? attrs.node + " " + attrs.name : attrs.name);
+
+ var focus = sv.append("g")
+ .attr("class", "focus")
+ .style("display", "none");
+
+ focus.append("circle")
+ .attr("r", 4.5);
+
+ var focusg = focus.append("g");
+ focusg.append("rect")
+ .attr("class", "mo-guide y")
+ .attr("width", 1)
+ .attr("height", height - (margin.top + margin.bottom));
+ focusg.append("rect")
+ .attr("class", "mo-guide x")
+ .attr("width", width - (margin.left + margin.right))
+ .attr("height", 1);
+ focus.append("foreignObject")
+ .attr('class', 'svg-tooltip')
+ .append("xhtml:span");
+ /*
+ var transition = d3.select({}).transition()
+ .duration(2000)
+ .ease("linear");
+ */
+ function chart(selection) {
+ selection.each(function(data) {
+
+ var seriesArr = []
+ if (stacked) {
+ var detailNames = data[0][2].map(function(detail) {
+ return detail.node
+ })
+ var revNames = angular.copy(detailNames).reverse();
+ color.domain(revNames);
+
+ var series = {};
+ detailNames.forEach(function(name) {
+ series[name] = {
+ name: name,
+ values: []
+ };
+ seriesArr.unshift(series[name]); // insert at beginning
+ });
+
+ data.forEach(function(d) {
+ detailNames.map(function(name, i) {
+ series[name].values.push({
+ date: d[0],
+ value: d[2][i] ? d[2][i].val : 0
+ });
+ });
+ });
+
+ // this decorates seriesArr with x,y,and y0 properties
+ stack(seriesArr);
+ }
+
+ var extent = d3.extent(data, function(d) {
+ return d[0];
+ });
+ //var points = data.length;
+ //var futureDate = new Date(data[points-1][0].getTime() - attrs.visibleDuration * 60 * 1000);
+ //extent = [futureDate, data[points-1][0]]
+ x.domain(extent)
+ .range([0, width - margin.left - margin.right]);
+
+ // Update the y-scale.
+ var min = attrs.zoom ? 0 : d3.min(data, function(d) {
+ return d[1]
+ }) * .99;
+ var max = d3.max(data, function(d) {
+ return d[1]
+ }) * 1.01;
+ var mean = d3.mean(data, function(d) {
+ return d[1]
+ });
+ //max = max * 1.01;
+ var diff = (max - min);
+ if (diff == 0) {
+ max = max + 1;
+ diff = 1;
+ }
+ var ratio = mean != 0 ? diff / mean : 1;
+ if (ratio < .05)
+ formatValue = d3.format(".3s")
+
+ if (stacked) {
+ y.domain([min, max])
+ .range([height - margin.top - margin.bottom, 0]);
+ } else {
+ y
+ .domain([min, max])
+ .range([height - margin.top - margin.bottom, 0]);
+ }
+ if (attrs.type == "rate") {
+ area.interpolate("linear"); // rate charts look better smoothed, but the tooltop is in the wrong place
+ line.interpolate("linear");
+// area.interpolate("basis"); // rate charts look better smoothed
+// line.interpolate("basis");
+ } else {
+ area.interpolate("linear"); // don't smooth value charts
+ line.interpolate("linear");
+ }
+
+ // adjust the xaxis based on the range of x values (domain)
+ var timeSpan = (extent[1] - extent[0]) / (1000 * 60); // number of minutes
+ if (timeSpan < 1.5)
+ xAxis.ticks(d3.time.seconds, 10);
+ else if (timeSpan < 3)
+ xAxis.ticks(d3.time.seconds, 30);
+ else if (timeSpan < 8)
+ xAxis.ticks(d3.time.minutes, 1);
+ else
+ xAxis.ticks(d3.time.minutes, 2);
+
+ // adjust the number of yaxis ticks based on the range of y values
+ if (formatValue(min) === formatValue(max))
+ yAxis.ticks(2);
+
+ var container = svg.select('.section-container');
+ container.selectAll('.series').remove();
+ if (stacked) {
+ y.domain([Math.min(min, 0), d3.max(seriesArr, function(c) {
+ return d3.max(c.values, function(d) {
+ return d.y0 + d.y;
+ });
+ })]);
+
+ // creates a .series g path for each section in the detail
+ // since we don't get more sections this selection is only run once
+ var series = container.selectAll(".series")
+ .data(seriesArr)
+
+ series.enter().append("g")
+ .attr("class", "series")
+ .append("path")
+ .attr("class", "streamPath")
+ .style("fill", function(d) {
+ return color(d.name);
+ })
+ .style("stroke", "grey");
+
+ series.exit().remove()
+
+ // each time the data is updated, update each section
+ container.selectAll(".series .streamPath").data(seriesArr)
+ .attr("d", function(d) {
+ return area(d.values);
+ })
+ } else {
+ var series = container.selectAll(".series")
+ .data([data], function(d) {
+ return d;
+ })
+
+ var g = series.enter().append("g")
+ .attr("class", "series")
+
+ g.append("path")
+ .attr("class", "area")
+ .style("fill", "url(" + attrs.url + "#" + id + ") " + attrs.areaColor) //temperature-gradient)")
+ .attr("d", area.y0(y.range()[0]))
+ .attr("transform", null);
+
+ g.append("path")
+ .attr("class", "line")
+ .style("stroke", attrs.lineColor)
+ .attr("d", line)
+ /*
+ debugger;
+ g.transition()
+ .duration(2000)
+ .attr("transform", "translate(-4)");
+ */
+ series.exit().remove()
+
+ sv.selectAll("stop")
+ .attr("stop-color", attrs.areaColor)
+
+ }
+ // Update the x-axis.
+ svg.select(".x.axis")
+ .attr("transform", "translate(0," + (height - margin.top - margin.bottom + 1) + ")")
+ .call(xAxis);
+
+ svg.select(".y.axis")
+ .transition().duration(yAxisTransitionDuration) // animate the y axis
+ .attr("transform", "translate(" + (width - margin.right - margin.left) + ",0)")
+ .call(yAxis);
+ yAxisTransitionDuration = 1000 // only do a transition after the chart is 1st drawn
+
+ // TODO: fix this
+ // need to recreate this every update... not sure why
+ var overlay = sv.select(".overlay");
+ if (!overlay.empty())
+ overlay.remove();
+ sv.append("rect")
+ .attr("class", "overlay")
+ .attr("width", width)
+ .attr("height", height)
+ .on("mouseover", function() {
+ focus.style("display", null)
+ })
+ .on("mouseout", function() {
+ focus.style("display", "none")
+ })
+ .on("mousemove", mousemove)
+
+ function mousemove() {
+ var x0 = x.invert(d3.mouse(this)[0] - margin.left);
+ var i = bisectDate(data, x0, 1);
+ if (i < data.length && i > 0) {
+ var d0 = data[i - 1];
+ var d1 = data[i];
+ // set d to the data that is closest to the mouse position
+ var d = x0 - d0[0] > d1[0] - x0 ? d1 : d0;
+ focus.attr("transform", "translate(" + (x(d[0]) + margin.left) + "," + (y(d[1]) + margin.top) + ")");
+
+ var tipFormat = formatPrecise;
+ if (attrs.type === "rate")
+ tipFormat = d3.format(".2n")
+ // set the tooltip html and position it
+ focus.select('.svg-tooltip span')
+ .html(tooltipGenerator(d, color, tipFormat))
+
+ var foBounds = focus.select('table')[0][0].getBoundingClientRect();
+ var mx = x(d[0]); // mouse x
+ var my = y(d[1]); // mouse y
+
+ // perfer to put the tooltip in the nw corner relative to the focus circle
+ var foy = -foBounds.height;
+ var fox = -foBounds.width;
+ // off the left side
+ if (mx - foBounds.width - margin.left < 0)
+ fox = 0;
+ // above the top
+ if (my - foBounds.height - margin.top < 0)
+ foy = 0;
+ // won't fit above or below, just put it at bottom
+ if (my + foBounds.height > height)
+ foy = -(foBounds.height - (height - my));
+
+ focus.select('.svg-tooltip')
+ .attr('x', fox).attr('y', foy);
+
+ // position the guide lines
+ focus.select(".mo-guide.y")
+ .attr("y", -my);
+ focus.select(".mo-guide.x")
+ .attr("x", -mx);
+
+ } else {
+ focus.attr("transform", "translate(-10,-10)");
+ }
+ }
+
+ })
+ }
+ chart.attr = function(attrName, value) {
+ if (arguments.length < 2)
+ return arguments.length == 1 ? attrs[attrName] : chart;
+ if (angular.isDefined(attrs[attrName]))
+ attrs[attrName] = value;
+ return chart;
+ }
+ chart.tooltipGenerator = function(_) {
+ tooltipGenerator = _;
+ return chart;
+ }
+ return chart;
+ }
+ }
+ return self;
+ }
+ ]);
+
+ return QDR;
+}(QDR || {}));
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/55d7bd34/console/hawtio/src/main/webapp/plugin/js/qdrList.js
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrList.js b/console/hawtio/src/main/webapp/plugin/js/qdrList.js
index bb1a004..b39c37f 100644
--- a/console/hawtio/src/main/webapp/plugin/js/qdrList.js
+++ b/console/hawtio/src/main/webapp/plugin/js/qdrList.js
@@ -308,6 +308,11 @@ var QDR = (function(QDR) {
updateDetails(row) // update the table on the right
}
scrollTreeDiv.scrollTop(scrollTop)
+ $('.dynatree-title').each( function (idx) {
+ var unsafe = $(this).html()
+ $(this).html(unsafe.replace(/</g, "<").replace(/>/g, ">"))
+ })
+
}
var schemaProps = function (entityName, key, currentNode) {
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/55d7bd34/console/hawtio/src/main/webapp/plugin/js/qdrOverview.js
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrOverview.js b/console/hawtio/src/main/webapp/plugin/js/qdrOverview.js
index 065d5d1..4c0fbcf 100644
--- a/console/hawtio/src/main/webapp/plugin/js/qdrOverview.js
+++ b/console/hawtio/src/main/webapp/plugin/js/qdrOverview.js
@@ -1423,7 +1423,12 @@ QDR.log.debug("newly created node needs to be activated")
activated(newActive)
}
}
- }
+ $('.dynatree-title').each( function (idx) {
+ //QDR.log.info('found a title of ' + $(this).html())
+ var unsafe = $(this).html()
+ $(this).html(unsafe.replace(/</g, "<").replace(/>/g, ">"))
+ })
+ }
// get saved tree state
var lastKey = loadActivatedNode();
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/55d7bd34/console/hawtio/src/main/webapp/plugin/js/qdrSchema.js
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrSchema.js b/console/hawtio/src/main/webapp/plugin/js/qdrSchema.js
deleted file mode 120000
index 5010e61..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrSchema.js
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/js/qdrSchema.js
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrSchema.js b/console/hawtio/src/main/webapp/plugin/js/qdrSchema.js
new file mode 100644
index 0000000..7365d5a
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/js/qdrSchema.js
@@ -0,0 +1,81 @@
+/*
+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) {
+
+ QDR.module.controller("QDR.SchemaController", ['$scope', '$location', '$timeout', 'QDRService', function($scope, $location, $timeout, QDRService) {
+ if (!QDRService.connected) {
+ QDRService.redirectWhenConnected("schema")
+ return;
+ }
+ var onDisconnect = function () {
+ $timeout( function () {QDRService.redirectWhenConnected("schema")})
+ }
+ // we are currently connected. setup a handler to get notified if we are ever disconnected
+ QDRService.addDisconnectAction( onDisconnect )
+
+ var keys2kids = function (tree, obj) {
+ if (obj === Object(obj)) {
+ tree.children = []
+ var keys = Object.keys(obj).sort()
+ for (var i=0; i<keys.length; ++i) {
+ var key = keys[i];
+ var kid = {title: key}
+ if (obj[key] === Object(obj[key])) {
+ kid.isFolder = true
+ keys2kids(kid, obj[key])
+ } else {
+ kid.title += (': ' + JSON.stringify(obj[key],null,2))
+ }
+ tree.children.push(kid)
+ }
+ }
+ }
+
+ var tree = []
+ for (var key in QDRService.schema) {
+ var kid = {title: key}
+ kid.isFolder = true
+ var val = QDRService.schema[key]
+ if (val === Object(val))
+ keys2kids(kid, val)
+ else
+ kid.title += (': ' + JSON.stringify(val,null,2))
+
+ tree.push(kid);
+ }
+ $('#schema').dynatree({
+ minExpandLevel: 2,
+ classNames: {
+ expander: 'fa-angle',
+ connector: 'dynatree-no-connector'
+ },
+ children: tree
+ })
+
+ $scope.$on("$destroy", function(event) {
+ QDRService.delDisconnectAction( onDisconnect )
+ });
+
+ }]);
+
+ return QDR;
+}(QDR || {}));
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[3/4] qpid-dispatch git commit: DISPATCH-886 Account for / in router
name and prevent script injections
Posted by ea...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/55d7bd34/console/hawtio/src/main/webapp/plugin/js/qdrService.js
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrService.js b/console/hawtio/src/main/webapp/plugin/js/qdrService.js
deleted file mode 120000
index 2d2a672..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrService.js
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/js/qdrService.js
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrService.js b/console/hawtio/src/main/webapp/plugin/js/qdrService.js
new file mode 100644
index 0000000..73102a7
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/js/qdrService.js
@@ -0,0 +1,1232 @@
+/*
+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) {
+
+ // The QDR service handles the connection to
+ // the server in the background
+ QDR.module.factory("QDRService", ['$rootScope', '$http', '$timeout', '$resource', '$location', function($rootScope, $http, $timeout, $resource, $location) {
+ var self = {
+
+ rhea: require("rhea"),
+ timeout: 10, // seconds to wait before assuming a request has failed
+ updateInterval: 2000, // milliseconds between background updates
+ connectActions: [],
+ disconnectActions: [],
+ updatedActions: {},
+ updating: false, // are we updating the node list in the background
+ maxCorrelatorDepth: 10, // max number of outstanding requests to allow
+
+ /*
+ * @property message
+ * The proton message that is used to send commands
+ * and receive responses
+ */
+ sender: undefined,
+ receiver: undefined,
+ version: undefined,
+ sendable: false,
+
+ schema: undefined,
+
+ connected: false,
+ gotTopology: false,
+ errorText: undefined,
+ connectionError: undefined,
+
+ addConnectAction: function(action) {
+ if (angular.isFunction(action)) {
+ self.connectActions.push(action);
+ }
+ },
+ addDisconnectAction: function(action) {
+ if (angular.isFunction(action)) {
+ self.disconnectActions.push(action);
+ }
+ },
+ delDisconnectAction: function(action) {
+ if (angular.isFunction(action)) {
+ var index = self.disconnectActions.indexOf(action)
+ if (index >= 0)
+ self.disconnectActions.splice(index, 1)
+ }
+ },
+ addUpdatedAction: function(key, action) {
+ if (angular.isFunction(action)) {
+ self.updatedActions[key] = action;
+ }
+ },
+ delUpdatedAction: function(key) {
+ if (key in self.updatedActions)
+ delete self.updatedActions[key];
+ },
+
+ executeConnectActions: function() {
+ self.connectActions.forEach(function(action) {
+ try {
+ action.apply();
+ } catch (e) {
+ // in case the page that registered the handler has been unloaded
+ QDR.log.info(e.message)
+ }
+ });
+ self.connectActions = [];
+ },
+ executeDisconnectActions: function() {
+ self.disconnectActions.forEach(function(action) {
+ try {
+ action.apply();
+ } catch (e) {
+ // in case the page that registered the handler has been unloaded
+ }
+ });
+ self.disconnectActions = [];
+ },
+ executeUpdatedActions: function() {
+ for (action in self.updatedActions) {
+// try {
+ self.updatedActions[action].apply();
+/* } catch (e) {
+QDR.log.debug("caught error executing updated actions")
+console.dump(e)
+ delete self.updatedActions[action]
+ }
+ */
+ }
+ },
+ redirectWhenConnected: function(org) {
+ $location.path(QDR.pluginRoot + "/connect")
+ $location.search('org', org);
+ },
+
+ notifyTopologyDone: function() {
+ if (!self.gotTopology) {
+ QDR.log.debug("topology was just initialized");
+ //console.dump(self.topology._nodeInfo)
+ self.gotTopology = true;
+ //$rootScope.$apply();
+ } else {
+ //QDR.log.debug("topology model was just updated");
+ }
+ self.executeUpdatedActions();
+
+ },
+
+ isConnected: function() {
+ return self.connected;
+ },
+
+ versionCheck: function (minVer) {
+ var verparts = self.version.split('.')
+ var minparts = minVer.split('.')
+ try {
+ for (var i=0; i<minparts.length; ++i) {
+ if (parseInt(minVer[i] > parseInt(verparts[i])))
+ return false
+ }
+ } catch (e) {
+ QDR.log.debug("error doing version check between: " + self.version + " and " + minVer + " " + e.message)
+ return false
+ }
+ return true
+ },
+
+ correlator: {
+ _objects: {},
+ _correlationID: 0,
+
+ corr: function() {
+ var id = ++this._correlationID + "";
+ this._objects[id] = {
+ resolver: null
+ }
+ return id;
+ },
+ request: function() {
+ //QDR.log.debug("correlator:request");
+ return this;
+ },
+ then: function(id, resolver, error) {
+ //QDR.log.debug("registered then resolver for correlationID: " + id);
+ if (error) {
+ //QDR.log.debug("then received an error. deleting correlator")
+ delete this._objects[id];
+ return;
+ }
+ this._objects[id].resolver = resolver;
+ },
+ // called by receiver's on('message') handler when a response arrives
+ resolve: function(context) {
+ var correlationID = context.message.correlation_id;
+ this._objects[correlationID].resolver(context.message.body, context);
+ delete this._objects[correlationID];
+ },
+ depth: function () {
+ return Object.keys(this._objects).length
+ }
+ },
+
+ onSubscription: function() {
+ self.executeConnectActions();
+ var org = $location.search()
+ if (org)
+ org = org.org
+ if (org && org.length > 0 && org !== "connect") {
+ self.getSchema(function () {
+ self.setUpdateEntities([])
+ self.topology.get()
+ self.addUpdatedAction('onSub', function () {
+ self.delUpdatedAction('onSub')
+ $timeout( function () {
+ $location.path(QDR.pluginRoot + '/' + org)
+ $location.search('org', null)
+ $location.replace()
+ })
+ })
+ });
+ }
+ },
+
+ startUpdating: function() {
+ self.stopUpdating(true);
+ QDR.log.info("startUpdating called")
+ self.updating = true;
+ self.topology.get();
+ },
+ stopUpdating: function(silent) {
+ self.updating = false;
+ if (self.topology._getTimer) {
+ clearTimeout(self.topology._getTimer)
+ self.topology._getTimer = null;
+ }
+ if (self.topology._waitTimer) {
+ clearTimeout(self.topology._waitTimer)
+ self.topology._waitTimer = null;
+ }
+ if (self.topology._gettingTopo) {
+ if (self.topology.q)
+ self.topology.q.abort()
+ }
+ if (!silent)
+ QDR.log.info("stopUpdating called")
+ },
+
+ cleanUp: function() {},
+ error: function(line) {
+ if (line.num) {
+ QDR.log.debug("error - num: ", line.num, " message: ", line.message);
+ } else {
+ QDR.log.debug("error - message: ", line.message);
+ }
+ },
+ disconnected: function(line) {
+ QDR.log.debug("Disconnected from QDR server");
+ self.executeDisconnectActions();
+ },
+
+ nameFromId: function(id) {
+ // the router id looks like 'amqp:/topo/0/routerName/$managemrnt'
+ var parts = id.split('/')
+ // handle cases where the router name contains a /
+ parts.splice(0, 3) // remove amqp, topo, 0
+ parts.pop() // remove $management
+ return parts.join('/')
+ },
+
+ humanify: function(s) {
+ if (!s || s.length === 0)
+ return s;
+ var t = s.charAt(0).toUpperCase() + s.substr(1).replace(/[A-Z]/g, ' $&');
+ return t.replace(".", " ");
+ },
+ pretty: function(v) {
+ var formatComma = d3.format(",");
+ if (!isNaN(parseFloat(v)) && isFinite(v))
+ return formatComma(v);
+ return v;
+ },
+
+ nodeNameList: function() {
+ var nl = [];
+ for (var id in self.topology._nodeInfo) {
+ nl.push(self.nameFromId(id));
+ }
+ return nl.sort();
+ },
+
+ nodeIdList: function() {
+ var nl = [];
+ for (var id in self.topology._nodeInfo) {
+ nl.push(id);
+ }
+ return nl.sort();
+ },
+
+ nodeList: function() {
+ var nl = [];
+ for (var id in self.topology._nodeInfo) {
+ nl.push({
+ name: self.nameFromId(id),
+ id: id
+ });
+ }
+ return nl;
+ },
+
+ isLargeNetwork: function () {
+ return Object.keys(self.topology._nodeInfo).length >= 12
+ },
+ isMSIE: function () {
+ return (document.documentMode || /Edge/.test(navigator.userAgent))
+ },
+
+ // given an attribute name array, find the value at the same index in the values array
+ valFor: function(aAr, vAr, key) {
+ var idx = aAr.indexOf(key);
+ if ((idx > -1) && (idx < vAr.length)) {
+ return vAr[idx];
+ }
+ return null;
+ },
+
+ isArtemis: function(d) {
+ return (d.nodeType === 'route-container' || d.nodeType === 'on-demand') && (d.properties && d.properties.product === 'apache-activemq-artemis');
+ },
+
+ isQpid: function(d) {
+ return (d.nodeType === 'route-container' || d.nodeType === 'on-demand') && (d.properties && d.properties.product === 'qpid-cpp');
+ },
+
+ isAConsole: function(properties, connectionId, nodeType, key) {
+ return self.isConsole({
+ properties: properties,
+ connectionId: connectionId,
+ nodeType: nodeType,
+ key: key
+ })
+ },
+ isConsole: function(d) {
+ // use connection properties if available
+ return (d && d['properties'] && d['properties']['console_identifier'] === 'Dispatch console')
+ },
+
+ flatten: function(attributes, result) {
+ var flat = {}
+ attributes.forEach(function(attr, i) {
+ if (result && result.length > i)
+ flat[attr] = result[i]
+ })
+ return flat;
+ },
+ isConsoleLink: function(link) {
+ // find the connection for this link
+ var conns = self.topology.nodeInfo()[link.nodeId]['.connection']
+ var connIndex = conns.attributeNames.indexOf("identity")
+ var linkCons = conns.results.filter(function(conn) {
+ return conn[connIndex] === link.connectionId;
+ })
+ var conn = self.flatten(conns.attributeNames, linkCons[0]);
+
+ return self.isConsole(conn)
+ },
+
+ quiesceLink: function(nodeId, name) {
+ function gotMethodResponse(nodeName, entity, response, context) {
+ var statusCode = context.message.application_properties.statusCode;
+ if (statusCode < 200 || statusCode >= 300) {
+ Core.notification('error', context.message.statusDescription);
+ QDR.log.info('Error ' + context.message.statusDescription)
+ }
+ }
+ var attributes = {
+ adminStatus: 'disabled',
+ name: name
+ };
+ self.sendMethod(nodeId, "router.link", attributes, "UPDATE", undefined, gotMethodResponse)
+ },
+ addr_text: function(addr) {
+ if (!addr)
+ return "-"
+ if (addr[0] == 'M')
+ return addr.substring(2)
+ else
+ return addr.substring(1)
+ },
+ addr_class: function(addr) {
+ if (!addr) return "-"
+ if (addr[0] == 'M') return "mobile"
+ if (addr[0] == 'R') return "router"
+ if (addr[0] == 'A') return "area"
+ if (addr[0] == 'L') return "local"
+ if (addr[0] == 'C') return "link-incoming"
+ if (addr[0] == 'E') return "link-incoming"
+ if (addr[0] == 'D') return "link-outgoing"
+ if (addr[0] == 'F') return "link-outgoing"
+ if (addr[0] == 'T') return "topo"
+ return "unknown: " + addr[0]
+ },
+ identity_clean: function(identity) {
+ if (!identity)
+ return "-"
+ var pos = identity.indexOf('/')
+ if (pos >= 0)
+ return identity.substring(pos + 1)
+ return identity
+ },
+
+ queueDepth: function () {
+ var qdepth = self.maxCorrelatorDepth - self.correlator.depth()
+ if (qdepth <= 0)
+ qdepth = 1;
+//QDR.log.debug("queueDepth requested " + qdepth + "(" + self.correlator.depth() + ")")
+ return qdepth;
+ },
+ // check if all nodes have this entity. if not, get them
+ initEntity: function (entity, callback) {
+ var callNeeded = Object.keys(self.topology._nodeInfo).some( function (node) {
+ return !angular.isDefined(self.topology._nodeInfo[node][entity])
+ })
+ if (callNeeded) {
+ self.loadEntity(entity, callback)
+ } else
+ callback()
+ },
+
+ // get/refresh entities for all nodes
+ loadEntity: function (entities, callback) {
+ if (Object.prototype.toString.call(entities) !== '[object Array]') {
+ entities = [entities]
+ }
+ var q = QDR.queue(self.queueDepth())
+ for (node in self.topology._nodeInfo) {
+ for (var i=0; i<entities.length; ++i) {
+ var entity = entities[i]
+ q.defer(self.ensureNodeInfo, node, entity, [], q)
+ }
+ }
+ q.await(function (error) {
+ clearTimeout(self.topology._waitTimer)
+ callback();
+ })
+ },
+
+ // enusre all the topology nones have all these entities
+ ensureAllEntities: function (entityAttribs, callback, extra) {
+ self.ensureEntities(Object.keys(self.topology._nodeInfo), entityAttribs, callback, extra)
+ },
+
+ // ensure these nodes have all these entities. don't fetch unless forced to
+ ensureEntities: function (nodes, entityAttribs, callback, extra) {
+ if (Object.prototype.toString.call(entityAttribs) !== '[object Array]') {
+ entityAttribs = [entityAttribs]
+ }
+ if (Object.prototype.toString.call(nodes) !== '[object Array]') {
+ nodes = [nodes]
+ }
+ var q = QDR.queue(self.queueDepth())
+ for (var n=0; n<nodes.length; ++n) {
+ for (var i=0; i<entityAttribs.length; ++i) {
+ var ea = entityAttribs[i]
+ // if we don'e already have the entity or we want to force a refresh
+ if (!self.topology._nodeInfo[nodes[n]][ea.entity] || ea.force)
+ q.defer(self.ensureNodeInfo, nodes[n], ea.entity, ea.attrs || [], q)
+ }
+ }
+ q.await(function (error) {
+ clearTimeout(self.topology._waitTimer)
+ callback(extra);
+ })
+ },
+
+ // queue up a request to get certain attributes for one entity for a node and return the results
+ fetchEntity: function (node, entity, attrs, callback) {
+ var results = {}
+ var gotResponse = function (nodeName, dotentity, response) {
+ results = response
+ }
+ var q = QDR.queue(self.queueDepth())
+ q.defer(self.fetchNodeInfo, node, entity, attrs, q, gotResponse)
+ q.await(function (error) {
+ callback(node, entity, results)
+ })
+ },
+
+ // get/refreshes entities for all topology.nodes
+ // call doneCallback when all data is available
+ // optionally supply a resultCallBack that will be called as each result is avaialble
+ // if a resultCallBack is supplied, the calling function is responsible for accumulating the responses
+ // otherwise the responses will be returned to the doneCallback as an object
+ fetchAllEntities: function (entityAttribs, doneCallback, resultCallback) {
+ var q = QDR.queue(self.queueDepth())
+ var results = {}
+ if (!resultCallback) {
+ resultCallback = function (nodeName, dotentity, response) {
+ if (!results[nodeName])
+ results[nodeName] = {}
+ results[nodeName][dotentity] = angular.copy(response);
+ }
+ }
+ var gotAResponse = function (nodeName, dotentity, response) {
+ resultCallback(nodeName, dotentity, response)
+ }
+ if (Object.prototype.toString.call(entityAttribs) !== '[object Array]') {
+ entityAttribs = [entityAttribs]
+ }
+ var nodes = Object.keys(self.topology._nodeInfo)
+ for (var n=0; n<nodes.length; ++n) {
+ for (var i=0; i<entityAttribs.length; ++i) {
+ var ea = entityAttribs[i]
+ q.defer(self.fetchNodeInfo, nodes[n], ea.entity, ea.attrs || [], q, gotAResponse)
+ }
+ }
+ q.await(function (error) {
+ doneCallback(results);
+ })
+ },
+
+ setUpdateEntities: function (entities) {
+ self.topology._autoUpdatedEntities = entities
+ },
+ addUpdateEntity: function (entity) {
+ if (self.topology._autoUpdatedEntities.indexOf(entity) == -1)
+ self.topology._autoUpdatedEntities.push(entity)
+ },
+ delUpdateEntity: function (entity) {
+ var index = self.topology._autoUpdatedEntities.indexOf(entity)
+ if (index != -1)
+ self.topology._autoUpdatedEntities.splice(index, 1)
+ },
+
+ /*
+ * send the management messages that build up the topology
+ *
+ *
+ */
+ topology: {
+ _gettingTopo: false,
+ _nodeInfo: {},
+ _lastNodeInfo: {},
+ _waitTimer: null,
+ _getTimer: null,
+ _autoUpdatedEntities: [],
+ q: null,
+
+ nodeInfo: function() {
+ return self.topology._nodeInfo
+ },
+
+ get: function() {
+ if (self.topology._gettingTopo) {
+ QDR.log.debug("asked to get topology but was already getting it")
+ if (self.topology.q)
+ self.topology.q.abort()
+ }
+ self.topology.q = null
+ if (!self.connected) {
+ QDR.log.debug("topology get failed because !self.connected")
+ return;
+ }
+ if (self.topology._getTimer) {
+ clearTimeout(self.topology._getTimer)
+ self.topology._getTimer = null
+ }
+
+ //QDR.log.info("starting get topology with correlator.depth of " + self.correlator.depth())
+ self.topology._gettingTopo = true;
+ self.errorText = undefined;
+
+ // get the list of nodes to query.
+ // once this completes, we will get the info for each node returned
+ self.getRemoteNodeInfo(function(response, context) {
+ if (Object.prototype.toString.call(response) === '[object Array]') {
+ // remove dropped nodes
+ var keys = Object.keys(self.topology._nodeInfo)
+ for (var i=0; i<keys.length; ++i) {
+ if (response.indexOf(keys[i]) < 0) {
+ delete self.topology._nodeInfo[keys[i]]
+ }
+ }
+ // add any new nodes
+ // if there is only one node, it will not be returned
+ if (response.length === 0) {
+ var parts = self.receiver.remote.attach.source.address.split('/')
+ parts[parts.length-1] = '$management'
+ response.push(parts.join('/'))
+ //QDR.log.info("GET-MGMT-NODES returned an empty list. Using ")
+ //console.dump(response)
+ }
+ for (var i=0; i<response.length; ++i) {
+ if (!angular.isDefined(self.topology._nodeInfo[response[i]])) {
+ self.topology._nodeInfo[angular.copy(response[i])] = {};
+ }
+ }
+ // also refresh any entities that were requested
+ self.topology.q = QDR.queue(self.queueDepth())
+ for (var i=0; i<self.topology._autoUpdatedEntities.length; ++i) {
+ var entity = self.topology._autoUpdatedEntities[i]
+ //QDR.log.debug("queuing requests for all nodes for " + entity)
+ for (node in self.topology._nodeInfo) {
+ self.topology.q.defer(self.ensureNodeInfo, node, entity, [], self.topology.q)
+ }
+ }
+ self.topology.q.await(function (error) {
+ self.topology._gettingTopo = false;
+ self.topology.q = null
+ self.topology.ondone(error)
+ })
+ };
+ });
+ },
+
+ cleanUp: function(obj) {
+ if (obj)
+ delete obj;
+ },
+ timedOut: function(q) {
+ // a node dropped out. this happens when the get-mgmt-nodex
+ // results contains more nodes than actually respond within
+ // the timeout
+ QDR.log.debug("timed out waiting for management responses");
+ // note: can't use 'this' in a timeout handler
+ self.topology.miniDump("state at timeout");
+ q.abort()
+ //self.topology.onerror(Error("management responses are not consistent"));
+ },
+
+ addNodeInfo: function(id, entity, values, q) {
+ clearTimeout(self.topology._waitTimer)
+ // save the results in the nodeInfo object
+ if (id) {
+ if (!(id in self.topology._nodeInfo)) {
+ self.topology._nodeInfo[id] = {};
+ }
+ // copy the values to allow garbage collector to reclaim their memory
+ self.topology._nodeInfo[id][entity] = angular.copy(values)
+ }
+ self.topology.cleanUp(values);
+ },
+ ondone: function(waserror) {
+ clearTimeout(self.topology._getTimer);
+ clearTimeout(self.topology._waitTimer);
+ self.topology._waitTimer = null;
+ if (self.updating)
+ self.topology._getTimer = setTimeout(self.topology.get, self.updateInterval);
+ //if (!waserror)
+ self.notifyTopologyDone();
+ },
+ dump: function(prefix) {
+ if (prefix)
+ QDR.log.info(prefix);
+ QDR.log.info("---");
+ for (var key in self.topology._nodeInfo) {
+ QDR.log.info(key);
+ console.dump(self.topology._nodeInfo[key]);
+ QDR.log.info("---");
+ }
+ },
+ miniDump: function(prefix) {
+ if (prefix)
+ QDR.log.info(prefix);
+ QDR.log.info("---");
+ console.dump(Object.keys(self.topology._nodeInfo));
+ QDR.log.info("---");
+ },
+ onerror: function(err) {
+ self.topology._gettingTopo = false;
+ QDR.log.debug("Err:" + err);
+ //self.executeDisconnectActions();
+ }
+
+ },
+ getRemoteNodeInfo: function(callback) {
+ //QDR.log.debug("getRemoteNodeInfo called");
+
+ setTimeout(function () {
+ var ret;
+ // first get the list of remote node names
+ self.correlator.request(
+ ret = self.sendMgmtQuery('GET-MGMT-NODES')
+ ).then(ret.id, function(response, context) {
+ callback(response, context);
+ self.topology.cleanUp(response);
+ }, ret.error);
+ }, 1)
+ },
+
+ // sends a request and updates the topology.nodeInfo object with the response
+ // should only be called from a q.defer() statement
+ ensureNodeInfo: function (nodeId, entity, attrs, q, callback) {
+ //QDR.log.debug("queuing request for " + nodeId + " " + entity)
+ self.getNodeInfo(nodeId, entity, attrs, q, function (nodeName, dotentity, response) {
+ //QDR.log.debug("got response for " + nodeId + " " + entity)
+ self.topology.addNodeInfo(nodeName, dotentity, response, q)
+ callback(null)
+ })
+ return {
+ abort: function() {
+ delete self.topology._nodeInfo[nodeId]
+ //self.topology._nodeInfo[nodeId][entity] = {attributeNames: [], results: [[]]};
+ }
+ }
+ },
+
+ // sends request and returns the response
+ // should only be called from a q.defer() statement
+ fetchNodeInfo: function (nodeId, entity, attrs, q, heartbeat, callback) {
+ self.getNodeInfo(nodeId, entity, attrs, q, function (nodeName, dotentity, response) {
+ heartbeat(nodeName, dotentity, response)
+ callback(null)
+ })
+ },
+
+ getMultipleNodeInfo: function(nodeNames, entity, attrs, callback, selectedNodeId, aggregate) {
+ if (!angular.isDefined(aggregate))
+ aggregate = true;
+ var responses = {};
+ var gotNodesResult = function(nodeName, dotentity, response) {
+ responses[nodeName] = response;
+ }
+
+ var q = QDR.queue(self.queueDepth())
+ nodeNames.forEach(function(id) {
+ q.defer(self.fetchNodeInfo, id, '.' + entity, attrs, q, gotNodesResult)
+ })
+ q.await(function (error) {
+ if (aggregate)
+ self.aggregateNodeInfo(nodeNames, entity, selectedNodeId, responses, callback);
+ else {
+ callback(nodeNames, entity, responses)
+ }
+ })
+ },
+
+ aggregateNodeInfo: function(nodeNames, entity, selectedNodeId, responses, callback) {
+ //QDR.log.debug("got all results for " + entity);
+ // aggregate the responses
+ var newResponse = {};
+ var thisNode = responses[selectedNodeId];
+ newResponse['attributeNames'] = thisNode.attributeNames;
+ newResponse['results'] = thisNode.results;
+ newResponse['aggregates'] = [];
+ for (var i = 0; i < thisNode.results.length; ++i) {
+ var result = thisNode.results[i];
+ var vals = [];
+ result.forEach(function(val) {
+ vals.push({
+ sum: val,
+ detail: []
+ })
+ })
+ newResponse.aggregates.push(vals);
+ }
+ var nameIndex = thisNode.attributeNames.indexOf("name");
+ var ent = self.schema.entityTypes[entity];
+ var ids = Object.keys(responses);
+ ids.sort();
+ ids.forEach(function(id) {
+ var response = responses[id];
+ var results = response.results;
+ results.forEach(function(result) {
+ // find the matching result in the aggregates
+ var found = newResponse.aggregates.some(function(aggregate, j) {
+ if (aggregate[nameIndex].sum === result[nameIndex]) {
+ // result and aggregate are now the same record, add the graphable values
+ newResponse.attributeNames.forEach(function(key, i) {
+ if (ent.attributes[key] && ent.attributes[key].graph) {
+ if (id != selectedNodeId)
+ aggregate[i].sum += result[i];
+ }
+ aggregate[i].detail.push({
+ node: self.nameFromId(id) + ':',
+ val: result[i]
+ })
+ })
+ return true; // stop looping
+ }
+ return false; // continute looking for the aggregate record
+ })
+ if (!found) {
+ // this attribute was not found in the aggregates yet
+ // because it was not in the selectedNodeId's results
+ var vals = [];
+ result.forEach(function(val) {
+ vals.push({
+ sum: val,
+ detail: [{
+ node: self.nameFromId(id),
+ val: val
+ }]
+ })
+ })
+ newResponse.aggregates.push(vals)
+ }
+ })
+ })
+ callback(nodeNames, entity, newResponse);
+ },
+
+
+ getSchema: function(callback) {
+ //QDR.log.info("getting schema");
+ var ret;
+ self.correlator.request(
+ ret = self.sendMgmtQuery('GET-SCHEMA')
+ ).then(ret.id, function(response) {
+ //QDR.log.info("Got schema response");
+ // remove deprecated
+ for (var entityName in response.entityTypes) {
+ var entity = response.entityTypes[entityName]
+ if (entity.deprecated) {
+ // deprecated entity
+ delete response.entityTypes[entityName]
+ } else {
+ for (var attributeName in entity.attributes) {
+ var attribute = entity.attributes[attributeName]
+ if (attribute.deprecated) {
+ // deprecated attribute
+ delete response.entityTypes[entityName].attributes[attributeName]
+ }
+ }
+ }
+ }
+ self.schema = response;
+ callback()
+ }, ret.error);
+ },
+
+ getNodeInfo: function(nodeName, entity, attrs, q, callback) {
+ //QDR.log.debug("getNodeInfo called with nodeName: " + nodeName + " and entity " + entity);
+ var timedOut = function (q) {
+ q.abort()
+ }
+ var atimer = setTimeout(timedOut, self.timeout * 1000, q);
+ var ret;
+ self.correlator.request(
+ ret = self.sendQuery(nodeName, entity, attrs)
+ ).then(ret.id, function(response) {
+ clearTimeout(atimer)
+ callback(nodeName, entity, response);
+ }, ret.error);
+ },
+
+ sendMethod: function(nodeId, entity, attrs, operation, props, callback) {
+ setTimeout(function () {
+ var ret;
+ self.correlator.request(
+ ret = self._sendMethod(nodeId, entity, attrs, operation, props)
+ ).then(ret.id, function(response, context) {
+ callback(nodeId, entity, response, context);
+ }, ret.error);
+ }, 1)
+ },
+
+ _fullAddr: function(toAddr) {
+ var toAddrParts = toAddr.split('/');
+ if (toAddrParts.shift() != "amqp:") {
+ self.topology.error(Error("unexpected format for router address: " + toAddr));
+ return;
+ }
+ var fullAddr = toAddrParts.join('/');
+ return fullAddr;
+ },
+
+ _sendMethod: function(toAddr, entity, attrs, operation, props) {
+ var ret = {
+ id: self.correlator.corr()
+ };
+ var fullAddr = self._fullAddr(toAddr);
+ if (!self.sender || !self.sendable) {
+ ret.error = "no sender"
+ return ret;
+ }
+ try {
+ var application_properties = {
+ operation: operation
+ }
+ if (entity) {
+ var ent = self.schema.entityTypes[entity];
+ var fullyQualifiedType = ent ? ent.fullyQualifiedType : entity;
+ application_properties.type = fullyQualifiedType || entity;
+ }
+ if (attrs.name)
+ application_properties.name = attrs.name;
+ if (props) {
+ jQuery.extend(application_properties, props);
+ }
+ var msg = {
+ body: attrs,
+ to: fullAddr,
+ reply_to: self.receiver.remote.attach.source.address,
+ correlation_id: ret.id,
+ application_properties: application_properties
+ }
+ self.sender.send(msg);
+ //console.dump("------- method called -------")
+ //console.dump(msg)
+ } catch (e) {
+ error = "error sending: " + e;
+ QDR.log.error(error)
+ ret.error = error;
+ }
+ return ret;
+ },
+
+ sendQuery: function(toAddr, entity, attrs, operation) {
+ operation = operation || "QUERY"
+ var fullAddr = self._fullAddr(toAddr);
+
+ var body;
+ if (attrs) {
+ body = {
+ "attributeNames": attrs,
+ }
+ } else {
+ body = {
+ "attributeNames": [],
+ }
+ }
+ if (entity[0] === '.')
+ entity = entity.substr(1, entity.length - 1)
+ var prefix = "org.apache.qpid.dispatch."
+ var configs = ["address", "autoLink", "linkRoute"]
+ if (configs.indexOf(entity) > -1)
+ prefix += "router.config."
+ return self._send(body, fullAddr, operation, prefix + entity);
+ },
+
+ sendMgmtQuery: function(operation) {
+ return self._send([], "/$management", operation);
+ },
+
+ _send: function(body, to, operation, entityType) {
+ var ret = {
+ id: self.correlator.corr()
+ };
+ if (!self.sender || !self.sendable) {
+ ret.error = "no sender"
+ return ret;
+ }
+ try {
+ var application_properties = {
+ operation: operation,
+ type: "org.amqp.management",
+ name: "self"
+ };
+ if (entityType)
+ application_properties.entityType = entityType;
+
+ self.sender.send({
+ body: body,
+ to: to,
+ reply_to: self.receiver.remote.attach.source.address,
+ correlation_id: ret.id,
+ application_properties: application_properties
+ })
+ } catch (e) {
+ error = "error sending: " + e;
+ QDR.log.error(error)
+ ret.error = error;
+ }
+ return ret;
+ },
+
+ disconnect: function() {
+ self.connection.close();
+ self.connected = false
+ self.errorText = "Disconnected."
+ },
+
+ connectionTimer: null,
+
+ testConnect: function (options, timeout, callback) {
+ var connection;
+ var allowDelete = true;
+ var reconnect = angular.isDefined(options.reconnect) ? options.reconnect : false
+ var baseAddress = options.address + ':' + options.port;
+ var protocol = "ws"
+ if ($location.protocol() === "https")
+ protocol = "wss"
+ QDR.log.info("testConnect called with reconnect " + reconnect + " using " + protocol + " protocol")
+ try {
+ var ws = self.rhea.websocket_connect(WebSocket);
+ connection = self.rhea.connect({
+ connection_details: ws(protocol + "://" + baseAddress, ["binary"]),
+ reconnect: reconnect,
+ properties: {
+ console_identifier: 'Dispatch console'
+ }
+ }
+ );
+ } catch (e) {
+ QDR.log.debug("exception caught on test connect " + e)
+ self.errorText = "Connection failed "
+ callback({error: e})
+ return
+ }
+ // called when initial connecting fails, and when connection is dropped after connecting
+ connection.on('disconnected', function(context) {
+ if (allowDelete) {
+ delete connection
+ connection.options.reconnect = false
+ //QDR.log.info("connection.on(disconnected) called")
+ callback({error: "failed to connect"})
+ }
+ })
+ connection.on("connection_open", function (context) {
+ allowDelete = false;
+ callback({connection: connection, context: context})
+ })
+ },
+
+ connect: function(options) {
+ var connection;
+ self.topologyInitialized = false;
+ if (!self.connected) {
+ var okay = {
+ connection: false,
+ sender: false,
+ receiver: false
+ }
+ var sender, receiver
+ self.connectionError = undefined;
+
+ var stop = function(context) {
+ //self.stopUpdating();
+ okay.sender = false;
+ okay.receiver = false;
+ okay.connected = false;
+ self.connected = false;
+ self.sender = null;
+ self.receiver = null;
+ self.sendable = false;
+ self.gotTopology = false;
+ }
+ var maybeStart = function() {
+ if (okay.connection && okay.sender && okay.receiver && self.sendable && !self.connected) {
+ //QDR.log.info("okay to start")
+ self.connected = true;
+ self.connection = connection;
+ self.sender = sender;
+ self.receiver = receiver;
+ self.gotTopology = false;
+ self.onSubscription();
+ }
+ }
+ var onDisconnect = function() {
+ //QDR.log.warn("Disconnected");
+ self.connectionError = true;
+ stop();
+ self.executeDisconnectActions();
+ }
+
+ // called after connection.open event is fired or connection error has happened
+ var connectionCallback = function (options) {
+ //QDR.log.info('connectionCallback called')
+ if (!options.error) {
+ //QDR.log.info('there was no error')
+ connection = options.connection
+ self.version = options.context.connection.properties.version
+ QDR.log.debug("connection_opened")
+ okay.connection = true;
+ okay.receiver = false;
+ okay.sender = false;
+
+ connection.on('disconnected', function(context) {
+ //QDR.log.info("connection.on(disconnected) called")
+ self.errorText = "Unable to connect"
+ onDisconnect();
+ })
+ connection.on('connection_close', function(context) {
+ //QDR.log.info("connection closed")
+ self.errorText = "Disconnected"
+ onDisconnect();
+ })
+
+ sender = connection.open_sender();
+ sender.on('sender_open', function(context) {
+ //QDR.log.info("sender_opened")
+ okay.sender = true
+ maybeStart()
+ })
+ sender.on('sendable', function(context) {
+ //QDR.log.debug("sendable")
+ self.sendable = true;
+ maybeStart();
+ })
+
+ receiver = connection.open_receiver({
+ source: {
+ dynamic: true
+ }
+ });
+ receiver.on('receiver_open', function(context) {
+ //QDR.log.info("receiver_opened")
+ if (receiver.remote && receiver.remote.attach && receiver.remote.attach.source) {
+ okay.receiver = true;
+ maybeStart()
+ }
+ })
+ receiver.on("message", function(context) {
+ self.correlator.resolve(context);
+ });
+ } else {
+ //QDR.log.info("there was an error " + options.error)
+ self.errorText = "Unable to connect"
+ onDisconnect();
+ }
+ }
+
+ QDR.log.debug("****** calling rhea.connect ********")
+ if (!options.connection) {
+ QDR.log.debug("rhea.connect was not passed an existing connection")
+ options.reconnect = true
+ self.testConnect(options, 5000, connectionCallback)
+ } else {
+ QDR.log.debug("rhea.connect WAS passed an existing connection")
+ connectionCallback(options)
+ }
+ }
+ }
+ }
+ return self;
+ }]);
+
+ return QDR;
+
+}(QDR || {}));
+
+(function() {
+ console.dump = function(o) {
+ if (window.JSON && window.JSON.stringify)
+ QDR.log.info(JSON.stringify(o, undefined, 2));
+ else
+ console.log(o);
+ };
+})();
+
+function ngGridFlexibleHeightPlugin (opts) {
+ var self = this;
+ self.grid = null;
+ self.scope = null;
+ self.init = function (scope, grid, services) {
+ self.domUtilityService = services.DomUtilityService;
+ self.grid = grid;
+ self.scope = scope;
+ var recalcHeightForData = function () { setTimeout(innerRecalcForData, 1); };
+ var innerRecalcForData = function () {
+ var gridId = self.grid.gridId;
+ var footerPanelSel = '.' + gridId + ' .ngFooterPanel';
+ if (!self.grid.$topPanel || !self.grid.$canvas)
+ return;
+ var extraHeight = self.grid.$topPanel.height() + $(footerPanelSel).height();
+ var naturalHeight = self.grid.$canvas.height() + 1;
+ if (opts != null) {
+ if (opts.minHeight != null && (naturalHeight + extraHeight) < opts.minHeight) {
+ naturalHeight = opts.minHeight - extraHeight - 2;
+ }
+ if (opts.maxHeight != null && (naturalHeight + extraHeight) > opts.maxHeight) {
+ naturalHeight = opts.maxHeight;
+ }
+ }
+
+ var newViewportHeight = naturalHeight + 3;
+ if (!self.scope.baseViewportHeight || self.scope.baseViewportHeight !== newViewportHeight) {
+ self.grid.$viewport.css('height', newViewportHeight + 'px');
+ self.grid.$root.css('height', (newViewportHeight + extraHeight) + 'px');
+ self.scope.baseViewportHeight = newViewportHeight;
+ self.domUtilityService.RebuildGrid(self.scope, self.grid);
+ }
+ };
+ self.scope.catHashKeys = function () {
+ var hash = '',
+ idx;
+ for (idx in self.scope.renderedRows) {
+ hash += self.scope.renderedRows[idx].$$hashKey;
+ }
+ return hash;
+ };
+ self.scope.$watch('catHashKeys()', innerRecalcForData);
+ self.scope.$watch(self.grid.config.data, recalcHeightForData);
+ };
+}
+
+if (!String.prototype.startsWith) {
+ String.prototype.startsWith = function (searchString, position) {
+ return this.substr(position || 0, searchString.length) === searchString
+ }
+}
+
+if (!String.prototype.endsWith) {
+ String.prototype.endsWith = function(searchString, position) {
+ var subjectString = this.toString();
+ if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
+ position = subjectString.length;
+ }
+ position -= searchString.length;
+ var lastIndex = subjectString.lastIndexOf(searchString, position);
+ return lastIndex !== -1 && lastIndex === position;
+ };
+}
+
+// https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
+if (!Array.prototype.findIndex) {
+ Object.defineProperty(Array.prototype, 'findIndex', {
+ value: function(predicate) {
+ // 1. Let O be ? ToObject(this value).
+ if (this == null) {
+ throw new TypeError('"this" is null or not defined');
+ }
+
+ var o = Object(this);
+
+ // 2. Let len be ? ToLength(? Get(O, "length")).
+ var len = o.length >>> 0;
+
+ // 3. If IsCallable(predicate) is false, throw a TypeError exception.
+ if (typeof predicate !== 'function') {
+ throw new TypeError('predicate must be a function');
+ }
+
+ // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
+ var thisArg = arguments[1];
+
+ // 5. Let k be 0.
+ var k = 0;
+
+ // 6. Repeat, while k < len
+ while (k < len) {
+ // a. Let Pk be ! ToString(k).
+ // b. Let kValue be ? Get(O, Pk).
+ // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
+ // d. If testResult is true, return k.
+ var kValue = o[k];
+ if (predicate.call(thisArg, kValue, k, o)) {
+ return k;
+ }
+ // e. Increase k by 1.
+ k++;
+ }
+
+ // 7. Return -1.
+ return -1;
+ }
+ });
+}
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/55d7bd34/console/hawtio/src/main/webapp/plugin/js/qdrSettings.js
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrSettings.js b/console/hawtio/src/main/webapp/plugin/js/qdrSettings.js
deleted file mode 120000
index 6861eb2..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrSettings.js
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/js/qdrSettings.js
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrSettings.js b/console/hawtio/src/main/webapp/plugin/js/qdrSettings.js
new file mode 100644
index 0000000..3f0c109
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/js/qdrSettings.js
@@ -0,0 +1,188 @@
+/*
+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) {
+
+ /**
+ * @method SettingsController
+ * @param $scope
+ * @param QDRServer
+ *
+ * Controller that handles the QDR settings page
+ */
+
+ QDR.module.controller("QDR.SettingsController", ['$scope', 'QDRService', '$timeout', '$location', function($scope, QDRService, $timeout, $location) {
+
+ $scope.connecting = false;
+ $scope.connectionError = false;
+ $scope.connectionErrorText = undefined;
+ $scope.forms = {};
+
+ $scope.formEntity = angular.fromJson(localStorage[QDR.SETTINGS_KEY]) || {
+ address: '',
+ port: '',
+ username: '',
+ password: '',
+ autostart: false
+ };
+
+ $scope.$watch('formEntity', function(newValue, oldValue) {
+ if (newValue !== oldValue) {
+ localStorage[QDR.SETTINGS_KEY] = angular.toJson(newValue);
+ }
+ }, true);
+
+ $scope.buttonText = function() {
+ if (QDRService.isConnected()) {
+ return "Disconnect";
+ } else {
+ return "Connect";
+ }
+ };
+
+ $scope.connect = function() {
+ if (QDRService.connected) {
+ $timeout( function () {
+ QDRService.disconnect();
+ })
+ return;
+ }
+
+ if ($scope.settings.$valid) {
+ $scope.connectionError = false;
+ $scope.connecting = true;
+ // timeout so connecting animation can display
+ $timeout(function () {
+ doConnect()
+ })
+ }
+ }
+
+ var doConnect = function(opts) {
+ if (!$scope.formEntity.address)
+ $scope.formEntity.address = "localhost"
+ if (!$scope.formEntity.port)
+ $scope.formEntity.port = 5673
+
+ var failed = function() {
+ $timeout(function() {
+ QDR.log.debug("disconnect action called");
+ $scope.connecting = false;
+ $scope.connectionErrorText = QDRService.errorText;
+ $scope.connectionError = true;
+ })
+ }
+ QDRService.addDisconnectAction(failed);
+ QDRService.addConnectAction(function() {
+ QDRService.delDisconnectAction(failed)
+ QDRService.getSchema(function () {
+ QDR.log.info("got schema after connection")
+ QDRService.addUpdatedAction("initialized", function () {
+ QDRService.delUpdatedAction("initialized")
+ QDR.log.info("got initial topology")
+ $timeout(function() {
+ $scope.connecting = false;
+ if ($location.path().startsWith(QDR.pluginRoot)) {
+ var searchObject = $location.search();
+ var goto = "overview";
+ if (searchObject.org && searchObject.org !== "connect") {
+ goto = searchObject.org;
+ }
+ $location.search('org', null)
+ $location.path(QDR.pluginRoot + "/" + goto);
+ }
+ })
+ })
+ QDR.log.info("requesting a topology")
+ QDRService.setUpdateEntities([])
+ QDRService.topology.get()
+ })
+ });
+ var options = {address: $scope.formEntity.address, port: $scope.formEntity.port}
+ // if we have already successfully connected (the test connections succeeded)
+ if (opts && opts.connection) {
+ options.connection = opts.connection
+ options.context = opts.context
+ }
+ QDRService.connect(options);
+ }
+ }]);
+
+
+ QDR.module.directive('posint', function() {
+ return {
+ require: 'ngModel',
+
+ link: function(scope, elem, attr, ctrl) {
+ // input type number allows + and - but we don't want them so filter them out
+ elem.bind('keypress', function(event) {
+ var nkey = !event.charCode ? event.which : event.charCode;
+ var skey = String.fromCharCode(nkey);
+ var nono = "-+.,"
+ if (nono.indexOf(skey) >= 0) {
+ event.preventDefault();
+ return false;
+ }
+ // firefox doesn't filter out non-numeric input. it just sets the ctrl to invalid
+ if (/[\!\@\#\$\%^&*\(\)]/.test(skey) && event.shiftKey || // prevent shift numbers
+ !( // prevent all but the following
+ nkey <= 0 || // arrows
+ nkey == 8 || // delete|backspace
+ nkey == 13 || // enter
+ (nkey >= 37 && nkey <= 40) || // arrows
+ event.ctrlKey || event.altKey || // ctrl-v, etc.
+ /[0-9]/.test(skey)) // numbers
+ ) {
+ event.preventDefault();
+ return false;
+ }
+ })
+ // check the current value of input
+ var _isPortInvalid = function(value) {
+ var port = value + ''
+ var isErrRange = false;
+ // empty string is valid
+ if (port.length !== 0) {
+ var n = ~~Number(port);
+ if (n < 1 || n > 65535) {
+ isErrRange = true;
+ }
+ }
+ ctrl.$setValidity('range', !isErrRange)
+ return isErrRange;
+ }
+
+ //For DOM -> model validation
+ ctrl.$parsers.unshift(function(value) {
+ return _isPortInvalid(value) ? undefined : value;
+ });
+
+ //For model -> DOM validation
+ ctrl.$formatters.unshift(function(value) {
+ _isPortInvalid(value);
+ return value;
+ });
+ }
+ };
+ });
+
+ return QDR;
+}(QDR || {}));
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[2/4] qpid-dispatch git commit: DISPATCH-886 Account for / in router
name and prevent script injections
Posted by ea...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/55d7bd34/console/hawtio/src/main/webapp/plugin/lib/rhea-min.js
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/lib/rhea-min.js b/console/hawtio/src/main/webapp/plugin/lib/rhea-min.js
deleted file mode 120000
index 6203ad5..0000000
--- a/console/hawtio/src/main/webapp/plugin/lib/rhea-min.js
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/lib/rhea-min.js
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/lib/rhea-min.js b/console/hawtio/src/main/webapp/plugin/lib/rhea-min.js
new file mode 100644
index 0000000..13d8344
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/lib/rhea-min.js
@@ -0,0 +1,6 @@
+require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){(function(process,Buffer){"use strict";var errors=require("./errors.js");var frames=require("./frames.js");var log=require("./log.js");var sasl=require("./sasl.js");var util=require("./util.js");var EndpointState=require("./endpoint.js");var Session=require("./session.js");var Transport=require("./transport.js");var net=require("net");var tls=require("tls");var EventEmitter=require("events").EventEmitter;var AMQP_PROTOCOL_ID=0;function get_socket_id(socket){if(socket.get_id_string)return socket.get_id_stri
ng();return socket.localAddress+":"+socket.localPort+" -> "+socket.remoteAddress+":"+socket.remotePort}function session_per_connection(conn){var ssn=null;return{get_session:function(){if(!ssn){ssn=conn.create_session();ssn.begin()}return ssn}}}function restrict(count,f){if(count){var current=count;var reset;return function(successful_attempts){if(reset!==successful_attempts){current=count;reset=successful_attempts}if(current--)return f(successful_attempts);else return-1}}else{return f}}function backoff(initial,max){var delay=initial;var reset;return function(successful_attempts){if(reset!==successful_attempts){delay=initial;reset=successful_attempts}var current=delay;var next=delay*2;delay=max>next?next:max;return current}}function get_connect_fn(options){if(options.transport===undefined||options.transport==="tcp"){return net.connect}else if(options.transport==="tls"||options.transport==="ssl"){return tls.connect}else{throw Error("Unrecognised transport: "+options.transport)}}functi
on connection_details(options){var details={};details.connect=options.connect?options.connect:get_connect_fn(options);details.host=options.host?options.host:"localhost";details.port=options.port?options.port:5672;details.options=options;return details}var aliases=["container_id","hostname","max_frame_size","channel_max","idle_time_out","outgoing_locales","incoming_locales","offered_capabilities","desired_capabilities","properties"];function remote_property_shortcut(name){return function(){return this.remote.open?this.remote.open[name]:undefined}}var conn_counter=1;var Connection=function(options,container){this.options={};if(options){for(var k in options){this.options[k]=options[k]}if((options.transport==="tls"||options.transport==="ssl")&&options.servername===undefined&&options.host!==undefined){this.options.servername=options.host}}this.container=container;if(!this.options.id){this.options.id="connection-"+conn_counter++}if(!this.options.container_id){this.options.container_id=con
tainer?container.id:util.generate_uuid()}if(!this.options.connection_details){var self=this;this.options.connection_details=function(){return connection_details(self.options)}}var reconnect=this.get_option("reconnect",true);if(typeof reconnect==="boolean"&&reconnect){var initial=this.get_option("initial_reconnect_delay",100);var max=this.get_option("max_reconnect_delay",6e4);this.options.reconnect=restrict(this.get_option("reconnect_limit"),backoff(initial,max))}else if(typeof reconnect==="number"){var fixed=this.options.reconnect;this.options.reconnect=restrict(this.get_option("reconnect_limit"),function(){return fixed})}this.registered=false;this.state=new EndpointState;this.local_channel_map={};this.remote_channel_map={};this.local={};this.remote={};this.local.open=frames.open(this.options);this.local.close=frames.close({});this.session_policy=session_per_connection(this);this.amqp_transport=new Transport(this.options.id,AMQP_PROTOCOL_ID,frames.TYPE_AMQP,this);this.sasl_transport
=undefined;this.transport=this.amqp_transport;this.conn_established_counter=0;this.heartbeat_out=undefined;this.heartbeat_in=undefined;this.abort_idle=false;this.socket_ready=false;this.scheduled_reconnect=undefined;this.default_sender=undefined;for(var i in aliases){var f=aliases[i];Object.defineProperty(this,f,{get:remote_property_shortcut(f)})}Object.defineProperty(this,"error",{get:function(){return this.remote.close?this.remote.close.error:undefined}})};Connection.prototype=Object.create(EventEmitter.prototype);Connection.prototype.constructor=Connection;Connection.prototype.dispatch=function(name){log.events("Connection got event: %s",name);if(this.listeners(name).length){EventEmitter.prototype.emit.apply(this,arguments);return true}else if(this.container){return this.container.dispatch.apply(this.container,arguments)}else{return false}};Connection.prototype.reset=function(){if(this.abort_idle){this.abort_idle=false;this.local.close.error=undefined;this.state=new EndpointState
;this.state.open()}this.amqp_transport=new Transport(this.options.id,AMQP_PROTOCOL_ID,frames.TYPE_AMQP,this);this.sasl_transport=undefined;this.transport=this.amqp_transport;this.state.disconnected();this.remote={};this.remote_channel_map={};for(var k in this.local_channel_map){this.local_channel_map[k].reset()}this.socket_ready=false};Connection.prototype.connect=function(){this.is_server=false;this._connect(this.options.connection_details(this.conn_established_counter));this.open();return this};Connection.prototype.reconnect=function(){this.scheduled_reconnect=undefined;log.reconnect("reconnecting...");this.reset();this._connect(this.options.connection_details(this.conn_established_counter));process.nextTick(this._process.bind(this));return this};Connection.prototype._connect=function(details){if(details.connect){this.init(details.connect(details.port,details.host,details.options,this.connected.bind(this)))}else{this.init(get_connect_fn(details)(details.port,details.host,details.o
ptions,this.connected.bind(this)))}return this};Connection.prototype.accept=function(socket){this.is_server=true;log.io("[%s] client accepted: %s",this.id,get_socket_id(socket));this.socket_ready=true;return this.init(socket)};Connection.prototype.init=function(socket){this.socket=socket;if(this.get_option("tcp_no_delay",false)&&this.socket.setNoDelay){this.socket.setNoDelay(true)}this.socket.on("data",this.input.bind(this));this.socket.on("error",this.on_error.bind(this));this.socket.on("end",this.eof.bind(this));if(this.is_server){var mechs;if(this.container&&Object.getOwnPropertyNames(this.container.sasl_server_mechanisms).length){mechs=this.container.sasl_server_mechanisms}if(this.socket.encrypted&&this.socket.authorized&&this.get_option("enable_sasl_external",false)){mechs=sasl.server_add_external(mechs?util.clone(mechs):{})}if(mechs){if(mechs.ANONYMOUS!==undefined&&!this.get_option("require_sasl",false)){this.sasl_transport=new sasl.Selective(this,mechs)}else{this.sasl_transpo
rt=new sasl.Server(this,mechs)}}else{if(!this.get_option("disable_sasl",false)){var anon=sasl.server_mechanisms();anon.enable_anonymous();this.sasl_transport=new sasl.Selective(this,anon)}}}else{var mechanisms=this.get_option("sasl_mechanisms");if(!mechanisms){var username=this.get_option("username");var password=this.get_option("password");if(username){mechanisms=sasl.client_mechanisms();if(password)mechanisms.enable_plain(username,password);else mechanisms.enable_anonymous(username)}}if(this.socket.encrypted&&this.options.cert&&this.get_option("enable_sasl_external",false)){if(!mechanisms)mechanisms=sasl.client_mechanisms();mechanisms.enable_external()}if(mechanisms){this.sasl_transport=new sasl.Client(this,mechanisms,this.options.sasl_init_hostname||this.options.servername||this.options.host)}}this.transport=this.sasl_transport?this.sasl_transport:this.amqp_transport;return this};Connection.prototype.attach_sender=function(options){return this.session_policy.get_session().attach_
sender(options)};Connection.prototype.open_sender=Connection.prototype.attach_sender;Connection.prototype.attach_receiver=function(options){if(this.get_option("tcp_no_delay",true)&&this.socket.setNoDelay){this.socket.setNoDelay(true)}return this.session_policy.get_session().attach_receiver(options)};Connection.prototype.open_receiver=Connection.prototype.attach_receiver;Connection.prototype.get_option=function(name,default_value){if(this.options[name]!==undefined)return this.options[name];else if(this.container)return this.container.get_option(name,default_value);else return default_value};Connection.prototype.send=function(msg){if(this.default_sender===undefined){this.default_sender=this.open_sender({target:{}})}return this.default_sender.send(msg)};Connection.prototype.connected=function(){this.socket_ready=true;this.conn_established_counter++;log.io("[%s] connected %s",this.options.id,get_socket_id(this.socket));this.output()};Connection.prototype.sasl_failed=function(text){this.
transport_error={condition:"amqp:unauthorized-access",description:text};this._handle_error()};Connection.prototype._is_fatal=function(error_condition){var non_fatal=this.get_option("non_fatal_errors",["amqp:connection:forced"]);return non_fatal.indexOf(error_condition)<0};Connection.prototype._handle_error=function(){var error=this.get_error();if(error){var handled=this.dispatch("connection_error",this._context());handled=this.dispatch("connection_close",this._context())||handled;if(!this._is_fatal(error.condition)){this.open()}else if(!handled){this.dispatch("error",new errors.ConnectionError(error.description,error.condition,this))}return true}else{return false}};Connection.prototype.get_error=function(){if(this.transport_error)return this.transport_error;if(this.remote.close&&this.remote.close.error)return this.remote.close.error;return undefined};Connection.prototype._get_peer_details=function(){var s="";if(this.remote.open&&this.remote.open.container){s+=this.remote.open.contai
ner+" "}if(this.remote.open&&this.remote.open.properties){s+=JSON.stringify(this.remote.open.properties)}return s};Connection.prototype.output=function(){try{if(this.socket&&this.socket_ready){if(this.heartbeat_out)clearTimeout(this.heartbeat_out);this.transport.write(this.socket);if((this.is_closed()&&this.state.has_settled()||this.abort_idle||this.transport_error)&&!this.transport.has_writes_pending()){this.socket.end()}else if(this.is_open()&&this.remote.open.idle_time_out){this.heartbeat_out=setTimeout(this._write_frame.bind(this),this.remote.open.idle_time_out/2)}}}catch(e){if(e.name==="ProtocolError"){console.error("["+this.options.id+"] error on write: "+e+" "+this._get_peer_details()+" "+e.name);this.dispatch("protocol_error",e)||console.error("["+this.options.id+"] error on write: "+e+" "+this._get_peer_details())}else{this.dispatch("error",e)}this.socket.end()}};function byte_to_hex(value){if(value<16)return"0x0"+Number(value).toString(16);else return"0x"+Number(value).toS
tring(16)}function buffer_to_hex(buffer){var bytes=[];for(var i=0;i<buffer.length;i++){bytes.push(byte_to_hex(buffer[i]))}return bytes.join(",")}Connection.prototype.input=function(buff){var buffer;try{if(this.heartbeat_in)clearTimeout(this.heartbeat_in);log.io("[%s] read %d bytes",this.options.id,buff.length);if(this.previous_input){buffer=Buffer.concat([this.previous_input,buff],this.previous_input.length+buff.length);this.previous_input=null}else{buffer=buff}var read=this.transport.read(buffer,this);if(read<buffer.length){this.previous_input=buffer.slice(read)}if(this.local.open.idle_time_out)this.heartbeat_in=setTimeout(this.idle.bind(this),this.local.open.idle_time_out);if(this.transport.has_writes_pending()){this.output()}else if(this.is_closed()&&this.state.has_settled()){this.socket.end()}else if(this.is_open()&&this.remote.open.idle_time_out&&!this.heartbeat_out){this.heartbeat_out=setTimeout(this._write_frame.bind(this),this.remote.open.idle_time_out/2)}}catch(e){if(e.name
==="ProtocolError"){this.dispatch("protocol_error",e)||console.error("["+this.options.id+"] error on read: "+e+" "+this._get_peer_details()+" (buffer:"+buffer_to_hex(buffer)+")")}else{this.dispatch("error",e)}this.socket.end()}};Connection.prototype.idle=function(){if(this.is_open()){this.abort_idle=true;this.local.close.error={condition:"amqp:resource-limit-exceeded",description:"max idle time exceeded"};this.close()}};Connection.prototype.on_error=function(e){console.warn("["+this.options.id+"] error: "+e);this._disconnected()};Connection.prototype.eof=function(){this._disconnected()};Connection.prototype._disconnected=function(){if(this.heartbeat_out)clearTimeout(this.heartbeat_out);if(this.heartbeat_in)clearTimeout(this.heartbeat_in);if(!this.is_closed()&&this.scheduled_reconnect===undefined){if(!this.dispatch("disconnected",this._context())){console.warn("["+this.options.id+"] disconnected ")}if(!this.is_server&&!this.transport_error&&this.options.reconnect){var delay=this.opti
ons.reconnect(this.conn_established_counter);if(delay>=0){log.reconnect("Scheduled reconnect in "+delay+"ms");this.scheduled_reconnect=setTimeout(this.reconnect.bind(this),delay)}}}};Connection.prototype.open=function(){if(this.state.open()){this._register()}};Connection.prototype.close=function(error){if(error)this.local.close.error=error;if(this.state.close()){this._register()}};Connection.prototype.is_open=function(){return this.state.is_open()};Connection.prototype.is_closed=function(){return this.state.is_closed()};Connection.prototype.create_session=function(){var i=0;while(this.local_channel_map[i])i++;var session=new Session(this,i);this.local_channel_map[i]=session;return session};Connection.prototype.find_sender=function(filter){return this.find_link(util.sender_filter(filter))};Connection.prototype.find_receiver=function(filter){return this.find_link(util.receiver_filter(filter))};Connection.prototype.find_link=function(filter){for(var channel in this.local_channel_map){v
ar session=this.local_channel_map[channel];var result=session.find_link(filter);if(result)return result}return undefined};Connection.prototype.each_receiver=function(action,filter){this.each_link(util.receiver_filter(filter))};Connection.prototype.each_sender=function(action,filter){this.each_link(util.sender_filter(filter))};Connection.prototype.each_link=function(action,filter){for(var channel in this.local_channel_map){var session=this.local_channel_map[channel];session.each_link(action,filter)}};Connection.prototype.on_open=function(frame){if(this.state.remote_opened()){this.remote.open=frame.performative;this.open();this.dispatch("connection_open",this._context())}else{throw new errors.ProtocolError("Open already received")}};Connection.prototype.on_close=function(frame){if(this.state.remote_closed()){this.remote.close=frame.performative;this.close();if(this.remote.close.error){this._handle_error()}else{this.dispatch("connection_close",this._context())}if(this.heartbeat_out)cle
arTimeout(this.heartbeat_out)}else{throw new errors.ProtocolError("Close already received")}};Connection.prototype._register=function(){if(!this.registered){this.registered=true;process.nextTick(this._process.bind(this))}};Connection.prototype._process=function(){this.registered=false;do{if(this.state.need_open()){this._write_open()}for(var k in this.local_channel_map){this.local_channel_map[k]._process()}if(this.state.need_close()){this._write_close()}}while(!this.state.has_settled())};Connection.prototype._write_frame=function(channel,frame,payload){this.amqp_transport.encode(frames.amqp_frame(channel,frame,payload));this.output()};Connection.prototype._write_open=function(){this._write_frame(0,this.local.open.described())};Connection.prototype._write_close=function(){this._write_frame(0,this.local.close.described())};Connection.prototype.on_begin=function(frame){var session;if(frame.performative.remote_channel===null||frame.performative.remote_channel===undefined){session=this.cr
eate_session();session.local.begin.remote_channel=frame.channel}else{session=this.local_channel_map[frame.performative.remote_channel];if(!session)throw new errors.ProtocolError("Invalid value for remote channel "+frame.performative.remote_channel)}session.on_begin(frame);this.remote_channel_map[frame.channel]=session};Connection.prototype.get_peer_certificate=function(){if(this.socket&&this.socket.getPeerCertificate){return this.socket.getPeerCertificate()}else{return undefined}};Connection.prototype.get_tls_socket=function(){if(this.socket&&(this.options.transport==="tls"||this.options.transport==="ssl")){return this.socket}else{return undefined}};Connection.prototype._context=function(c){var context=c?c:{};context.connection=this;if(this.container)context.container=this.container;return context};function delegate_to_session(name){Connection.prototype["on_"+name]=function(frame){var session=this.remote_channel_map[frame.channel];if(!session){throw new errors.ProtocolError(name+" r
eceived on invalid channel "+frame.channel)}session["on_"+name](frame)}}delegate_to_session("end");delegate_to_session("attach");delegate_to_session("detach");delegate_to_session("transfer");delegate_to_session("disposition");delegate_to_session("flow");module.exports=Connection}).call(this,require("_process"),require("buffer").Buffer)},{"./endpoint.js":2,"./errors.js":3,"./frames.js":5,"./log.js":7,"./sasl.js":10,"./session.js":11,"./transport.js":13,"./util.js":15,_process:25,buffer:19,events:22,net:18,tls:18}],2:[function(require,module,exports){"use strict";var EndpointState=function(){this.init()};EndpointState.prototype.init=function(){this.local_open=false;this.remote_open=false;this.open_requests=0;this.close_requests=0;this.initialised=false};EndpointState.prototype.open=function(){this.initialised=true;if(!this.local_open){this.local_open=true;this.open_requests++;return true}else{return false}};EndpointState.prototype.close=function(){if(this.local_open){this.local_open=f
alse;this.close_requests++;return true}else{return false}};EndpointState.prototype.disconnected=function(){var was_open=this.local_open;this.init();if(was_open){this.open()}else{this.close()}};EndpointState.prototype.remote_opened=function(){if(!this.remote_open){this.remote_open=true;return true}else{return false}};EndpointState.prototype.remote_closed=function(){if(this.remote_open){this.remote_open=false;return true}else{return false}};EndpointState.prototype.is_open=function(){return this.local_open&&this.remote_open};EndpointState.prototype.is_closed=function(){return this.initialised&&!this.local_open&&!this.remote_open};EndpointState.prototype.has_settled=function(){return this.open_requests===0&&this.close_requests===0};EndpointState.prototype.need_open=function(){if(this.open_requests>0){this.open_requests--;return true}else{return false}};EndpointState.prototype.need_close=function(){if(this.close_requests>0){this.close_requests--;return true}else{return false}};module.exp
orts=EndpointState},{}],3:[function(require,module,exports){"use strict";var util=require("util");function ProtocolError(message){Error.call(this);this.message=message;this.name="ProtocolError"}util.inherits(ProtocolError,Error);function TypeError(message){ProtocolError.call(this,message);this.message=message;this.name="TypeError"}util.inherits(TypeError,ProtocolError);function ConnectionError(message,condition,connection){Error.call(this,message);this.message=message;this.name="ConnectionError";this.condition=condition;this.description=message;this.connection=connection}util.inherits(ConnectionError,Error);module.exports={ProtocolError:ProtocolError,TypeError:TypeError,ConnectionError:ConnectionError}},{util:34}],4:[function(require,module,exports){"use strict";var amqp_types=require("./types.js");module.exports={selector:function(s){return{"jms-selector":amqp_types.wrap_described(s,77567109365764)}}}},{"./types.js":14}],5:[function(require,module,exports){"use strict";var types=re
quire("./types.js");var errors=require("./errors.js");var frames={};var by_descriptor={};frames.read_header=function(buffer){var offset=4;var header={};var name=buffer.toString("ascii",0,offset);if(name!=="AMQP"){throw new errors.ProtocolError("Invalid protocol header for AMQP "+name)}header.protocol_id=buffer.readUInt8(offset++);header.major=buffer.readUInt8(offset++);header.minor=buffer.readUInt8(offset++);header.revision=buffer.readUInt8(offset++);if(header.protocol_id===0&&header.major===0&&header.minor===9&&header.revision===1){throw new errors.ProtocolError("Unsupported AMQP version: 0-9-1")}if(header.protocol_id===1&&header.major===1&&header.minor===0&&header.revision===10){throw new errors.ProtocolError("Unsupported AMQP version: 0-10")}if(header.major!==1||header.minor!==0){throw new errors.ProtocolError("Unsupported AMQP version: "+JSON.stringify(header))}return header};frames.write_header=function(buffer,header){var offset=4;buffer.write("AMQP",0,offset,"ascii");buffer.wr
iteUInt8(header.protocol_id,offset++);buffer.writeUInt8(header.major,offset++);buffer.writeUInt8(header.minor,offset++);buffer.writeUInt8(header.revision,offset++);return 8};frames.TYPE_AMQP=0;frames.TYPE_SASL=1;frames.read_frame=function(buffer){var reader=new types.Reader(buffer);var frame={};frame.size=reader.read_uint(4);if(reader.remaining<frame.size){return null}var doff=reader.read_uint(1);if(doff<2){throw new errors.ProtocolError("Invalid data offset, must be at least 2 was "+doff)}frame.type=reader.read_uint(1);if(frame.type===frames.TYPE_AMQP){frame.channel=reader.read_uint(2)}else if(frame.type===frames.TYPE_SASL){reader.skip(2)}else{throw new errors.ProtocolError("Unknown frame type "+frame.type)}if(doff>1){reader.skip(doff*4-8)}if(reader.remaining()){frame.performative=reader.read();var c=by_descriptor[frame.performative.descriptor.value];if(c){frame.performative=new c(frame.performative.value)}if(reader.remaining()){frame.payload=reader.read_bytes(reader.remaining())}}
return frame};frames.write_frame=function(frame){var writer=new types.Writer;writer.skip(4);writer.write_uint(2,1);writer.write_uint(frame.type,1);if(frame.type===frames.TYPE_AMQP){writer.write_uint(frame.channel,2)}else if(frame.type===frames.TYPE_SASL){writer.write_uint(0,2)}else{throw new errors.ProtocolError("Unknown frame type "+frame.type)}if(frame.performative){writer.write(frame.performative);if(frame.payload){writer.write_bytes(frame.payload)}}var buffer=writer.toBuffer();buffer.writeUInt32BE(buffer.length,0);return buffer};frames.amqp_frame=function(channel,performative,payload){return{channel:channel||0,type:frames.TYPE_AMQP,performative:performative,payload:payload}};frames.sasl_frame=function(performative){return{channel:0,type:frames.TYPE_SASL,performative:performative}};function define_frame(type,def){var c=types.define_composite(def);frames[def.name]=c.create;by_descriptor[Number(c.descriptor.numeric).toString(10)]=c;by_descriptor[c.descriptor.symbolic]=c}var open={n
ame:"open",code:16,fields:[{name:"container_id",type:"string",mandatory:true},{name:"hostname",type:"string"},{name:"max_frame_size",type:"uint",default_value:4294967295},{name:"channel_max",type:"ushort",default_value:65535},{name:"idle_time_out",type:"uint"},{name:"outgoing_locales",type:"symbol",multiple:true},{name:"incoming_locales",type:"symbol",multiple:true},{name:"offered_capabilities",type:"symbol",multiple:true},{name:"desired_capabilities",type:"symbol",multiple:true},{name:"properties",type:"symbolic_map"}]};var begin={name:"begin",code:17,fields:[{name:"remote_channel",type:"ushort"},{name:"next_outgoing_id",type:"uint",mandatory:true},{name:"incoming_window",type:"uint",mandatory:true},{name:"outgoing_window",type:"uint",mandatory:true},{name:"handle_max",type:"uint",default_value:"4294967295"},{name:"offered_capabilities",type:"symbol",multiple:true},{name:"desired_capabilities",type:"symbol",multiple:true},{name:"properties",type:"symbolic_map"}]};var attach={name:"
attach",code:18,fields:[{name:"name",type:"string",mandatory:true},{name:"handle",type:"uint",mandatory:true},{name:"role",type:"boolean",mandatory:true},{name:"snd_settle_mode",type:"ubyte",default_value:2},{name:"rcv_settle_mode",type:"ubyte",default_value:0},{name:"source",type:"*"},{name:"target",type:"*"},{name:"unsettled",type:"map"},{name:"incomplete_unsettled",type:"boolean",default_value:false},{name:"initial_delivery_count",type:"uint"},{name:"max_message_size",type:"ulong"},{name:"offered_capabilities",type:"symbol",multiple:true},{name:"desired_capabilities",type:"symbol",multiple:true},{name:"properties",type:"symbolic_map"}]};var flow={name:"flow",code:19,fields:[{name:"next_incoming_id",type:"uint"},{name:"incoming_window",type:"uint",mandatory:true},{name:"next_outgoing_id",type:"uint",mandatory:true},{name:"outgoing_window",type:"uint",mandatory:true},{name:"handle",type:"uint"},{name:"delivery_count",type:"uint"},{name:"link_credit",type:"uint"},{name:"available",t
ype:"uint"},{name:"drain",type:"boolean",default_value:false},{name:"echo",type:"boolean",default_value:false},{name:"properties",type:"symbolic_map"}]};var transfer={name:"transfer",code:20,fields:[{name:"handle",type:"uint",mandatory:true},{name:"delivery_id",type:"uint"},{name:"delivery_tag",type:"binary"},{name:"message_format",type:"uint"},{name:"settled",type:"boolean"},{name:"more",type:"boolean",default_value:false},{name:"rcv_settle_mode",type:"ubyte"},{name:"state",type:"delivery_state"},{name:"resume",type:"boolean",default_value:false},{name:"aborted",type:"boolean",default_value:false},{name:"batchable",type:"boolean",default_value:false}]};var disposition={name:"disposition",code:21,fields:[{name:"role",type:"boolean",mandatory:true},{name:"first",type:"uint",mandatory:true},{name:"last",type:"uint"},{name:"settled",type:"boolean",default_value:false},{name:"state",type:"*"},{name:"batchable",type:"boolean",default_value:false}]};var detach={name:"detach",code:22,field
s:[{name:"handle",type:"uint",mandatory:true},{name:"closed",type:"boolean",default_value:false},{name:"error",type:"error"}]};var end={name:"end",code:23,fields:[{name:"error",type:"error"}]};var close={name:"close",code:24,fields:[{name:"error",type:"error"}]};define_frame(frames.TYPE_AMQP,open);define_frame(frames.TYPE_AMQP,begin);define_frame(frames.TYPE_AMQP,attach);define_frame(frames.TYPE_AMQP,flow);define_frame(frames.TYPE_AMQP,transfer);define_frame(frames.TYPE_AMQP,disposition);define_frame(frames.TYPE_AMQP,detach);define_frame(frames.TYPE_AMQP,end);define_frame(frames.TYPE_AMQP,close);var sasl_mechanisms={name:"sasl_mechanisms",code:64,fields:[{name:"sasl_server_mechanisms",type:"symbol",multiple:true,mandatory:true}]};var sasl_init={name:"sasl_init",code:65,fields:[{name:"mechanism",type:"symbol",mandatory:true},{name:"initial_response",type:"binary"},{name:"hostname",type:"string"}]};var sasl_challenge={name:"sasl_challenge",code:66,fields:[{name:"challenge",type:"binar
y",mandatory:true}]};var sasl_response={name:"sasl_response",code:67,fields:[{name:"response",type:"binary",mandatory:true}]};var sasl_outcome={name:"sasl_outcome",code:68,fields:[{name:"code",type:"ubyte",mandatory:true},{name:"additional_data",type:"binary"}]};define_frame(frames.TYPE_SASL,sasl_mechanisms);define_frame(frames.TYPE_SASL,sasl_init);define_frame(frames.TYPE_SASL,sasl_challenge);define_frame(frames.TYPE_SASL,sasl_response);define_frame(frames.TYPE_SASL,sasl_outcome);module.exports=frames},{"./errors.js":3,"./types.js":14}],6:[function(require,module,exports){(function(Buffer){"use strict";var frames=require("./frames.js");var log=require("./log.js");var message=require("./message.js");var terminus=require("./terminus.js");var EndpointState=require("./endpoint.js");var FlowController=function(window){this.window=window};FlowController.prototype.update=function(context){var delta=this.window-context.receiver.credit;if(delta>=this.window/4){context.receiver.flow(delta)}}
;function auto_settle(context){context.delivery.settled=true}function auto_accept(context){context.delivery.update(undefined,message.accepted().described())}function LinkError(message,condition,link){Error.call(this);Error.captureStackTrace(this,this.constructor);this.message=message;this.condition=condition;this.description=message;this.link=link}require("util").inherits(LinkError,Error);var EventEmitter=require("events").EventEmitter;var link=Object.create(EventEmitter.prototype);link.dispatch=function(name){log.events("Link got event: %s",name);EventEmitter.prototype.emit.apply(this.observers,arguments);if(this.listeners(name).length){EventEmitter.prototype.emit.apply(this,arguments);return true}else{return this.session.dispatch.apply(this.session,arguments)}};link.set_source=function(fields){this.local.attach.source=terminus.source(fields).described()};link.set_target=function(fields){this.local.attach.target=terminus.target(fields).described()};link.attach=function(){if(this.st
ate.open()){this.connection._register()}};link.open=link.attach;link.detach=function(){this.local.detach.closed=false;if(this.state.close()){this.connection._register()}};link.close=function(error){if(error)this.local.detach.error=error;this.local.detach.closed=true;if(this.state.close()){this.connection._register()}};link.is_open=function(){return this.session.is_open()&&this.state.is_open()};link.is_closed=function(){return this.session.is_closed()||this.state.is_closed()};link._process=function(){do{if(this.state.need_open()){this.session.output(this.local.attach.described())}if(this.issue_flow){this.session._write_flow(this);this.issue_flow=false}if(this.state.need_close()){this.session.output(this.local.detach.described())}}while(!this.state.has_settled())};link.on_attach=function(frame){if(this.state.remote_opened()){if(!this.remote.handle){this.remote.handle=frame.handle}frame.performative.source=terminus.unwrap(frame.performative.source);frame.performative.target=terminus.un
wrap(frame.performative.target);this.remote.attach=frame.performative;this.open();this.dispatch(this.is_receiver()?"receiver_open":"sender_open",this._context())}else{throw Error("Attach already received")}};link.prefix_event=function(event){return(this.local.attach.role?"receiver_":"sender_")+event};link.on_detach=function(frame){if(this.state.remote_closed()){this.remote.detach=frame.performative;this.close();var error=this.remote.detach.error;if(error){var handled=this.dispatch(this.prefix_event("error"),this._context());handled=this.dispatch(this.prefix_event("close"),this._context())||handled;if(!handled){EventEmitter.prototype.emit.call(this.connection.container,"error",new LinkError(error.description,error.condition,this))}}else{this.dispatch(this.prefix_event("close"),this._context())}}else{throw Error("Detach already received")}};function is_internal(name){switch(name){case"name":case"handle":case"role":case"initial_delivery_count":return true;default:return false}}var alia
ses=["snd_settle_mode","rcv_settle_mode","source","target","max_message_size","offered_capabilities","desired_capabilities","properties"];function remote_property_shortcut(name){return function(){return this.remote.attach?this.remote.attach[name]:undefined}}link.init=function(session,name,local_handle,opts,is_receiver){this.session=session;this.connection=session.connection;this.name=name;this.options=opts===undefined?{}:opts;this.state=new EndpointState;this.issue_flow=false;this.local={handle:local_handle};this.local.attach=frames.attach({handle:local_handle,name:name,role:is_receiver});for(var field in this.local.attach){if(!is_internal(field)&&this.options[field]!==undefined){this.local.attach[field]=this.options[field]}}this.local.detach=frames.detach({handle:local_handle,closed:true});this.remote={handle:undefined};this.delivery_count=0;this.credit=0;this.observers=new EventEmitter;for(var i in aliases){var alias=aliases[i];Object.defineProperty(this,alias,{get:remote_property
_shortcut(alias)})}Object.defineProperty(this,"error",{get:function(){
+return this.remote.detach?this.remote.detach.error:undefined}})};link.reset=function(){this.state.disconnected();this.remote={handle:undefined};this.delivery_count=0;this.credit=0};link.has_credit=function(){return this.credit>0};link.is_receiver=function(){return this.local.attach.role};link.is_sender=function(){return!this.is_receiver()};link._context=function(c){var context=c?c:{};if(this.is_receiver()){context.receiver=this}else{context.sender=this}return this.session._context(context)};link.get_option=function(name,default_value){if(this.options[name]!==undefined)return this.options[name];else return this.session.get_option(name,default_value)};var Sender=function(session,name,local_handle,opts){this.init(session,name,local_handle,opts,false);this._draining=false;this._drained=false;this.local.attach.initial_delivery_count=0;this.tag=0;if(this.get_option("autosettle",true)){this.observers.on("settled",auto_settle)}var sender=this;if(this.get_option("treat_modified_as_released",
true)){this.observers.on("modified",function(context){sender.dispatch("released",context)})}};Sender.prototype=Object.create(link);Sender.prototype.constructor=Sender;Sender.prototype._get_drain=function(){if(this._draining&&this._drained&&this.credit){while(this.credit){++this.delivery_count;--this.credit}return true}else{return false}};Sender.prototype.set_drained=function(drained){this._drained=drained;if(this._draining&&this._drained){this.issue_flow=true}};Sender.prototype.next_tag=function(){return new Buffer(new String(this.tag++))};Sender.prototype.sendable=function(){return this.credit&&this.session.outgoing.available()};Sender.prototype.on_flow=function(frame){var flow=frame.performative;this.credit=flow.delivery_count+flow.link_credit-this.delivery_count;this._draining=flow.drain;this._drained=this.credit>0;if(this.is_open()){this.dispatch("sender_flow",this._context());if(this._draining){this.dispatch("sender_draining",this._context())}if(this.sendable()){this.dispatch("
sendable",this._context())}}};Sender.prototype.on_transfer=function(){throw Error("got transfer on sending link")};Sender.prototype.send=function(msg,tag){var delivery=this.session.send(this,tag?tag:this.next_tag(),message.encode(msg),0);if(this.local.attach.snd_settle_mode===1){delivery.settled=true}return delivery};var Receiver=function(session,name,local_handle,opts){this.init(session,name,local_handle,opts,true);this.drain=false;this.set_credit_window(this.get_option("credit_window",1e3));if(this.get_option("autoaccept",true)){this.observers.on("message",auto_accept)}};Receiver.prototype=Object.create(link);Receiver.prototype.constructor=Receiver;Receiver.prototype.on_flow=function(frame){this.dispatch("receiver_flow",this._context());if(frame.performative.drain){if(frame.performative.link_credit>0)console.error("ERROR: received flow with drain set, but non zero credit");else this.dispatch("receiver_drained",this._context())}};Receiver.prototype.flow=function(credit){if(credit>0
){this.credit+=credit;this.issue_flow=true;this.connection._register()}};Receiver.prototype.add_credit=Receiver.prototype.flow;Receiver.prototype._get_drain=function(){return this.drain};Receiver.prototype.set_credit_window=function(credit_window){if(credit_window>0){var flow_controller=new FlowController(credit_window);var listener=flow_controller.update.bind(flow_controller);this.observers.on("message",listener);this.observers.on("receiver_open",listener)}};module.exports={Sender:Sender,Receiver:Receiver}}).call(this,require("buffer").Buffer)},{"./endpoint.js":2,"./frames.js":5,"./log.js":7,"./message.js":8,"./terminus.js":12,buffer:19,events:22,util:34}],7:[function(require,module,exports){"use strict";var debug=require("debug");module.exports={frames:debug("rhea:frames"),raw:debug("rhea:raw"),reconnect:debug("rhea:reconnect"),events:debug("rhea:events"),message:debug("rhea:message"),flow:debug("rhea:flow"),io:debug("rhea:io")}},{debug:20}],8:[function(require,module,exports){"us
e strict";var log=require("./log.js");var types=require("./types.js");var by_descriptor={};var unwrappers={};var wrappers=[];var message={};function define_section(descriptor,unwrap,wrap){unwrap.descriptor=descriptor;unwrappers[descriptor.symbolic]=unwrap;unwrappers[Number(descriptor.numeric).toString(10)]=unwrap;if(wrap){wrappers.push(wrap)}}function define_composite_section(def){var c=types.define_composite(def);message[def.name]=c.create;by_descriptor[Number(c.descriptor.numeric).toString(10)]=c;by_descriptor[c.descriptor.symbolic]=c;var unwrap=function(msg,section){var composite=new c(section.value);for(var i=0;i<def.fields.length;i++){var f=def.fields[i];var v=composite[f.name];if(v!==undefined&&v!==null){msg[f.name]=v}}};var wrap=function(sections,msg){sections.push(c.create(msg).described())};define_section(c.descriptor,unwrap,wrap)}function define_map_section(def){var descriptor={numeric:def.code};descriptor.symbolic="amqp:"+def.name.replace(/_/g,"-")+":map";var unwrap=funct
ion(msg,section){msg[def.name]=types.unwrap_map_simple(section)};var wrap=function(sections,msg){if(msg[def.name]){sections.push(types.described_nc(types.wrap_ulong(descriptor.numeric),types.wrap_map(msg[def.name])))}};define_section(descriptor,unwrap,wrap)}function Section(typecode,content){this.typecode=typecode;this.content=content}Section.prototype.described=function(){return types.described(types.wrap_ulong(this.typecode),types.wrap(this.content))};define_composite_section({name:"header",code:112,fields:[{name:"durable",type:"boolean",default_value:false},{name:"priority",type:"ubyte",default_value:4},{name:"ttl",type:"uint"},{name:"first_acquirer",type:"boolean",default_value:false},{name:"delivery_count",type:"uint",default_value:0}]});define_map_section({name:"delivery_annotations",code:113});define_map_section({name:"message_annotations",code:114});define_composite_section({name:"properties",code:115,fields:[{name:"message_id",type:"message_id"},{name:"user_id",type:"binary
"},{name:"to",type:"string"},{name:"subject",type:"string"},{name:"reply_to",type:"string"},{name:"correlation_id",type:"message_id"},{name:"content_type",type:"symbol"},{name:"content_encoding",type:"symbol"},{name:"absolute_expiry_time",type:"timestamp"},{name:"creation_time",type:"timestamp"},{name:"group_id",type:"string"},{name:"group_sequence",type:"uint"},{name:"reply_to_group_id",type:"string"}]});define_map_section({name:"application_properties",code:116});define_section({numeric:117,symbolic:"amqp:data:binary"},function(msg,section){msg.body=new Section(117,types.unwrap(section))});define_section({numeric:118,symbolic:"amqp:amqp-sequence:list"},function(msg,section){msg.body=new Section(118,types.unwrap(section))});define_section({numeric:119,symbolic:"amqp:value:*"},function(msg,section){msg.body=types.unwrap(section)});define_map_section({name:"footer",code:120});function wrap_body(sections,msg){if(msg.body&&msg.body.constructor===Section){sections.push(msg.body.describe
d())}else{sections.push(types.described(types.wrap_ulong(119),types.wrap(msg.body)))}}wrappers.push(wrap_body);message.data_section=function(data){return new Section(117,data)};message.sequence_section=function(list){return new Section(118,list)};function copy(src,tgt){for(var k in src){var v=src[k];if(typeof v==="object"){copy(v,tgt[k])}else{tgt[k]=v}}}function Message(o){if(o){copy(o,this)}}Message.prototype.toJSON=function(){var o={};for(var key in this){if(typeof this[key]==="function")continue;o[key]=this[key]}return o};Message.prototype.inspect=function(){return JSON.stringify(this.toJSON())};Message.prototype.toString=function(){return JSON.stringify(this.toJSON())};message.encode=function(msg){var sections=[];wrappers.forEach(function(wrapper_fn){wrapper_fn(sections,msg)});var writer=new types.Writer;for(var i=0;i<sections.length;i++){log.message("Encoding section %d of %d: %o",i+1,sections.length,sections[i]);writer.write(sections[i])}var data=writer.toBuffer();log.message(
"encoded %d bytes",data.length);return data};message.decode=function(buffer){var msg=new Message;var reader=new types.Reader(buffer);while(reader.remaining()){var s=reader.read();log.message("decoding section: %o of type: %o",s,s.descriptor);if(s.descriptor){var unwrap=unwrappers[s.descriptor.value];if(unwrap){unwrap(msg,s)}else{console.warn("WARNING: did not recognise message section with descriptor "+s.descriptor)}}else{console.warn("WARNING: expected described message section got "+JSON.stringify(s))}}return msg};var outcomes={};function define_outcome(def){var c=types.define_composite(def);c.composite_type=def.name;message[def.name]=c.create;outcomes[Number(c.descriptor.numeric).toString(10)]=c;outcomes[c.descriptor.symbolic]=c;message["is_"+def.name]=function(o){if(o&&o.descriptor){var c=outcomes[o.descriptor.value];if(c){return c.descriptor.numeric===def.code}}return false}}message.unwrap_outcome=function(outcome){if(outcome&&outcome.descriptor){var c=outcomes[outcome.descript
or.value];if(c){return new c(outcome.value)}}console.error("unrecognised outcome: "+JSON.stringify(outcome));return outcome};message.are_outcomes_equivalent=function(a,b){if(a===undefined&&b===undefined)return true;else if(a===undefined||b===undefined)return false;else return a.descriptor.value===b.descriptor.value&&a.descriptor.value===36};define_outcome({name:"received",code:35,fields:[{name:"section_number",type:"uint",mandatory:true},{name:"section_offset",type:"ulong",mandatory:true}]});define_outcome({name:"accepted",code:36,fields:[]});define_outcome({name:"rejected",code:37,fields:[{name:"error",type:"error"}]});define_outcome({name:"released",code:38,fields:[]});define_outcome({name:"modified",code:39,fields:[{name:"delivery_failed",type:"boolean"},{name:"undeliverable_here",type:"boolean"},{name:"message_annotations",type:"map"}]});module.exports=message},{"./log.js":7,"./types.js":14}],9:[function(require,module,exports){"use strict";var url=require("url");var simple_id_g
enerator={counter:1,next:function(){return this.counter++}};var Client=function(container,address){var u=url.parse(address);this.connection=container.connect({host:u.hostname,port:u.port});this.connection.on("message",this._response.bind(this));this.connection.on("receiver_open",this._ready.bind(this));this.sender=this.connection.attach_sender(u.path.substr(1));this.receiver=this.connection.attach_receiver({source:{dynamic:true}});this.id_generator=simple_id_generator;this.pending=[];this.outstanding={}};Client.prototype._request=function(id,name,args,callback){var request={};request.subject=name;request.body=args;request.message_id=id;request.reply_to=this.receiver.remote.attach.source.address;this.outstanding[id]=callback;this.sender.send(request)};Client.prototype._response=function(context){var id=context.message.correlation_id;var callback=this.outstanding[id];if(callback){if(context.message.subject==="ok"){callback(context.message.body)}else{callback(undefined,{name:context.me
ssage.subject,description:context.message.body})}}else{console.error("no request pending for "+id+", ignoring response")}};Client.prototype._ready=function(){this._process_pending()};Client.prototype._process_pending=function(){for(var i=0;i<this.pending.length;i++){var r=this.pending[i];this._request(r.id,r.name,r.args,r.callback)}this.pending=[]};Client.prototype.call=function(name,args,callback){var id=this.id_generator.next();if(this.receiver.is_open()&&this.pending.length===0){this._request(id,name,args,callback)}else{this.pending.push({name:name,args:args,callback:callback,id:id})}};Client.prototype.close=function(){this.receiver.close();this.sender.close();this.connection.close()};Client.prototype.define=function(name){this[name]=function(args,callback){this.call(name,args,callback)}};var Cache=function(ttl,purged){this.ttl=ttl;this.purged=purged;this.entries={};this.timeout=undefined};Cache.prototype.clear=function(){if(this.timeout)clearTimeout(this.timeout);this.entries={}
};Cache.prototype.put=function(key,value){this.entries[key]={value:value,last_accessed:Date.now()};if(!this.timeout)this.timeout=setTimeout(this.purge.bind(this),this.ttl)};Cache.prototype.get=function(key){var entry=this.entries[key];if(entry){entry.last_accessed=Date.now();return entry.value}else{return undefined}};Cache.prototype.purge=function(){var now=Date.now();var expired=[];var live=0;for(var k in this.entries){if(now-this.entries[k].last_accessed>=this.ttl){expired.push(k)}else{live++}}for(var i=0;i<expired.length;i++){var entry=this.entries[expired[i]];delete this.entries[expired[i]];this.purged(entry.value)}if(live&&!this.timeout){this.timeout=setTimeout(this.purge.bind(this),this.ttl)}};var LinkCache=function(factory,ttl){this.factory=factory;this.cache=new Cache(ttl,function(link){link.close()})};LinkCache.prototype.clear=function(){this.cache.clear()};LinkCache.prototype.get=function(address){var link=this.cache.get(address);if(link===undefined){link=this.factory(addr
ess);this.cache.put(address,link)}return link};var Server=function(container,address,options){this.options=options||{};var u=url.parse(address);this.connection=container.connect({host:u.hostname,port:u.port});this.connection.on("connection_open",this._connection_open.bind(this));this.connection.on("message",this._request.bind(this));this.receiver=this.connection.attach_receiver(u.path.substr(1));this.callbacks={};this._send=undefined;this._clear=undefined};function match(desired,offered){if(offered){if(Array.isArray(offered)){return offered.indexOf(desired)>-1}else{return desired===offered}}else{return false}}Server.prototype._connection_open=function(){if(match("ANONYMOUS-RELAY",this.connection.remote.open.offered_capabilities)){var relay=this.connection.attach_sender({target:{}});this._send=function(msg){relay.send(msg)}}else{var cache=new LinkCache(this.connection.attach_sender.bind(this.connection),this.options.cache_ttl||6e4);this._send=function(msg){var s=cache.get(msg.to);if(
s)s.send(msg)};this._clear=function(){cache.clear()}}};Server.prototype._respond=function(response){var server=this;return function(result,error){if(error){response.subject=error.name||"error";response.body=error.description||error}else{response.subject="ok";response.body=result}server._send(response)}};Server.prototype._request=function(context){var request=context.message;var response={};response.to=request.reply_to;response.correlation_id=request.message_id;var callback=this.callbacks[request.subject];if(callback){callback(request.body,this._respond(response))}else{response.subject="bad-method";response.body="Unrecognised method "+request.subject;this._send(response)}};Server.prototype.bind_sync=function(f,name){this.callbacks[name||f.name]=function(args,callback){var result=f(args);callback(result)}};Server.prototype.bind=function(f,name){this.callbacks[name||f.name]=f};Server.prototype.close=function(){if(this._clear)this._clear();this.receiver.close();this.connection.close()};
module.exports={server:function(container,address,options){return new Server(container,address,options)},client:function(connection,address){return new Client(connection,address)}}},{url:30}],10:[function(require,module,exports){(function(Buffer){"use strict";var errors=require("./errors.js");var frames=require("./frames.js");var Transport=require("./transport.js");var sasl_codes={OK:0,AUTH:1,SYS:2,SYS_PERM:3,SYS_TEMP:4};var SASL_PROTOCOL_ID=3;function extract(buffer){var results=[];var start=0;var i=0;while(i<buffer.length){if(buffer[i]===0){if(i>start)results.push(buffer.toString("utf8",start,i));else results.push(null);start=++i}else{++i}}if(i>start)results.push(buffer.toString("utf8",start,i));else results.push(null);return results}var PlainServer=function(callback){this.callback=callback;this.outcome=undefined;this.username=undefined};PlainServer.prototype.start=function(response,hostname){var fields=extract(response);if(fields.length!==3){this.connection.sasl_failed("Unexpecte
d response in PLAIN, got "+fields.length+" fields, expected 3")}if(this.callback(fields[1],fields[2],hostname)){this.outcome=true;this.username=fields[1]}else{this.outcome=false}};var PlainClient=function(username,password){this.username=username;this.password=password};PlainClient.prototype.start=function(){var response=new Buffer(1+this.username.length+1+this.password.length);response.writeUInt8(0,0);response.write(this.username,1);response.writeUInt8(0,1+this.username.length);response.write(this.password,1+this.username.length+1);return response};var AnonymousServer=function(){this.outcome=undefined;this.username=undefined};AnonymousServer.prototype.start=function(response){this.outcome=true;this.username=response?response.toString("utf8"):"anonymous"};var AnonymousClient=function(name){this.username=name?name:"anonymous"};AnonymousClient.prototype.start=function(){var response=new Buffer(1+this.username.length);response.writeUInt8(0,0);response.write(this.username,1);return resp
onse};var ExternalServer=function(){this.outcome=undefined;this.username=undefined};ExternalServer.prototype.start=function(){this.outcome=true};var ExternalClient=function(){this.username=undefined};ExternalClient.prototype.start=function(){return""};ExternalClient.prototype.step=function(){return""};var SaslServer=function(connection,mechanisms){this.connection=connection;this.transport=new Transport(connection.amqp_transport.identifier,SASL_PROTOCOL_ID,frames.TYPE_SASL,this);this.next=connection.amqp_transport;this.mechanisms=mechanisms;this.mechanism=undefined;this.outcome=undefined;this.username=undefined;var mechlist=Object.getOwnPropertyNames(mechanisms);this.transport.encode(frames.sasl_frame(frames.sasl_mechanisms({sasl_server_mechanisms:mechlist}).described()))};SaslServer.prototype.do_step=function(challenge){if(this.mechanism.outcome===undefined){this.transport.encode(frames.sasl_frame(frames.sasl_challenge({challenge:challenge}).described()))}else{this.outcome=this.mech
anism.outcome?sasl_codes.OK:sasl_codes.AUTH;this.transport.encode(frames.sasl_frame(frames.sasl_outcome({code:this.outcome}).described()));if(this.outcome===sasl_codes.OK){this.username=this.mechanism.username;this.transport.write_complete=true;this.transport.read_complete=true}}};SaslServer.prototype.on_sasl_init=function(frame){var f=this.mechanisms[frame.performative.mechanism];if(f){this.mechanism=f();var challenge=this.mechanism.start(frame.performative.initial_response,frame.performative.hostname);this.do_step(challenge)}else{this.outcome=sasl_codes.AUTH;this.transport.encode(frames.sasl_frame(frames.sasl_outcome({code:this.outcome}).described()))}};SaslServer.prototype.on_sasl_response=function(frame){this.do_step(this.mechanism.step(frame.performative.response))};SaslServer.prototype.has_writes_pending=function(){return this.transport.has_writes_pending()||this.next.has_writes_pending()};SaslServer.prototype.write=function(socket){if(this.transport.write_complete&&this.trans
port.pending.length===0){return this.next.write(socket)}else{return this.transport.write(socket)}};SaslServer.prototype.read=function(buffer){if(this.transport.read_complete){return this.next.read(buffer)}else{return this.transport.read(buffer)}};var SaslClient=function(connection,mechanisms,hostname){this.connection=connection;this.transport=new Transport(connection.amqp_transport.identifier,SASL_PROTOCOL_ID,frames.TYPE_SASL,this);this.next=connection.amqp_transport;this.mechanisms=mechanisms;this.mechanism=undefined;this.mechanism_name=undefined;this.hostname=hostname;this.failed=false};SaslClient.prototype.on_sasl_mechanisms=function(frame){for(var i=0;this.mechanism===undefined&&i<frame.performative.sasl_server_mechanisms.length;i++){var mech=frame.performative.sasl_server_mechanisms[i];var f=this.mechanisms[mech];if(f){this.mechanism=f();this.mechanism_name=mech}}if(this.mechanism){var response=this.mechanism.start();var init={mechanism:this.mechanism_name,initial_response:resp
onse};if(this.hostname){init.hostname=this.hostname}this.transport.encode(frames.sasl_frame(frames.sasl_init(init).described()))}else{this.failed=true;this.connection.sasl_failed("No suitable mechanism; server supports "+frame.performative.sasl_server_mechanisms)}};SaslClient.prototype.on_sasl_challenge=function(frame){var response=this.mechanism.step(frame.performative.challenge);this.transport.encode(frames.sasl_frame(frames.sasl_response({response:response}).described()))};SaslClient.prototype.on_sasl_outcome=function(frame){switch(frame.performative.code){case sasl_codes.OK:this.transport.read_complete=true;this.transport.write_complete=true;break;default:this.transport.write_complete=true;this.connection.sasl_failed("Failed to authenticate: "+frame.performative.code)}};SaslClient.prototype.has_writes_pending=function(){return this.transport.has_writes_pending()||this.next.has_writes_pending()};SaslClient.prototype.write=function(socket){if(this.transport.write_complete){return
this.next.write(socket)}else{return this.transport.write(socket)}};SaslClient.prototype.read=function(buffer){if(this.transport.read_complete){return this.next.read(buffer)}else{return this.transport.read(buffer)}};var SelectiveServer=function(connection,mechanisms){this.header_received=false;this.transports={0:connection.amqp_transport,3:new SaslServer(connection,mechanisms)};this.selected=undefined};SelectiveServer.prototype.has_writes_pending=function(){return this.header_received&&this.selected.has_writes_pending()};SelectiveServer.prototype.write=function(socket){if(this.selected){return this.selected.write(socket)}else{return 0}};SelectiveServer.prototype.read=function(buffer){if(!this.header_received){if(buffer.length<8){return 0}else{this.header_received=frames.read_header(buffer);this.selected=this.transports[this.header_received.protocol_id];if(this.selected===undefined){throw new errors.ProtocolError("Invalid AMQP protocol id "+this.header_received.protocol_id)}}}return t
his.selected.read(buffer)};var default_server_mechanisms={enable_anonymous:function(){this["ANONYMOUS"]=function(){return new AnonymousServer}},enable_plain:function(callback){this["PLAIN"]=function(){return new PlainServer(callback)}}};var default_client_mechanisms={enable_anonymous:function(name){this["ANONYMOUS"]=function(){return new AnonymousClient(name)}},enable_plain:function(username,password){this["PLAIN"]=function(){return new PlainClient(username,password)}},enable_external:function(){this["EXTERNAL"]=function(){return new ExternalClient}}};module.exports={Client:SaslClient,Server:SaslServer,Selective:SelectiveServer,server_mechanisms:function(){return Object.create(default_server_mechanisms)},client_mechanisms:function(){return Object.create(default_client_mechanisms)},server_add_external:function(mechs){mechs["EXTERNAL"]=function(){return new ExternalServer};return mechs}}}).call(this,require("buffer").Buffer)},{"./errors.js":3,"./frames.js":5,"./transport.js":13,buffer
:19}],11:[function(require,module,exports){(function(Buffer){"use strict";var frames=require("./frames.js");var link=require("./link.js");var log=require("./log.js");var message=require("./message.js");var types=require("./types.js");var util=require("./util.js");var EndpointState=require("./endpoint.js");var EventEmitter=require("events").EventEmitter;var CircularBuffer=function(capacity){this.capacity=capacity;this.size=0;this.head=0;this.tail=0;this.entries=[]};CircularBuffer.prototype.available=function(){return this.capacity-this.size};CircularBuffer.prototype.push=function(o){if(this.size<this.capacity){this.entries[this.tail]=o;this.tail=(this.tail+1)%this.capacity;this.size++}else{throw Error("circular buffer overflow: head="+this.head+" tail="+this.tail+" size="+this.size+" capacity="+this.capacity)}};CircularBuffer.prototype.pop_if=function(f){var count=0;while(this.size&&f(this.entries[this.head])){this.entries[this.head]=undefined;this.head=(this.head+1)%this.capacity;th
is.size--;count++}return count};CircularBuffer.prototype.by_id=function(id){if(this.size>0){var gap=id-this.entries[this.head].id;if(gap<this.size){return this.entries[(this.head+gap)%this.capacity]}}return undefined};CircularBuffer.prototype.get_head=function(){return this.size>0?this.entries[this.head]:undefined};function write_dispositions(deliveries){var first,last,next_id,i,delivery;for(i=0;i<deliveries.length;i++){delivery=deliveries[i];if(first===undefined){first=delivery;last=delivery;next_id=delivery.id}if(!message.are_outcomes_equivalent(last.state,delivery.state)||last.settled!==delivery.settled||next_id!==delivery.id){first.link.session.output(frames.disposition({role:first.link.is_receiver(),first:first.id,last:last.id,state:first.state,settled:first.settled}).described());first=delivery;last=delivery;next_id=delivery.id}else{if(last.id!==delivery.id){last=delivery}next_id++}}if(first!==undefined&&last!==undefined){first.link.session.output(frames.disposition({role:firs
t.link.is_receiver(),first:first.id,last:last.id,state:first.state,settled:first.settled}).described())}}var Outgoing=function(){this.deliveries=new CircularBuffer(2048);this.updated=[];this.pending_dispositions=[];this.next_delivery_id=0;this.next_pending_delivery=0;this.next_transfer_id=0;this.window=types.MAX_UINT;this.remote_next_transfer_id=undefined;this.remote_window=undefined};Outgoing.prototype.available=function(){return this.deliveries.available()};Outgoing.prototype.send=function(sender,tag,data,format){var d={id:this.next_delivery_id++,tag:tag,link:sender,data:data,format:format?format:0,sent:false,settled:false,state:undefined,remote_settled:false,remote_state:undefined};var self=this;d.update=function(settled,state){self.update(d,settled,state)};this.deliveries.push(d);return d};Outgoing.prototype.on_begin=function(fields){this.remote_window=fields.incoming_window};Outgoing.prototype.on_flow=function(fields){this.remote_next_transfer_id=fields.next_incoming_id;this.re
mote_window=fields.incoming_window};Outgoing.prototype.on_disposition=function(fields){var last=fields.last?fields.last:fields.first;for(var i=fields.first;i<=last;i++){var d=this.deliveries.by_id(i);if(d&&!d.remote_settled){var updated=false;if(fields.settled){d.remote_settled=fields.settled;updated=true}if(fields.state&&fields.state!==d.remote_state){d.remote_state=message.unwrap_outcome(fields.state);updated=true}if(updated){this.updated.push(d)}}}};Outgoing.prototype.update=function(delivery,settled,state){if(delivery){delivery.settled=settled;if(state!==undefined)delivery.state=state;if(!delivery.remote_settled){this.pending_dispositions.push(delivery)}delivery.link.connection._register()}};Outgoing.prototype.transfer_window=function(){if(this.remote_window){return this.remote_window-(this.next_transfer_id-this.remote_next_transfer_id)}else{return 0}};Outgoing.prototype.process=function(){var d;while(this.next_pending_delivery<this.next_delivery_id){d=this.deliveries.by_id(this
.next_pending_delivery);if(d){if(d.link.has_credit()){d.link.delivery_count++;d.transfers_required=1;if(this.transfer_window()>=d.transfers_required){this.next_transfer_id+=d.transfers_required;this.window-=d.transfers_required;d.link.session.output(frames.transfer({handle:d.link.local.handle,message_format:d.format,delivery_id:d.id,delivery_tag:d.tag,settled:d.settled}).described(),d.data);d.link.credit--;this.next_pending_delivery++}else{log.flow("Incoming window of peer preventing sending further transfers: remote_window=%d, remote_next_transfer_id=%d, next_transfer_id=%d",this.remote_window,this.remote_next_transfer_id,this.next_transfer_id);break}}else{log.flow("Link has no credit");break}}else{console.error("ERROR: Next pending delivery not found: "+this.next_pending_delivery);break}}for(var i=0;i<this.updated.length;i++){d=this.updated[i];if(d.remote_state&&d.remote_state.constructor.composite_type){d.link.dispatch(d.remote_state.constructor.composite_type,d.link._context({de
livery:d}))}if(d.remote_settled)d.link.dispatch("settled",d.link._context({delivery:d}))}this.updated=[];if(this.pending_dispositions.length){write_dispositions(this.pending_dispositions);this.pending_dispositions=[]}this.deliveries.pop_if(function(d){return d.settled&&d.remote_settled})};var Incoming=function(){this.deliveries=new CircularBuffer(2048);this.updated=[];this.next_transfer_id=0;this.next_delivery_id=undefined;this.window=2048;this.remote_next_transfer_id=undefined;this.remote_window=undefined};Incoming.prototype.update=function(delivery,settled,state){if(delivery){delivery.settled=settled;if(state!==undefined)delivery.state=state;if(!delivery.remote_settled){this.updated.push(delivery)}delivery.link.connection._register()}};Incoming.prototype.on_transfer=function(frame,receiver){this.next_transfer_id++;if(receiver.is_open()){if(this.next_delivery_id===undefined){this.next_delivery_id=frame.performative.delivery_id}var current;var data;var last=this.deliveries.get_head(
);if(last&&last.incomplete){if(frame.performative.delivery_id!==undefined&&this.next_delivery_id!==frame.performative.delivery_id){throw Error("frame sequence error: delivery "+this.next_delivery_id+" not complete, got "+frame.performative.delivery_id)}current=last;data=Buffer.concat([current.data,frame.payload],current.data.length+frame.payload.length)}else if(this.next_delivery_id===frame.performative.delivery_id){current={id:frame.performative.delivery_id,tag:frame.performative.delivery_tag,link:receiver,settled:false,state:undefined,remote_settled:frame.performative.settled===undefined?false:frame.performative.settled,remote_state:frame.performative.state};var self=this;current.update=function(settled,state){var settled_=settled;if(settled_===undefined){settled_=receiver.local.attach.rcv_settle_mode!==1}self.update(current,settled_,state)};current.accept=function(){this.update(undefined,message.accepted().described())};current.release=function(params){if(params){this.update(unde
fined,message.modified(params).described())}else{this.update(undefined,message.released().described())}};current.reject=function(error){this.update(true,message.rejected({error:error}).described())};current.modified=function(params){this.update(true,message.modified(params).described())};this.deliveries.push(current);data=frame.payload}else{throw Error("frame sequence error: expected "+this.next_delivery_id+", got "+frame.performative.delivery_id)}current.incomplete=frame.performative.more;if(current.incomplete){current.data=data}else{receiver.credit--;receiver.delivery_count++;this.next_delivery_id++;receiver.dispatch("message",receiver._context({message:message.decode(data),delivery:current}))}}};Incoming.prototype.process=function(){if(this.updated.length>0){write_dispositions(this.updated);this.updated=[]}this.deliveries.pop_if(function(d){return d.settled})};Incoming.prototype.on_begin=function(fields){this.remote_window=fields.outgoing_window};Incoming.prototype.on_flow=functi
on(fields){this.remote_next_transfer_id=fields.next_outgoing_id;this.remote_window=fields.outgoing_window};Incoming.prototype.on_disposition=function(fields){var last=fields.last?fields.last:fields.first;for(var i=fields.first;i<=last;i++){var d=this.deliveries.by_id(i);if(d&&!d.remote_settled){if(fields.settled){d.remote_settled=fields.settled;d.link.dispatch("settled",d.link._context({delivery:d}))}}}};var Session=function(connection,local_channel){this.connection=connection;this.outgoing=new Outgoing;this.incoming=new Incoming;this.state=new EndpointState;this.local={channel:local_channel,handles:{}};this.local.begin=frames.begin({next_outgoing_id:this.outgoing.next_transfer_id,incoming_window:this.incoming.window,outgoing_window:this.outgoing.window});this.local.end=frames.end();this.remote={handles:{}};this.links={};this.options={}};Session.prototype=Object.create(EventEmitter.prototype);Session.prototype.constructor=Session;Session.prototype.reset=function(){this.state.disconn
ected();this.outgoing=new Outgoing;this.incoming=new Incoming;this.remote={handles:{}}
+;for(var l in this.links){this.links[l].reset()}};Session.prototype.dispatch=function(name){log.events("Session got event: %s",name);if(this.listeners(name).length){EventEmitter.prototype.emit.apply(this,arguments);return true}else{return this.connection.dispatch.apply(this.connection,arguments)}};Session.prototype.output=function(frame,payload){this.connection._write_frame(this.local.channel,frame,payload)};Session.prototype.create_sender=function(name,opts){return this.create_link(name,link.Sender,opts)};Session.prototype.create_receiver=function(name,opts){return this.create_link(name,link.Receiver,opts)};function attach(factory,args,remote_terminus){var opts=args?args:{};if(typeof args==="string"){opts={};opts[remote_terminus]=args}if(!opts.name)opts.name=util.generate_uuid();var l=factory(opts.name,opts);for(var t in{source:0,target:0}){if(opts[t]){if(typeof opts[t]==="string"){opts[t]={address:opts[t]}}l["set_"+t](opts[t])}}if(l.is_sender()&&opts.source===undefined){opts.sourc
e=l.set_source({})}if(l.is_receiver()&&opts.target===undefined){opts.target=l.set_target({})}l.attach();return l}Session.prototype.get_option=function(name,default_value){if(this.options[name]!==undefined)return this.options[name];else return this.connection.get_option(name,default_value)};Session.prototype.attach_sender=function(args){return attach(this.create_sender.bind(this),args,"target")};Session.prototype.open_sender=Session.prototype.attach_sender;Session.prototype.attach_receiver=function(args){return attach(this.create_receiver.bind(this),args,"source")};Session.prototype.open_receiver=Session.prototype.attach_receiver;Session.prototype.find_sender=function(filter){return this.find_link(util.sender_filter(filter))};Session.prototype.find_receiver=function(filter){return this.find_link(util.receiver_filter(filter))};Session.prototype.find_link=function(filter){for(var name in this.links){var link=this.links[name];if(filter(link))return link}return undefined};Session.prototy
pe.each_receiver=function(action,filter){this.each_link(util.receiver_filter(filter))};Session.prototype.each_sender=function(action,filter){this.each_link(util.sender_filter(filter))};Session.prototype.each_link=function(action,filter){for(var name in this.links){var link=this.links[name];if(filter===undefined||filter(link))action(link)}};Session.prototype.create_link=function(name,constructor,opts){var i=0;while(this.local.handles[i])i++;var l=new constructor(this,name,i,opts);this.links[name]=l;this.local.handles[i]=l;return l};Session.prototype.begin=function(){if(this.state.open()){this.connection._register()}};Session.prototype.open=Session.prototype.begin;Session.prototype.end=function(error){if(error)this.local.end.error=error;if(this.state.close()){this.connection._register()}};Session.prototype.close=Session.prototype.end;Session.prototype.is_open=function(){return this.connection.is_open()&&this.state.is_open()};Session.prototype.is_closed=function(){return this.connectio
n.is_closed()||this.state.is_closed()};Session.prototype._process=function(){do{if(this.state.need_open()){this.output(this.local.begin.described())}this.outgoing.process();this.incoming.process();for(var k in this.links){this.links[k]._process()}if(this.state.need_close()){this.output(this.local.end.described())}}while(!this.state.has_settled())};Session.prototype.send=function(sender,tag,data,format){var d=this.outgoing.send(sender,tag,data,format);this.connection._register();return d};Session.prototype._write_flow=function(link){var fields={next_incoming_id:this.incoming.next_transfer_id,incoming_window:this.incoming.window,next_outgoing_id:this.outgoing.next_transfer_id,outgoing_window:this.outgoing.window};if(link){if(link._get_drain())fields.drain=true;fields.delivery_count=link.delivery_count;fields.handle=link.local.handle;fields.link_credit=link.credit}this.output(frames.flow(fields).described())};Session.prototype.on_begin=function(frame){if(this.state.remote_opened()){if(
!this.remote.channel){this.remote.channel=frame.channel}this.remote.begin=frame.performative;this.outgoing.on_begin(frame.performative);this.incoming.on_begin(frame.performative);this.open();this.dispatch("session_open",this._context())}else{throw Error("Begin already received")}};Session.prototype.on_end=function(frame){if(this.state.remote_closed()){this.remote.end=frame.performative;this.close();this.dispatch("session_close",this._context())}else{throw Error("End already received")}};Session.prototype.on_attach=function(frame){var name=frame.performative.name;var link=this.links[name];if(!link){link=frame.performative.role?this.create_sender(name):this.create_receiver(name)}this.remote.handles[frame.performative.handle]=link;link.on_attach(frame);link.remote.attach=frame.performative};Session.prototype.on_disposition=function(frame){if(frame.performative.role){log.events("Received disposition for outgoing transfers");this.outgoing.on_disposition(frame.performative)}else{log.event
s("Received disposition for incoming transfers");this.incoming.on_disposition(frame.performative)}this.connection._register()};Session.prototype.on_flow=function(frame){this.outgoing.on_flow(frame.performative);this.incoming.on_flow(frame.performative);if(frame.performative.handle!==undefined){this._get_link(frame).on_flow(frame)}this.connection._register()};Session.prototype._context=function(c){var context=c?c:{};context.session=this;return this.connection._context(context)};Session.prototype._get_link=function(frame){var handle=frame.performative.handle;var link=this.remote.handles[handle];if(!link){throw Error("Invalid handle "+handle)}return link};Session.prototype.on_detach=function(frame){this._get_link(frame).on_detach(frame);var handle=frame.performative.handle;var link=this.remote.handles[handle];delete this.remote.handles[handle];delete this.local.handles[link.local.handle];delete this.links[link.name]};Session.prototype.on_transfer=function(frame){this.incoming.on_transf
er(frame,this._get_link(frame))};module.exports=Session}).call(this,require("buffer").Buffer)},{"./endpoint.js":2,"./frames.js":5,"./link.js":6,"./log.js":7,"./message.js":8,"./types.js":14,"./util.js":15,buffer:19,events:22}],12:[function(require,module,exports){"use strict";var types=require("./types.js");var terminus={};var by_descriptor={};function define_terminus(def){var c=types.define_composite(def);terminus[def.name]=c.create;by_descriptor[Number(c.descriptor.numeric).toString(10)]=c;by_descriptor[c.descriptor.symbolic]=c}terminus.unwrap=function(field){if(field&&field.descriptor){var c=by_descriptor[field.descriptor.value];if(c){return new c(field.value)}else{console.warn("Unknown terminus: "+field.descriptor)}}return null};define_terminus({name:"source",code:40,fields:[{name:"address",type:"string"},{name:"durable",type:"uint",default_value:0},{name:"expiry_policy",type:"symbol",default_value:"session-end"},{name:"timeout",type:"uint",default_value:0},{name:"dynamic",type:
"boolean",default_value:false},{name:"dynamic_node_properties",type:"symbolic_map"},{name:"distribution_mode",type:"symbol"},{name:"filter",type:"symbolic_map"},{name:"default_outcome",type:"*"},{name:"outcomes",type:"symbol",multiple:true},{name:"capabilities",type:"symbol",multiple:true}]});define_terminus({name:"target",code:41,fields:[{name:"address",type:"string"},{name:"durable",type:"uint",default_value:0},{name:"expiry_policy",type:"symbol",default_value:"session-end"},{name:"timeout",type:"uint",default_value:0},{name:"dynamic",type:"boolean",default_value:false},{name:"dynamic_node_properties",type:"symbolic_map"},{name:"capabilities",type:"symbol",multiple:true}]});module.exports=terminus},{"./types.js":14}],13:[function(require,module,exports){(function(Buffer){"use strict";var errors=require("./errors.js");var frames=require("./frames.js");var log=require("./log.js");var Transport=function(identifier,protocol_id,frame_type,handler){this.identifier=identifier;this.protoc
ol_id=protocol_id;this.frame_type=frame_type;this.handler=handler;this.pending=[];this.header_sent=undefined;this.header_received=undefined;this.write_complete=false;this.read_complete=false};Transport.prototype.has_writes_pending=function(){return this.pending.length>0};Transport.prototype.encode=function(frame){var buffer=frames.write_frame(frame);log.frames("[%s] PENDING: %o",this.identifier,JSON.stringify(frame));this.pending.push(buffer)};Transport.prototype.write=function(socket){if(!this.header_sent){var buffer=new Buffer(8);var header={protocol_id:this.protocol_id,major:1,minor:0,revision:0};frames.write_header(buffer,header);socket.write(buffer);this.header_sent=header}for(var i=0;i<this.pending.length;i++){socket.write(this.pending[i]);log.raw("[%s] SENT: %o",this.identifier,this.pending[i])}this.pending=[]};Transport.prototype.read=function(buffer){var offset=0;if(!this.header_received){if(buffer.length<8){return offset}else{this.header_received=frames.read_header(buffer)
;log.frames("[%s] RECV: %o",this.identifier,this.header_received);if(this.header_received.protocol_id!==this.protocol_id){if(this.protocol_id===3&&this.header_received.protocol_id===0){throw new errors.ProtocolError("Expecting SASL layer")}else if(this.protocol_id===0&&this.header_received.protocol_id===3){throw new errors.ProtocolError("SASL layer not enabled")}else{throw new errors.ProtocolError("Invalid AMQP protocol id "+this.header_received.protocol_id+" expecting: "+this.protocol_id)}}offset=8}}while(offset<buffer.length-4&&!this.read_complete){var frame_size=buffer.readUInt32BE(offset);log.io("[%s] got frame of size %d",this.identifier,frame_size);if(buffer.length<offset+frame_size){log.io("[%s] incomplete frame; have only %d of %d",this.identifier,buffer.length-offset,frame_size);break}else{var frame=frames.read_frame(buffer.slice(offset,offset+frame_size));log.frames("[%s] RECV: %o",this.identifier,JSON.stringify(frame));if(frame.type!==this.frame_type){throw new errors.Pro
tocolError("Invalid frame type: "+frame.type)}offset+=frame_size;if(frame.performative){frame.performative.dispatch(this.handler,frame)}}}return offset};module.exports=Transport}).call(this,require("buffer").Buffer)},{"./errors.js":3,"./frames.js":5,"./log.js":7,buffer:19}],14:[function(require,module,exports){(function(Buffer){"use strict";var errors=require("./errors.js");var CAT_FIXED=1;var CAT_VARIABLE=2;var CAT_COMPOUND=3;var CAT_ARRAY=4;function Typed(type,value,code,descriptor){this.type=type;this.value=value;if(code){this.array_constructor={typecode:code};if(descriptor){this.array_constructor.descriptor=descriptor}}}Typed.prototype.toString=function(){return this.value?this.value.toString():null};Typed.prototype.toLocaleString=function(){return this.value?this.value.toLocaleString():null};Typed.prototype.valueOf=function(){return this.value};Typed.prototype.toJSON=function(){return this.value&&this.value.toJSON?this.value.toJSON():this.value};function TypeDesc(name,typecode,
props,empty_value){this.name=name;this.typecode=typecode;var subcategory=typecode>>>4;switch(subcategory){case 4:this.width=0;this.category=CAT_FIXED;break;case 5:this.width=1;this.category=CAT_FIXED;break;case 6:this.width=2;this.category=CAT_FIXED;break;case 7:this.width=4;this.category=CAT_FIXED;break;case 8:this.width=8;this.category=CAT_FIXED;break;case 9:this.width=16;this.category=CAT_FIXED;break;case 10:this.width=1;this.category=CAT_VARIABLE;break;case 11:this.width=4;this.category=CAT_VARIABLE;break;case 12:this.width=1;this.category=CAT_COMPOUND;break;case 13:this.width=4;this.category=CAT_COMPOUND;break;case 14:this.width=1;this.category=CAT_ARRAY;break;case 15:this.width=4;this.category=CAT_ARRAY;break;default:break}if(props){if(props.read){this.read=props.read}if(props.write){this.write=props.write}if(props.encoding){this.encoding=props.encoding}}var t=this;if(subcategory===4){this.create=function(){return new Typed(t,empty_value)}}else if(subcategory===14||subcategory
===15){this.create=function(v,code,descriptor){return new Typed(t,v,code,descriptor)}}else{this.create=function(v){return new Typed(t,v)}}}TypeDesc.prototype.toString=function(){return this.name+"#"+hex(this.typecode)};function hex(i){return Number(i).toString(16)}var types={by_code:{}};Object.defineProperty(types,"MAX_UINT",{value:4294967295,writable:false,configurable:false});Object.defineProperty(types,"MAX_USHORT",{value:65535,writable:false,configurable:false});function define_type(name,typecode,annotations,empty_value){var t=new TypeDesc(name,typecode,annotations,empty_value);t.create.typecode=t.typecode;types.by_code[t.typecode]=t;types[name]=t.create}function buffer_uint8_ops(){return{read:function(buffer,offset){return buffer.readUInt8(offset)},write:function(buffer,value,offset){buffer.writeUInt8(value,offset)}}}function buffer_uint16be_ops(){return{read:function(buffer,offset){return buffer.readUInt16BE(offset)},write:function(buffer,value,offset){buffer.writeUInt16BE(val
ue,offset)}}}function buffer_uint32be_ops(){return{read:function(buffer,offset){return buffer.readUInt32BE(offset)},write:function(buffer,value,offset){buffer.writeUInt32BE(value,offset)}}}function buffer_int8_ops(){return{read:function(buffer,offset){return buffer.readInt8(offset)},write:function(buffer,value,offset){buffer.writeInt8(value,offset)}}}function buffer_int16be_ops(){return{read:function(buffer,offset){return buffer.readInt16BE(offset)},write:function(buffer,value,offset){buffer.writeInt16BE(value,offset)}}}function buffer_int32be_ops(){return{read:function(buffer,offset){return buffer.readInt32BE(offset)},write:function(buffer,value,offset){buffer.writeInt32BE(value,offset)}}}function buffer_floatbe_ops(){return{read:function(buffer,offset){return buffer.readFloatBE(offset)},write:function(buffer,value,offset){buffer.writeFloatBE(value,offset)}}}function buffer_doublebe_ops(){return{read:function(buffer,offset){return buffer.readDoubleBE(offset)},write:function(buffer,
value,offset){buffer.writeDoubleBE(value,offset)}}}var MAX_UINT=4294967296;var MIN_INT=-2147483647;function write_ulong(buffer,value,offset){if(typeof value==="number"||value instanceof Number){var hi=Math.floor(value/MAX_UINT);var lo=value%MAX_UINT;buffer.writeUInt32BE(hi,offset);buffer.writeUInt32BE(lo,offset+4)}else{value.copy(buffer,offset)}}function read_ulong(buffer,offset){var hi=buffer.readUInt32BE(offset);var lo=buffer.readUInt32BE(offset+4);if(hi<2097153){return hi*MAX_UINT+lo}else{return buffer.slice(offset,offset+8)}}function write_long(buffer,value,offset){if(typeof value==="number"||value instanceof Number){var abs=Math.abs(value);var hi=Math.floor(abs/MAX_UINT);var lo=abs%MAX_UINT;buffer.writeInt32BE(hi,offset);buffer.writeUInt32BE(lo,offset+4);if(value<0){var carry=1;for(var i=0;i<8;i++){var index=offset+(7-i);var v=(buffer[index]^255)+carry;buffer[index]=v&255;carry=v>>8}}}else{value.copy(buffer,offset)}}function read_long(buffer,offset){var hi=buffer.readInt32BE(of
fset);var lo=buffer.readUInt32BE(offset+4);if(hi<2097153&&hi>-2097153){return hi*MAX_UINT+lo}else{return buffer.slice(offset,offset+8)}}define_type("Null",64,undefined,null);define_type("Boolean",86,buffer_uint8_ops());define_type("True",65,undefined,true);define_type("False",66,undefined,false);define_type("Ubyte",80,buffer_uint8_ops());define_type("Ushort",96,buffer_uint16be_ops());define_type("Uint",112,buffer_uint32be_ops());define_type("SmallUint",82,buffer_uint8_ops());define_type("Uint0",67,undefined,0);define_type("Ulong",128,{write:write_ulong,read:read_ulong});define_type("SmallUlong",83,buffer_uint8_ops());define_type("Ulong0",68,undefined,0);define_type("Byte",81,buffer_int8_ops());define_type("Short",97,buffer_int16be_ops());define_type("Int",113,buffer_int32be_ops());define_type("SmallInt",84,buffer_int8_ops());define_type("Long",129,{write:write_long,read:read_long});define_type("SmallLong",85,buffer_int8_ops());define_type("Float",114,buffer_floatbe_ops());define_typ
e("Double",130,buffer_doublebe_ops());define_type("Decimal32",116);define_type("Decimal64",132);define_type("Decimal128",148);define_type("CharUTF32",115,buffer_uint32be_ops());define_type("Timestamp",131,{write:write_long,read:read_long});define_type("Uuid",152);define_type("Vbin8",160);define_type("Vbin32",176);define_type("Str8",161,{encoding:"utf8"});define_type("Str32",177,{encoding:"utf8"});define_type("Sym8",163,{encoding:"ascii"});define_type("Sym32",179,{encoding:"ascii"});define_type("List0",69,undefined,[]);define_type("List8",192);define_type("List32",208);define_type("Map8",193);define_type("Map32",209);define_type("Array8",224);define_type("Array32",240);function is_one_of(o,typelist){for(var i=0;i<typelist.length;i++){if(o.type.typecode===typelist[i].typecode)return true}return false}function buffer_zero(b,len,neg){for(var i=0;i<len&&i<b.length;i++){if(b[i]!==(neg?255:0))return false}return true}types.is_ulong=function(o){return is_one_of(o,[types.Ulong,types.Ulong0,t
ypes.SmallUlong])};types.is_string=function(o){return is_one_of(o,[types.Str8,types.Str32])};types.is_symbol=function(o){return is_one_of(o,[types.Sym8,types.Sym32])};types.is_list=function(o){return is_one_of(o,[types.List0,types.List8,types.List32])};types.is_map=function(o){return is_one_of(o,[types.Map8,types.Map32])};types.wrap_boolean=function(v){return v?types.True():types.False()};types.wrap_ulong=function(l){if(Buffer.isBuffer(l)){if(buffer_zero(l,8,false))return types.Ulong0();return buffer_zero(l,7,false)?types.SmallUlong(l[7]):types.Ulong(l)}else{if(l===0)return types.Ulong0();else return l>255?types.Ulong(l):types.SmallUlong(l)}};types.wrap_uint=function(l){if(l===0)return types.Uint0();else return l>255?types.Uint(l):types.SmallUint(l)};types.wrap_ushort=function(l){return types.Ushort(l)};types.wrap_ubyte=function(l){return types.Ubyte(l)};types.wrap_long=function(l){if(Buffer.isBuffer(l)){var negFlag=(l[0]&128)!==0;if(buffer_zero(l,7,negFlag)&&(l[7]&128)===(negFlag?1
28:0)){return types.SmallLong(negFlag?-((l[7]^255)+1):l[7])}return types.Long(l)}else{return l>127||l<-128?types.Long(l):types.SmallLong(l)}};types.wrap_int=function(l){return l>127||l<-128?types.Int(l):types.SmallInt(l)};types.wrap_short=function(l){return types.Short(l)};types.wrap_byte=function(l){return types.Byte(l)};types.wrap_float=function(l){return types.Float(l)};types.wrap_double=function(l){return types.Double(l)};types.wrap_timestamp=function(l){return types.Timestamp(l)};types.wrap_char=function(v){return types.CharUTF32(v)};types.wrap_uuid=function(v){return types.Uuid(v)};types.wrap_binary=function(s){return s.length>255?types.Vbin32(s):types.Vbin8(s)};types.wrap_string=function(s){return s.length>255?types.Str32(s):types.Str8(s)};types.wrap_symbol=function(s){return s.length>255?types.Sym32(s):types.Sym8(s)};types.wrap_list=function(l){if(l.length===0)return types.List0();var items=l.map(types.wrap);return types.List32(items)};types.wrap_map=function(m,key_wrapper){
var items=[];for(var k in m){items.push(key_wrapper?key_wrapper(k):types.wrap(k));items.push(types.wrap(m[k]))}return types.Map32(items)};types.wrap_symbolic_map=function(m){return types.wrap_map(m,types.wrap_symbol)};types.wrap_array=function(l,code,descriptors){if(code){return types.Array32(l,code,descriptors)}else{console.trace("An array must specify a type for its elements");throw new errors.TypeError("An array must specify a type for its elements")}};types.wrap=function(o){var t=typeof o;if(t==="string"){return types.wrap_string(o)}else if(t==="boolean"){return o?types.True():types.False()}else if(t==="number"||o instanceof Number){if(isNaN(o)){throw new errors.TypeError("Cannot wrap NaN! "+o)}else if(Math.floor(o)-o!==0){return types.Double(o)}else if(o>0){if(o<MAX_UINT){return types.wrap_uint(o)}else{return types.wrap_ulong(o)}}else{if(o>MIN_INT){return types.wrap_int(o)}else{return types.wrap_long(o)}}}else if(o instanceof Date){return types.wrap_timestamp(o.getTime())}else
if(o instanceof Typed){return o}else if(o instanceof Buffer){return types.wrap_binary(o)}else if(t==="undefined"||o===null){return types.Null()}else if(Array.isArray(o)){return types.wrap_list(o)}else{return types.wrap_map(o)}};types.wrap_described=function(value,descriptor){var result=types.wrap(value);if(descriptor){if(typeof descriptor==="string"){result=types.described(types.wrap_string(descriptor),result)}else if(typeof descriptor==="number"||descriptor instanceof Number){result=types.described(types.wrap_ulong(descriptor),result)}}return result};types.wrap_message_id=function(o){var t=typeof o;if(t==="string"){return types.wrap_string(o)}else if(t==="number"||o instanceof Number){return types.wrap_ulong(o)}else{throw new errors.TypeError("invalid message id:"+o)}};function mapify(elements){var result={};for(var i=0;i+1<elements.length;){result[elements[i++]]=elements[i++]}return result}var by_descriptor={};types.unwrap_map_simple=function(o){return mapify(o.value.map(function(
i){return types.unwrap(i,true)}))};types.unwrap=function(o,leave_described){if(o instanceof Typed){if(o.descriptor){var c=by_descriptor[o.descriptor.value];if(c){return new c(o.value)}else if(leave_described){return o}}var u=types.unwrap(o.value,true);return types.is_map(o)?mapify(u):u}else if(Array.isArray(o)){return o.map(function(i){return types.unwrap(i,true)})}else{return o}};types.described_nc=function(descriptor,o){if(descriptor.length){o.descriptor=descriptor.shift();return types.described(descriptor,o)}else{o.descriptor=descriptor;return o}};types.described=types.described_nc;function get_type(code){var type=types.by_code[code];if(!type){throw new errors.TypeError("Unrecognised typecode: "+hex(code))}return type}types.Reader=function(buffer){this.buffer=buffer;this.position=0};types.Reader.prototype.read_typecode=function(){return this.read_uint(1)};types.Reader.prototype.read_uint=function(width){var current=this.position;this.position+=width;if(width===1){return this.buff
er.readUInt8(current)}else if(width===2){return this.buffer.readUInt16BE(current)}else if(width===4){return this.buffer.readUInt32BE(current)}else{throw new errors.TypeError("Unexpected width for uint "+width)}};types.Reader.prototype.read_fixed_width=function(type){var current=this.position;this.position+=type.width;if(type.read){return type.read(this.buffer,current)}else{return this.buffer.slice(current,this.position)}};types.Reader.prototype.read_variable_width=function(type){var size=this.read_uint(type.width);var slice=this.read_bytes(size);return type.encoding?slice.toString(type.encoding):slice};types.Reader.prototype.read=function(){var constructor=this.read_constructor();var value=this.read_value(get_type(constructor.typecode));return constructor.descriptor?types.described_nc(constructor.descriptor,value):value};types.Reader.prototype.read_constructor=function(){var code=this.read_typecode();if(code===0){var d=[];d.push(this.read());var c=this.read_constructor();while(c.des
criptor){d.push(c.descriptor);c=this.read_constructor()}return{typecode:c.typecode,descriptor:d.length===1?d[0]:d}}else{return{typecode:code}}};types.Reader.prototype.read_value=function(type){if(type.width===0){return type.create()}else if(type.category===CAT_FIXED){return type.create(this.read_fixed_width(type))}else if(type.category===CAT_VARIABLE){return type.create(this.read_variable_width(type))}else if(type.category===CAT_COMPOUND){return this.read_compound(type)}else if(type.category===CAT_ARRAY){return this.read_array(type)}else{throw new errors.TypeError("Invalid category for type: "+type)}};types.Reader.prototype.read_array_items=function(n,type){var items=[];while(items.length<n){items.push(this.read_value(type))}return items};types.Reader.prototype.read_n=function(n){var items=new Array(n);for(var i=0;i<n;i++){items[i]=this.read()}return items};types.Reader.prototype.read_size_count=function(width){return{size:this.read_uint(width),count:this.read_uint(width)}};types.Re
ader.prototype.read_compound=function(type){var limits=this.read_size_count(type.width);return type.create(this.read_n(limits.count))};types.Reader.prototype.read_array=function(type){var limits=this.read_size_count(type.width);var constructor=this.read_constructor();return type.create(this.read_array_items(limits.count,get_type(constructor.typecode)),constructor.typecode,constructor.descriptor)};types.Reader.prototype.toString=function(){var s="buffer@"+this.position;if(this.position)s+=": ";for(var i=this.position;i<this.buffer.length;i++){if(i>0)s+=",";s+="0x"+Number(this.buffer[i]).toString(16)}return s};types.Reader.prototype.reset=function(){this.position=0};types.Reader.prototype.skip=function(bytes){this.position+=bytes};types.Reader.prototype.read_bytes=function(bytes){var current=
<TRUNCATED>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org