You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ea...@apache.org on 2018/01/11 14:15:12 UTC
[1/3] qpid-dispatch git commit: removing rhea since it is
incorporated in dispatch-management.js
Repository: qpid-dispatch
Updated Branches:
refs/heads/master 33feac55c -> cabc6f075
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9b2b64ff/console/stand-alone/plugin/lib/rhea-min.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/lib/rhea-min.js b/console/stand-alone/plugin/lib/rhea-min.js
deleted file mode 100644
index 13d8344..0000000
--- a/console/stand-alone/plugin/lib/rhea-min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-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=this.position;this.position+=bytes;return this.buffer.slice(current,this.position)};types.Reader.prototype.remaining=function(){return this.buffer.length-this.position};types.Writer=function(buffe
r){this.buffer=buffer?buffer:new Buffer(1024);this.position=0};types.Writer.prototype.toBuffer=function(){return this.buffer.slice(0,this.position)};function max(a,b){return a>b?a:b}typ
<TRUNCATED>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[3/3] qpid-dispatch git commit: DISPATCH-903 Use c3 library for charts
Posted by ea...@apache.org.
DISPATCH-903 Use c3 library for charts
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/cabc6f07
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/cabc6f07
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/cabc6f07
Branch: refs/heads/master
Commit: cabc6f07552ee078046e01662fa81c9fa1ab56e3
Parents: 9b2b64f
Author: Ernest Allen <ea...@redhat.com>
Authored: Thu Jan 11 09:14:23 2018 -0500
Committer: Ernest Allen <ea...@redhat.com>
Committed: Thu Jan 11 09:14:23 2018 -0500
----------------------------------------------------------------------
console/stand-alone/index.html | 11 +-
console/stand-alone/package.json | 3 +-
console/stand-alone/plugin/css/dispatch.css | 14 +-
console/stand-alone/plugin/css/dispatchpf.css | 43 ++
console/stand-alone/plugin/css/plugin.css | 13 +-
console/stand-alone/plugin/html/qdrCharts.html | 2 +-
.../plugin/html/tmplChartConfig.html | 11 +-
.../stand-alone/plugin/html/tmplListChart.html | 2 +-
console/stand-alone/plugin/js/dispatchPlugin.js | 18 +-
console/stand-alone/plugin/js/navbar.js | 19 +-
.../stand-alone/plugin/js/qdrChartService.js | 764 +++++--------------
console/stand-alone/plugin/js/qdrCharts.js | 83 +-
console/stand-alone/plugin/js/qdrList.js | 152 ++--
console/stand-alone/plugin/js/qdrListChart.js | 16 +-
console/stand-alone/plugin/js/qdrOverview.js | 2 +-
console/stand-alone/plugin/js/qdrService.js | 45 ++
console/stand-alone/plugin/js/qdrSettings.js | 10 +-
console/stand-alone/plugin/js/qdrTopology.js | 51 +-
18 files changed, 535 insertions(+), 724 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/index.html
----------------------------------------------------------------------
diff --git a/console/stand-alone/index.html b/console/stand-alone/index.html
index 20d1ecf..add2116 100644
--- a/console/stand-alone/index.html
+++ b/console/stand-alone/index.html
@@ -35,9 +35,11 @@ under the License.
<link rel="stylesheet" href="node_modules/patternfly/dist/css/patternfly-additions.min.css" >
<!-- jquery Styles -->
- <link rel="stylesheet" href="node_modules/jquery.tipsy/src/jquery.tipsy.css" type="text/css"/>
<link rel="stylesheet" href="node_modules/jquery.fancytree/dist/skin-bootstrap-n/ui.fancytree.css" type="text/css"/>
+ <!-- charting styles -->
+ <link rel="stylesheet" href="node_modules/c3/c3.css" type="text/css"/>
+
<!-- angular Styles -->
<link rel="stylesheet" href="node_modules/angular-ui-grid/ui-grid.css" type="text/css"/>
@@ -116,11 +118,16 @@ under the License.
<!-- d3 -->
<script src='node_modules/d3/d3.min.js'></script>
<script src='node_modules/d3-queue/build/d3-queue.min.js'></script>
+<script src='node_modules/d3-time/build/d3-time.min.js'></script>
+<script src='node_modules/d3-time-format/build/d3-time-format.min.js'></script>
+
+<!-- c3 for charts -->
+<script src="node_modules/c3/c3.js"></script>
-<script src="node_modules/jquery.tipsy/src/jquery.tipsy.js"></script>
<script src="node_modules/angular-ui-slider/src/slider.js"></script>
<script src="node_modules/angular-ui-grid/ui-grid.js"></script>
<script src="node_modules/notifyjs-browser/dist/notify.js"></script>
+<script src="node_modules/patternfly/dist/js/patternfly.min.js"></script>
<script type="text/javascript" src="node_modules/dispatch-management/dist/dispatch-management.js"></script>
<script type="text/javascript" src="plugin/js/dispatchPlugin.js"></script>
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/package.json
----------------------------------------------------------------------
diff --git a/console/stand-alone/package.json b/console/stand-alone/package.json
index c40057d..6b4df49 100644
--- a/console/stand-alone/package.json
+++ b/console/stand-alone/package.json
@@ -31,14 +31,15 @@
"angular-ui-grid": "^4.0.8",
"angular-ui-slider": "^0.4.0",
"bluebird": "^3.5.1",
+ "c3": "^0.4.18",
"d3": "^3.5.14",
"d3-queue": "^3.0.7",
+ "d3-time-format": "^2.1.1",
"dispatch-management": "^0.1.0",
"html5shiv": "^3.7.3",
"jquery": "^3.2.1",
"jquery-ui-dist": "^1.12.1",
"jquery.fancytree": "^2.26.0",
- "jquery.tipsy": "^1.0.3",
"notifyjs-browser": "^0.4.2",
"patternfly": "^3.30.0"
}
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/css/dispatch.css
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/css/dispatch.css b/console/stand-alone/plugin/css/dispatch.css
index 6af6b9d..670b158 100644
--- a/console/stand-alone/plugin/css/dispatch.css
+++ b/console/stand-alone/plugin/css/dispatch.css
@@ -35,7 +35,7 @@ svg:not(.active):not(.ctrl) {
fill: #33F;
}
path.link.selected {
- stroke-dasharray: 10,2;
+ /* stroke-dasharray: 10,2; */
stroke: #33F !important;
}
@@ -435,8 +435,8 @@ div.boolean {
}
.aggregate i {
- float: right;
- margin: 3px 3px 3px 8px;
+ float: right;
+ /* margin: 3px 3px 3px 8px; */
}
.aggregate .hastip {
@@ -516,6 +516,14 @@ div.boolean {
left: 600px;
}
+.cross-rect {
+ /* fill: #cfe2f3; */
+}
+.cross-line {
+ stroke: black;
+ stroke-width: 4px;
+}
+
.node circle {
/* fill: rgb(31, 119, 180);
fill-opacity: .25; */
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/css/dispatchpf.css
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/css/dispatchpf.css b/console/stand-alone/plugin/css/dispatchpf.css
index fc6c2ac..c7e981f 100644
--- a/console/stand-alone/plugin/css/dispatchpf.css
+++ b/console/stand-alone/plugin/css/dispatchpf.css
@@ -249,4 +249,47 @@ span.fancytree-expander {
display: none;
+}
+
+.dispatch-c3-tooltip {
+ border-collapse: collapse;
+ border-spacing: 0;
+ background-color: #fff;
+ empty-cells: show;
+ -webkit-box-shadow: 7px 7px 12px -9px #777777;
+ -moz-box-shadow: 7px 7px 12px -9px #777777;
+ box-shadow: 7px 7px 12px -9px #777777;
+ opacity: 0.9;
+
+}
+
+.dispatch-c3-tooltip tr {
+ border: 1px solid #CCC;
+}
+
+.dispatch-c3-tooltip th {
+ background-color: #aaa;
+ font-size: 13px;
+ padding: 2px 5px;
+ text-align: left;
+ color: #FFF;
+ font-weight: normal;
+}
+
+.dispatch-c3-tooltip td {
+ font-size: 13px;
+ padding: 3px 6px;
+ background-color: #fff;
+ border-left: 1px dotted #999;
+}
+
+.chart-tip-legend {
+ width: 10px;
+ height: 10px;
+ display: inline-block;
+ margin-right: 4px;
+}
+
+th.text-center {
+ text-align: center;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/css/plugin.css
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/css/plugin.css b/console/stand-alone/plugin/css/plugin.css
index e903c79..fc0fa60 100644
--- a/console/stand-alone/plugin/css/plugin.css
+++ b/console/stand-alone/plugin/css/plugin.css
@@ -63,6 +63,10 @@ div.listAttrName button {
margin: 3px 5px;
}
+div.listAggrValue button {
+ margin: 3px 5px;
+}
+
@-moz-document url-prefix() {
div.listAttrName button {
top: -24px;
@@ -156,7 +160,7 @@ div.chartContainer {
/* the line surrounding the area chart */
div.d3Chart path {
/* stroke: black; */
- stroke-width: 0;
+/* stroke-width: 0; */
/* opacity: 0.5; */
}
@@ -222,8 +226,8 @@ div.d3Chart .title {
}
div.d3Chart {
- padding: 1em 0;
- border: 1px solid #C0C0C0;
+ /* padding: 1em 0; */
+ /* border: 1px solid #C0C0C0; */
margin-bottom: 2em;
}
div.d3Chart.hDash {
@@ -233,8 +237,9 @@ div.d3Chart.hDash {
div.d3Chart .axis path {
display: inherit;
}
+
.c3-circle {
- display: none;
+ /* display: none; */
}
.fo-table {
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/html/qdrCharts.html
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/html/qdrCharts.html b/console/stand-alone/plugin/html/qdrCharts.html
index 583a407..d2bd38c 100644
--- a/console/stand-alone/plugin/html/qdrCharts.html
+++ b/console/stand-alone/plugin/html/qdrCharts.html
@@ -24,7 +24,7 @@ under the License.
<button ng-click="editChart(chart)" title="Configure"><span class="fa-edit"></span></button>
<!-- <button ng-click="zoomChart(chart)" title="Zoom {{chart.zoomed ? 'in' : 'out'}}" ng-if="!chart.chart.request().nodeList"><i ng-class="chart.zoomed ? 'fa-zoom-in' : 'icon-zoom-out'"></i></button> -->
</p><div style="clear:both"></div>
- <div id="{{chart.chart.id()}}" class="aChart d3Chart"></div>
+ <div id="{{chart.chart.id()}}" class="line-chart-pf aChart d3Chart"></div>
</div>
<div ng-init="chartsLoaded()"></div>
</div>
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/html/tmplChartConfig.html
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/html/tmplChartConfig.html b/console/stand-alone/plugin/html/tmplChartConfig.html
index ac5363b..2e2cb8c 100644
--- a/console/stand-alone/plugin/html/tmplChartConfig.html
+++ b/console/stand-alone/plugin/html/tmplChartConfig.html
@@ -26,7 +26,7 @@
<h3 class="modal-title">Chart {{chart.attr() | humanify}}</h3>
</div>
<div class="modal-body">
- <div id="{{svgDivId}}" class="d3Chart"></div>
+ <div id="{{svgDivId}}" class="line-chart-pf"></div>
<uib-tabset>
<uib-tab heading="Type">
@@ -34,25 +34,26 @@
<div>
<label><input type="radio" ng-model="dialogChart.type" value="value" /> Value Chart</label>
<label><input type="radio" ng-model="dialogChart.type" value="rate" /> Rate Chart</label>
+<!--
<div class="dlg-slider" ng-show="dialogChart.type=='rate'">
<span>Rate Window: {{rateWindow}} second{{rateWindow > 1 ? "s" : ""}}</span>
<div id="rateSlider"></div>
</div>
+-->
</div>
<div style="clear:both;"> </div>
</uib-tab>
+<!--
<uib-tab ng-hide="$parent.chart.aggregate()" heading="Colors">
<legend>Chart colors</legend>
<div>
<div class="colorPicker">
- <label>Line: <input id="lineColor" name="lineColor" type="color" /></label>
- </div>
- <div class="colorPicker">
<label>Area: <input id="areaColor" name="areaColor" type="color" /></label>
</div>
</div>
<div style="clear:both;"> </div>
</uib-tab>
+-->
<uib-tab heading="Duration">
<legend>Chart duration</legend>
<div>
@@ -77,7 +78,7 @@
<button class="btn btn-success" type="button" ng-click="addChartsPage()"><i class="icon-bar-chart"></i> Add</button> this chart to the Charts page.
</span>
<span ng-show="isOnChartsPage()">
- <button class="btn btn-danger" type="button" ng-click="delChartsPage()">Remove</button> this chart from the <button class="btn btn-success" type="button" ng-click="showChartsPage()"><i class="icon-bar-chart"></i> Charts</button> page.
+ View the <button class="btn btn-success" type="button" ng-click="showChartsPage()"><i class="icon-bar-chart"></i> Charts</button> page.
</span>
<button class="btn btn-primary" type="button" ng-click="okClick()">Close</button>
</div>
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/html/tmplListChart.html
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/html/tmplListChart.html b/console/stand-alone/plugin/html/tmplListChart.html
index 4884984..3214187 100644
--- a/console/stand-alone/plugin/html/tmplListChart.html
+++ b/console/stand-alone/plugin/html/tmplListChart.html
@@ -27,7 +27,7 @@
<p class="newChart">
<button ng-click="editChart()" title="Configure"><span class="fa-edit"></span></button>
</p><div style="clear:both"></div>
- <div id="{{svgDivId}}" class="d3Chart"></div>
+ <div id="pfDialogChart" class="line-chart-pf"></div>
</div>
<div class="modal-footer">
<span ng-hide="isOnChartsPage()">
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/js/dispatchPlugin.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/dispatchPlugin.js b/console/stand-alone/plugin/js/dispatchPlugin.js
index d897425..81d716c 100644
--- a/console/stand-alone/plugin/js/dispatchPlugin.js
+++ b/console/stand-alone/plugin/js/dispatchPlugin.js
@@ -184,10 +184,6 @@ var QDR = (function(QDR) {
}
QDR.queue = d3.queue;
- QDRService.management.topology.addUpdatedAction("initChartService", function() {
- QDRService.management.topology.delUpdatedAction("initChartService")
- QDRChartService.init(); // initialize charting service after we are connected
- });
if (!QDRService.management.connection.is_connected()) {
// attempt to connect to the host:port that served this page
var protocol = $location.protocol()
@@ -202,11 +198,23 @@ var QDR = (function(QDR) {
QDR.log.info("Attempting AMQP over websockets connection using address:port of browser ("+host+':'+port+")")
QDRService.management.connection.testConnect(connectOptions)
.then( function (r) {
+ // We didn't connect with reconnect: true flag.
+ // The reason being that if we used reconnect:true and the connection failed, rhea would keep trying. There
+ // doesn't appear to be a way to tell it to stop trying to reconnect.
QDRService.disconnect()
QDR.log.info("Connect succeeded. Using address:port of browser")
connectOptions.reconnect = true
// complete the connection (create the sender/receiver)
- QDRService.connect(connectOptions) // since the testConnect succeeded, we don't need to handle the success/failure return of the promise
+ QDRService.connect(connectOptions)
+ .then( function (r) {
+ // register a callback for when the node list is available (needed for loading saved charts)
+ QDRService.management.topology.addUpdatedAction("initChartService", function() {
+ QDRService.management.topology.delUpdatedAction("initChartService")
+ QDRChartService.init(); // initialize charting service after we are connected
+ });
+ // get the list of nodes
+ QDRService.management.topology.startUpdating(false);
+ })
}, function (e) {
QDR.log.info("failed to auto-connect to " + host + ":" + port)
QDR.log.info("redirecting to connect page")
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/js/navbar.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/navbar.js b/console/stand-alone/plugin/js/navbar.js
index e562a7e..7cb129a 100644
--- a/console/stand-alone/plugin/js/navbar.js
+++ b/console/stand-alone/plugin/js/navbar.js
@@ -158,6 +158,9 @@ var QDR = (function (QDR) {
$scope.addChartsPage = function () {
QDRChartService.addDashboard(dialogSvgChart.chart);
};
+ $scope.delChartsPage = function () {
+ QDRChartService.delDashboard($scope.chart);
+ }
$scope.showChartsPage = function () {
cleanup();
@@ -197,7 +200,7 @@ var QDR = (function (QDR) {
setTimeout(initRateSlider, 100)
}
}
- initRateSlider();
+ //initRateSlider();
var initDurationSlider = function () {
if (document.getElementById('durationSlider')) {
@@ -224,8 +227,9 @@ var QDR = (function (QDR) {
}
$scope.isOnChartsPage = function () {
+ var chart = $scope.chart
if (adding)
- return dialogSvgChart ? dialogSvgChart.chart.dashboard : false;
+ return QDRChartService.isAttrCharted(chart.nodeId(), chart.entity(), chart.name(), chart.attr(), chart.aggregate())
else
return $scope.chart.dashboard
}
@@ -260,7 +264,7 @@ var QDR = (function (QDR) {
dialogSvgChart.tick($scope.svgDivId);
// draw the chart again in 1 second
- var updateRate = localStorage['updateRate'] ? localStorage['updateRate'] : 5000;
+ var updateRate = localStorage['updateRate'] ? localStorage['updateRate'] : 1000;
if (updateTimer)
clearTimeout(updateTimer);
updateTimer = setTimeout(updateDialogChart, updateRate);
@@ -273,17 +277,14 @@ var QDR = (function (QDR) {
setTimeout(showChart, 100);
return;
}
- dialogSvgChart = new QDRChartService.AreaChart($scope.dialogChart);
- $('input[name=lineColor]').val($scope.dialogChart.lineColor);
+ dialogSvgChart = new QDRChartService.pfAreaChart($scope.dialogChart, $scope.svgDivId)
+/*
$('input[name=areaColor]').val($scope.dialogChart.areaColor);
$('input[name=areaColor]').on('input', function (e) {
$scope.dialogChart.areaColor = $(this).val();
updateDialogChart()
})
- $('input[name=lineColor]').on('input', function (e) {
- $scope.dialogChart.lineColor = $(this).val();
- updateDialogChart()
- })
+*/
if (updateTimer)
clearTimeout(updateTimer);
updateDialogChart();
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/js/qdrChartService.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrChartService.js b/console/stand-alone/plugin/js/qdrChartService.js
index 418b597..ed96fd4 100644
--- a/console/stand-alone/plugin/js/qdrChartService.js
+++ b/console/stand-alone/plugin/js/qdrChartService.js
@@ -70,9 +70,9 @@ var QDR = (function(QDR) {
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.areaColor = "#32b9f3"; // 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.visibleDuration = opts.visibleDuration ? opts.visibleDuration : 1; // number of minutes of data to show (<= base.duration)
this.userTitle = null; // user title overrides title()
// generate a unique id for this chart
@@ -141,6 +141,9 @@ var QDR = (function(QDR) {
this.base.request.duration = _;
return this;
}
+ this.router = function () {
+ return QDRService.management.topology.nameFromId(this.nodeId())
+ }
this.title = function(_) {
var name = this.request().aggregate ? 'Aggregate' : QDRService.management.topology.nameFromId(this.nodeId());
var computed = name +
@@ -338,6 +341,7 @@ var QDR = (function(QDR) {
request = new ChartRequest(opts); //nodeId, entity, name, attr, interval, aggregate);
self.chartRequests.push(request);
self.startCollecting(request);
+ self.sendChartRequest(request, true)
}
var charts = self.findCharts(opts); //name, attr, nodeId, entity, hdash);
var chart;
@@ -479,7 +483,7 @@ var QDR = (function(QDR) {
//return self.charts.length;
},
- isAttrCharted: function(nodeId, entity, name, attr) {
+ isAttrCharted: function(nodeId, entity, name, attr, aggregate) {
var charts = self.findCharts({
name: name,
attr: attr,
@@ -488,7 +492,7 @@ var QDR = (function(QDR) {
})
// if any of the matching charts are on the dashboard page, return true
return charts.some(function(chart) {
- return (chart.dashboard)
+ return (chart.dashboard && (aggregate ? chart.aggregate() : !chart.aggregate()))
});
},
@@ -527,9 +531,7 @@ var QDR = (function(QDR) {
var charts = angular.fromJson(localStorage["QDRCharts"]);
if (charts) {
// get array of known ids
- var nodeList = QDRService.management.topology.nodeList().map(function(node) {
- return node.id;
- })
+ var nodeList = QDRService.management.topology.nodeIdList()
charts.forEach(function(chart) {
// if this chart is not in the current list of nodes, skip
if (nodeList.indexOf(chart.nodeId) >= 0) {
@@ -539,7 +541,7 @@ var QDR = (function(QDR) {
if (chart.instance >= instance)
instance = chart.instance + 1;
if (!chart.duration)
- chart.duration = 10;
+ chart.duration = 1;
if (chart.nodeList)
chart.aggregate = true;
if (!chart.hdash)
@@ -558,10 +560,10 @@ var QDR = (function(QDR) {
newChart.hreq = false;
newChart.type = chart.type;
newChart.rateWindow = chart.rateWindow;
- newChart.areaColor = chart.areaColor ? chart.areaColor : "#cbe7f3";
+ newChart.areaColor = chart.areaColor ? chart.areaColor : "#32b9f3";
newChart.lineColor = chart.lineColor ? chart.lineColor : "#058dc7";
newChart.duration(chart.duration);
- newChart.visibleDuration = chart.visibleDuration ? chart.visibleDuration : 10;
+ newChart.visibleDuration = chart.visibleDuration ? chart.visibleDuration : 1;
if (chart.userTitle)
newChart.title(chart.userTitle);
}
@@ -569,583 +571,223 @@ var QDR = (function(QDR) {
}
},
- AreaChart: function(chart) {
+ // constructor for a c3 area chart
+ pfAreaChart: function (chart, chartId, defer) {
if (!chart)
return;
+ // reference to underlying chart
+ this.chart = chart;
+
// 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();
+ this.stacked = chart.request().aggregate;
- // 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() {
+ // the id of the html element that is bound to the chart. The svg will be a child of this
+ this.htmlId = chartId
- var now = new Date();
- var visibleDate = new Date(now.getTime() - chart.visibleDuration * 60 * 1000);
- var data = chart.data();
- var nodeList = QDRService.management.topology.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.management.topology.nameFromId(node),
- val: (d1[2][nodeIndex].val - d[2][nodeIndex].val) / elapsed
- })
- })
- rd.push(detail)
- }
- rateData.push(rd);
- break;
- }
- }
+ // an array of 20 colors
+ this.colors = d3.scale.category10().range();
+
+ if (!defer)
+ this.generate()
+ },
+ }
+
+ // create the svg and bind it to the given div.id
+ self.pfAreaChart.prototype.generate = function () {
+ var chart = this.chart // for access during chart callbacks
+ var self = this
+
+ // list of router names. used to get the color index
+ var nameList = QDRService.management.topology.nodeNameList();
+
+ var c3ChartDefaults = $().c3ChartDefaults();
+ var singleAreaChartConfig = c3ChartDefaults.getDefaultSingleAreaConfig();
+ singleAreaChartConfig.bindto = '#' + this.htmlId;
+ singleAreaChartConfig.data = {
+ x: 'x', // x-axis is named x
+ columns: [[]],
+ type: 'area-spline'
+ }
+ singleAreaChartConfig.axis = {
+ x: {
+ type: 'timeseries',
+ tick: {
+ format: (function (d) {
+ var data = this.singleAreaChart.data.shown()
+ var first = data[0]['values'][0].x
+
+ if (d - first == 0) {
+ return d3.timeFormat("%I:%M:%S")(d)
}
- }
- // we need at least a point to chart
- if (rateData.length == 0) {
- rateData[0] = [chart.data()[0][0], 0, [{
- node: '',
- val: 0
- }]];
- }
- return rateData;
+ return d3.timeFormat("%M:%S")(d)
+ }).bind(this),
+ culling: {max: 4}
+ },
+ label: {
+ text: chart.name()
}
- 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)
+ },
+ y: {
+ tick: {
+ format: function (d) { return d<1 ? d3.format(".2f")(d) : d3.format(".2s")(d) },
+ count: 5
}
}
+ }
+ singleAreaChartConfig.transition = {
+ duration: 0
+ }
- // 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;
- }
+ singleAreaChartConfig.area = {
+ zerobased: false
+ }
- // 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;
- }
+ singleAreaChartConfig.tooltip = {
+ contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
+ var d3f = ","
+ if (chart.type === 'rate')
+ d3f = ",.2f"
+ var zPre = function (i) {
+ if (i < 10) {
+ i = "0" + i;
}
- // create and initialize the chart
- this.svgchart = self.timeSeriesStackedChart(id, width, height,
- QDRService.utilities.humanify(this.chart.attr()),
- this.chart.name(),
- QDRService.management.topology.nameFromId(this.chart.nodeId()),
- this.chart.entity(),
- stacked,
- this.chart.visibleDuration)
- .tooltipGenerator(tooltipGenerator);
-
+ return i;
}
- // 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
+ var h = zPre(d[0].x.getHours())
+ var m = zPre(d[0].x.getMinutes())
+ var s = zPre(d[0].x.getSeconds())
+ var table = "<table class='dispatch-c3-tooltip'> <tr><th colspan='2' class='text-center'><strong>"+h+':'+m+':'+s+"</strong></th></tr> <tbody>"
+ for (var i=0; i<d.length; i++) {
+ var colorIndex = nameList.indexOf(d[i].id) % 10
+ var span = "<span class='chart-tip-legend' style='background-color: "+self.colors[colorIndex]+";'> </span>" + d[i].id
+ table += ("<tr><td>"+span+"<td>"+d3.format(d3f)(d[i].value)+"</td></tr>")
}
- // 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])
+ table += "</tbody></table>"
+ return table
}
+ }
- 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)
- })
+ singleAreaChartConfig.title = {
+ text: QDRService.utilities.humanify(this.chart.attr())
+ }
- 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);
- }
+ singleAreaChartConfig.data.colors = {}
+ nameList.forEach( (function (r, i) {
+ singleAreaChartConfig.data.colors[r] = this.colors[i % 10]
+ }).bind(this))
- 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")
+ singleAreaChartConfig.data.color = (function (color, d) {
+ var i = nameList.indexOf(d)
+ return i >= 0 ? this.colors[i % 10] : color
+ }).bind(this)
- 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");
- }
+ singleAreaChartConfig.legend = {show: true}
- // 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)
+ this.singleAreaChart = c3.generate(singleAreaChartConfig);
+ }
+ // filter/modify the chart.data into data points for the svg
+ /* the collected data looks like:
+ [[date, val, [v1,v2,...]], [date, val, [v1,v2,...]],...]
+ with date being the timestamp of the sample
+ val being the total value
+ and the [v1,v2,...] array being the component values for each router for stacked charts
+
+ for stacked charts, the returned data looks like:
+ [['x', date, date,...},
+ ['R1', v1, v1,...},
+ ['R2', v2, v2,...],
+ ...]
+
+ for non-stacked charts, the returned data looks like:
+ ['x', date, date,...],
+ ['R1', val, val,...]]
+
+ for rate charts, all the values returned are the change per second between adjacent values
+ */
+ self.pfAreaChart.prototype.chartData = function() {
+ var data = this.chart.data();
+ var nodeList = QDRService.management.topology.nodeIdList();
+
+ // oldest data point that should be visible
+ var now = new Date();
+ var visibleDate = new Date(now.getTime() - this.chart.visibleDuration * 60 * 1000);
+
+ var accessorSingle = function (d, d1, elapsed) {
+ return this.chart.type === 'rate' ? (d1[1] - d[1]) / elapsed : d[1]
+ }
+ var accessorStacked = function (d, d1, elapsed, i) {
+ return this.chart.type === 'rate' ? (d1[2][i].val - d[2][i].val) / elapsed : d[2][i].val
+ }
+ var accessor = this.stacked ? accessorStacked : accessorSingle
+
+ var dx = ['x']
+ var dlines = []
+ if (this.stacked) {
+ // for stacked, there is a line per router
+ nodeList.forEach( function (node) {
+ dlines.push([QDRService.management.topology.nameFromId(node)])
+ })
+ } else {
+ // for non-stacked, there is only one line
+ dlines.push([this.chart.router()])
+ }
+ for (var i=0; i<data.length; i++) {
+ var d = data[i], elapsed = 1, d1
+ if (d[0] >= visibleDate) {
+ if (this.chart.type === 'rate' && i < data.length-1) {
+ d1 = data[i+1]
+ elapsed = Math.max((d1[0] - d[0]) / 1000, 0.001); // number of seconds that elapsed
+ }
+ // don't push the last data point for a rate chart
+ if (this.chart.type !== 'rate' || i < data.length-1) {
+ dx.push(d[0])
+ if (this.stacked) {
+ nodeList.forEach( (function (node, nodeIndex) {
+ dlines[nodeIndex].push(accessor.call(this, d, d1, elapsed, nodeIndex))
+ }).bind(this))
+ } else {
+ dlines[0].push(accessor.call(this, d, d1, elapsed))
}
- // 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;
}
+ var columns = [dx]
+ dlines.forEach( function (line) {
+ columns.push(line)
+ })
+ return columns
}
+
+ // get the data for the chart and update it
+ self.pfAreaChart.prototype.tick = function() {
+ // can't draw charts that don't have data yet
+ if (this.chart.data().length == 0 || !this.singleAreaChart) {
+ return;
+ }
+
+ // update the chart title
+ // since there is no c3 api to get or set the chart title, we change the title directly using d3
+ var rate = ''
+ if (this.chart.type === 'rate')
+ rate = ' per second'
+ d3.select("#"+this.htmlId+" svg text.c3-title").text(QDRService.utilities.humanify(this.chart.attr()) + rate);
+
+/*
+ var type='area'
+ if (this.chart.type === 'rate')
+ type = 'area-spline'
+ this.singleAreaChart.transform(type);
+*/
+ var d = this.chartData()
+ // load the new data
+ // using the c3.flow api causes the x-axis labels to jump around
+ this.singleAreaChart.load({
+ columns: d
+ })
+ }
+
return self;
}
]);
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/js/qdrCharts.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrCharts.js b/console/stand-alone/plugin/js/qdrCharts.js
index 3cec385..5724a1d 100644
--- a/console/stand-alone/plugin/js/qdrCharts.js
+++ b/console/stand-alone/plugin/js/qdrCharts.js
@@ -26,46 +26,54 @@ var QDR = (function (QDR) {
*
* Controller that handles the QDR charts page
*/
- QDR.module.controller("QDR.ChartsController", function($scope, QDRService, QDRChartService, $uibModal, $location, $routeParams) {
+ QDR.module.controller("QDR.ChartsController", function($scope, QDRService, QDRChartService, $uibModal, $location, $routeParams, $timeout) {
- var updateTimer = null;
+ var updateTimer = null;
- if (!QDRService.management.connection.is_connected()) {
- // we are not connected. we probably got here from a bookmark or manual page reload
- QDR.redirectWhenConnected($location, "charts");
- return;
- }
+ if (!QDRService.management.connection.is_connected()) {
+ // we are not connected. we probably got here from a bookmark or manual page reload
+ QDR.redirectWhenConnected($location, "charts");
+ return;
+ }
+
+ $scope.svgCharts = [];
+ // create an svg object for each chart
+ QDRChartService.charts.filter(function (chart) {return chart.dashboard}).forEach(function (chart) {
+ var svgChart = new QDRChartService.pfAreaChart(chart, chart.id(), true)
+ svgChart.zoomed = false;
+ $scope.svgCharts.push(svgChart);
+ })
- $scope.svgCharts = [];
- // create an svg object for each chart
- QDRChartService.charts.filter(function (chart) {return chart.dashboard}).forEach(function (chart) {
- var svgChart = new QDRChartService.AreaChart(chart)
- svgChart.zoomed = false;
- $scope.svgCharts.push(svgChart);
- })
// redraw the chart every update period
- // this is a $scope function because it is called from the dialog
var updateCharts = function () {
$scope.svgCharts.forEach(function (svgChart) {
svgChart.tick(svgChart.chart.id()); // on this page we are using the chart.id() as the div id in which to render the chart
})
- var updateRate = localStorage['updateRate'] ? localStorage['updateRate'] : 5000;
+ var updateRate = localStorage['updateRate'] ? localStorage['updateRate'] : 1000;
if (updateTimer) {
clearTimeout(updateTimer)
}
updateTimer = setTimeout(updateCharts, updateRate);
}
- // called by ng-init in the html when the page is loaded
- $scope.chartsLoaded = function () {
- $scope.svgCharts.forEach(function (svgChart) {
- QDRChartService.sendChartRequest(svgChart.chart.request(), true);
- })
- if (updateTimer)
- clearTimeout(updateTimer)
- setTimeout(updateCharts, 0);
- }
+ // called by ng-init in the html when the page is loaded
+ $scope.chartsLoaded = function () {
+ // ensure the div for our chart is loaded in the dom
+ var div = angular.element(".chartContainer");
+ if (!div.width()) {
+ setTimeout($scope.chartsLoaded, 100);
+ return;
+ }
+ // create an svg object for each chart
+ $scope.svgCharts.forEach ( function (c) {
+ c.generate()
+ QDRChartService.sendChartRequest(c.chart.request(), true);
+ })
+ if (updateTimer)
+ clearTimeout(updateTimer)
+ setTimeout(updateCharts);
+ }
$scope.zoomChart = function (chart) {
chart.zoomed = !chart.zoomed;
@@ -80,23 +88,28 @@ var QDR = (function (QDR) {
};
$scope.editChart = function (chart) {
- doDialog("tmplChartConfig.html", chart.chart);
+ doDialog("tmplChartConfig.html", chart.chart);
};
$scope.delChart = function (chart) {
- QDRChartService.unRegisterChart(chart.chart);
- // remove from svgCharts
- $scope.svgCharts.forEach(function (svgChart, i) {
- if (svgChart === chart) {
- delete $scope.svgCharts.splice(i, 1);
- }
- })
- };
+ QDRChartService.unRegisterChart(chart.chart);
+ // remove from svgCharts
+ $scope.svgCharts.forEach(function (svgChart, i) {
+ if (svgChart === chart) {
+ delete $scope.svgCharts.splice(i, 1);
+ }
+ })
+ }
// called from dialog when we want to clone the dialog chart
// the chart argument here is a QDRChartService chart
$scope.addChart = function (chart) {
- $scope.svgCharts.push(new QDRChartService.AreaChart(chart));
+ var nchart = new QDRChartService.pfAreaChart(chart, chart.id(), true)
+ $scope.svgCharts.push(nchart);
+ $timeout( function () {
+ nchart.generate()
+ QDRChartService.sendChartRequest(chart.request(), true);
+ })
};
$scope.$on("$destroy", function( event ) {
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/js/qdrList.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrList.js b/console/stand-alone/plugin/js/qdrList.js
index 9f60e5c..7263da8 100644
--- a/console/stand-alone/plugin/js/qdrList.js
+++ b/console/stand-alone/plugin/js/qdrList.js
@@ -24,8 +24,8 @@ var QDR = (function(QDR) {
/**
* Controller for the main interface
*/
- QDR.module.controller("QDR.ListController", ['$scope', '$location', '$uibModal', '$filter', '$timeout', 'QDRService', 'QDRChartService', 'uiGridConstants',
- function ($scope, $location, $uibModal, $filter, $timeout, QDRService, QDRChartService, uiGridConstants) {
+ QDR.module.controller("QDR.ListController", ['$scope', '$location', '$uibModal', '$filter', '$timeout', 'QDRService', 'QDRChartService', 'uiGridConstants', '$sce',
+ function ($scope, $location, $uibModal, $filter, $timeout, QDRService, QDRChartService, uiGridConstants, $sce) {
QDR.log.debug("QDR.ListControll started with location of " + $location.path() + " and connection of " + QDRService.management.connection.is_connected());
var updateIntervalHandle = undefined;
@@ -147,6 +147,7 @@ var QDR = (function(QDR) {
$scope.nodes = []
var excludedEntities = ["management", "org.amqp.management", "operationalEntity", "entity", "configurationEntity", "dummy", "console"];
var aggregateEntities = ["router.address"];
+
var classOverrides = {
"connection": function (row, nodeId) {
var isConsole = QDRService.utilities.isAConsole (row.properties.value, row.identity.value, row.role.value, nodeId)
@@ -429,25 +430,6 @@ var QDR = (function(QDR) {
return (old.name === attr) ? old.graph && old.rawValue != row[attr].value : false;
})
var schemaEntity = schemaProps($scope.selectedEntity, attr, $scope.currentNode)
-/*
-[{
- "type": "value",
- "rateWindow": 1000,
- "areaColor": "#cbe7f3",
- "lineColor": "#058dc7",
- "visibleDuration": 10,
- "userTitle": null,
- "dashboard": true,
- "hdash": false,
- "instance": 1,
- "name": "Lqdhello",
- "attr": "deliveriesFromContainer",
- "nodeId": "amqp:/_topo/0/QDR.A/$management",
- "entity": "router.address",
- "interval": 1000,
- "duration": 10
-}]
-*/
details.push( {
attributeName: QDRService.utilities.humanify(attr),
attributeValue: attr === 'port' ? row[attr].value : QDRService.utilities.pretty(row[attr].value),
@@ -456,8 +438,8 @@ var QDR = (function(QDR) {
rawValue: row[attr].value,
graph: row[attr].graph,
title: row[attr].title,
- chartExists: (QDRChartService.findCharts({name: row.name.value, attr: attr, nodeId: $scope.currentNode.id, entity: $scope.selectedEntity}).length > 0),
- //chartExists: QDRChartService.findChartRequest($scope.currentNode.id, $scope.selectedEntity) !== null,
+ chartExists: (QDRChartService.isAttrCharted($scope.currentNode.id, $scope.selectedEntity, row.name.value, attr)),
+ aggchartExists: (QDRChartService.isAttrCharted($scope.currentNode.id, $scope.selectedEntity, row.name.value, attr, true)),
aggregateValue: QDRService.utilities.pretty(row[attr].aggregate),
aggregateTip: row[attr].aggregateTip,
@@ -629,43 +611,8 @@ var QDR = (function(QDR) {
// tableRows are the records that were returned, this populates the left hand tree on the page
var selectRow = function (info) {
updateTreeChildren(info.entity, info.rows, info.expand);
- fixTooltips();
- }
-
- var titleFromAlt = function (alt) {
- if (alt && alt.length) {
- var data = angular.fromJson(alt);
- var table = "<table class='tiptable'><tbody>";
- data.forEach (function (row) {
- table += "<tr>";
- table += "<td>" + row.node + "</td><td align='right'>" + QDRService.utilities.pretty(row.val) + "</td>";
- table += "</tr>"
- })
- table += "</tbody></table>"
- return table;
- }
- return '';
+ //fixTooltips();
}
-
- var fixTooltips = function () {
- if ($('.hastip').length == 0) {
- setTimeout(fixTooltips, 100);
- return;
- }
- $('.hastip').each( function (i, tip) {
- var tipset = tip.getAttribute('tipset')
- if (!tipset) {
- $(tip).tipsy({html: true, className: 'subTip', opacity: 1, title: function () {
- return titleFromAlt(this.getAttribute('alt'))
- } });
- tip.setAttribute('tipset', true)
- } else {
- var title = titleFromAlt(tip.getAttribute('alt'))
- tip.setAttribute('original-title', title)
- }
- })
- }
-
$scope.detailFields = [];
$scope.addToGraph = function(rowEntity) {
@@ -675,7 +622,8 @@ var QDR = (function(QDR) {
name: $scope.selectedRecordName,
attr: rowEntity.name,
forceCreate: true});
- doDialog('tmplListChart.html', chart);
+
+ doDialog('tmplChartConfig.html', chart);
}
$scope.addAllToGraph = function(rowEntity) {
@@ -689,9 +637,31 @@ var QDR = (function(QDR) {
visibleDuration: 1,
forceCreate: true,
aggregate: true});
- doDialog('tmplListChart.html', chart);
+ doDialog('tmplChartConfig.html', chart);
}
+ // The ui-popover dynamic html
+ $scope.aggregateTip = ''
+ // disable popover tips for non-integer cells
+ $scope.aggregateTipEnabled = function (row) {
+ var tip = row.entity.aggregateTip
+ return (tip && tip.length) ? "true" : "false"
+ }
+ // convert the aggregate data into a table for the popover tip
+ $scope.genAggregateTip = function (row) {
+ var tip = row.entity.aggregateTip
+ if (tip && tip.length) {
+ var data = angular.fromJson(tip);
+ var table = "<table class='tiptable'><tbody>";
+ data.forEach (function (row) {
+ table += "<tr>";
+ table += "<td>" + row.node + "</td><td align='right'>" + QDRService.utilities.pretty(row.val) + "</td>";
+ table += "</tr>"
+ })
+ table += "</tbody></table>"
+ $scope.aggregateTip = $sce.trustAsHtml(table)
+ }
+ }
var aggregateColumn = function () {
if ((aggregateEntities.indexOf($scope.selectedEntity) > -1 && $scope.detailCols.length != 3) ||
(aggregateEntities.indexOf($scope.selectedEntity) == -1 && $scope.detailCols.length != 2)) {
@@ -710,13 +680,13 @@ var QDR = (function(QDR) {
]
if (aggregateEntities.indexOf($scope.selectedEntity) > -1) {
$scope.detailCols.push(
- {
- width: '10%',
- field: 'aggregateValue',
- displayName: 'Aggregate',
- cellTemplate: '<div class="hastip ui-grid-cell-contents" alt="{{row.entity.aggregateTip}}" ng-class="{\'changed\': row.entity.changed == 1}">{{COL_FIELD CUSTOM_FILTERS}} <button title="Click to view/add a graph" ng-if="row.entity.graph" ng-click="grid.appScope.addAllToGraph(row.entity)" ng-class="{\'btn-success\': row.entity.chartExists}" class="btn"><i ng-class="{\'icon-bar-chart\': row.entity.graph == true }"></i></button></div>',
- cellClass: 'aggregate'
- }
+ {
+ width: '10%',
+ field: 'aggregateValue',
+ displayName: 'Aggregate',
+ cellTemplate: '<div popover-enable="{{grid.appScope.aggregateTipEnabled(row)}}" uib-popover-html="grid.appScope.aggregateTip" popover-append-to-body="true" ng-mouseover="grid.appScope.genAggregateTip(row)" popover-trigger="\'mouseenter\'" class="listAggrValue ui-grid-cell-contents" ng-class="{\'changed\': row.entity.changed == 1}">{{COL_FIELD CUSTOM_FILTERS}} <button title="Click to view/add a graph" ng-if="row.entity.graph" ng-click="grid.appScope.addAllToGraph(row.entity)" ng-class="{\'btn-success\': row.entity.aggchartExists}" class="btn"><i ng-class="{\'icon-bar-chart\': row.entity.graph == true }"></i></button></div>',
+ cellClass: 'aggregate'
+ }
)
}
}
@@ -802,27 +772,32 @@ var QDR = (function(QDR) {
.then(function (response) {gotMethodResponse($scope.selectedEntity, response.context)})
}
- function doDialog(tmpl, chart) {
- var d = $uibModal.open({
- backdrop: true,
- keyboard: true,
- backdropClick: true,
- templateUrl: QDR.templatePath + tmpl,
- controller: "QDR.ListChartController",
- resolve: {
- chart: function() {
- return chart
- },
- nodeName: function () {
- return $scope.selectedNode
- }
- }
- });
-
- d.result.then(function(result) { QDR.log.debug("d.open().then"); });
+ function doDialog(template, chart) {
+ var d = $uibModal.open({
+ backdrop: true,
+ keyboard: true,
+ backdropClick: true,
+ templateUrl: QDR.templatePath + template,
+ controller: "QDR.ChartDialogController",
+ resolve: {
+ chart: function() {
+ return chart;
+ },
+ updateTick: function () {
+ return function () {};
+ },
+ dashboard: function () {
+ return $scope;
+ },
+ adding: function () {
+ return true
+ }
+ }
+ }).result.then(function(result) {
+ QDRChartService.unRegisterChart(chart)
+ });
};
-
var setCurrentNode = function () {
$scope.nodes.some( function (node, i) {
if (node.name === $scope.selectedNode) {
@@ -835,6 +810,9 @@ var QDR = (function(QDR) {
var treeReady = false;
var serviceReady = false;
$scope.largeNetwork = QDRService.management.topology.isLargeNetwork()
+ if ($scope.largeNetwork)
+ aggregateEntities = [];
+
// called after we know for sure the schema is fetched and the routers are all ready
QDRService.management.topology.addUpdatedAction("initList", function () {
QDRService.management.topology.stopUpdating();
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/js/qdrListChart.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrListChart.js b/console/stand-alone/plugin/js/qdrListChart.js
index 3c14ebf..af281ad 100644
--- a/console/stand-alone/plugin/js/qdrListChart.js
+++ b/console/stand-alone/plugin/js/qdrListChart.js
@@ -19,9 +19,11 @@ under the License.
/**
* @module QDR
*/
+
var QDR = (function(QDR) {
- QDR.module.controller('QDR.ListChartController', function ($scope, $uibModalInstance, $uibModal, $location, QDRChartService, chart, nodeName) {
+ QDR.module.controller('QDR.ListChartController', function ($scope, $uibModalInstance, $uibModal, $location, QDRService, QDRChartService, chart, nodeName) {
+
$scope.chart = chart;
$scope.dialogSvgChart = null;
var updateTimer = null;
@@ -69,21 +71,21 @@ var QDR = (function(QDR) {
}
var showChart = function () {
- // the chart divs are generated by angular and aren't available immediately
- var div = angular.element("#" + $scope.svgDivId);
+ // we need a width and height before generating the chart
+ var div = angular.element("#pfDialogChart");
if (!div.width()) {
setTimeout(showChart, 100);
return;
}
- dialogSvgChart = new QDRChartService.AreaChart($scope.chart);
- $scope.dialogSvgChart = dialogSvgChart;
+ $scope.pfDialogSvgChart = new QDRChartService.pfAreaChart($scope.chart, 'pfDialogChart')
updateDialogChart();
}
showChart();
var updateDialogChart = function () {
- if ($scope.dialogSvgChart)
- $scope.dialogSvgChart.tick($scope.svgDivId);
+ if ($scope.pfDialogSvgChart) {
+ $scope.pfDialogSvgChart.tick();
+ }
if (updateTimer)
clearTimeout(updateTimer)
updateTimer = setTimeout(updateDialogChart, 1000);
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/js/qdrOverview.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrOverview.js b/console/stand-alone/plugin/js/qdrOverview.js
index 7167250..9c2ae0a 100644
--- a/console/stand-alone/plugin/js/qdrOverview.js
+++ b/console/stand-alone/plugin/js/qdrOverview.js
@@ -1442,7 +1442,7 @@ return;
}
var setTemplate = function (node) {
- var type = node.data.type;
+ var type = node.type;
var template = $scope.templates.filter( function (tpl) {
return tpl.name == type;
})
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/js/qdrService.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrService.js b/console/stand-alone/plugin/js/qdrService.js
index d49a4e1..f5acb89 100644
--- a/console/stand-alone/plugin/js/qdrService.js
+++ b/console/stand-alone/plugin/js/qdrService.js
@@ -176,3 +176,48 @@ if (!Array.prototype.findIndex) {
}
});
}
+
+// https://tc39.github.io/ecma262/#sec-array.prototype.find
+if (!Array.prototype.find) {
+ Object.defineProperty(Array.prototype, 'find', {
+ 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 kValue.
+ var kValue = o[k];
+ if (predicate.call(thisArg, kValue, k, o)) {
+ return kValue;
+ }
+ // e. Increase k by 1.
+ k++;
+ }
+
+ // 7. Return undefined.
+ return undefined;
+ }
+ });
+}
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/js/qdrSettings.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrSettings.js b/console/stand-alone/plugin/js/qdrSettings.js
index 3edaffc..2af529a 100644
--- a/console/stand-alone/plugin/js/qdrSettings.js
+++ b/console/stand-alone/plugin/js/qdrSettings.js
@@ -29,7 +29,7 @@ var QDR = (function(QDR) {
* Controller that handles the QDR settings page
*/
- QDR.module.controller("QDR.SettingsController", ['$scope', 'QDRService', '$timeout', '$location', function($scope, QDRService, $timeout, $location) {
+ QDR.module.controller("QDR.SettingsController", ['$scope', 'QDRService', 'QDRChartService', '$timeout', '$location', function($scope, QDRService, QDRChartService, $timeout, $location) {
$scope.connecting = false;
$scope.connectionError = false;
@@ -58,6 +58,7 @@ var QDR = (function(QDR) {
}
};
+ // connect/disconnect button clicked
$scope.connect = function() {
if (QDRService.management.connection.is_connected()) {
$timeout( function () {
@@ -93,6 +94,13 @@ var QDR = (function(QDR) {
var options = {address: $scope.formEntity.address, port: $scope.formEntity.port, reconnect: true}
QDRService.connect(options)
.then( function (r) {
+ // register a callback for when the node list is available (needed for loading saved charts)
+ QDRService.management.topology.addUpdatedAction("initChartService", function() {
+ QDRService.management.topology.delUpdatedAction("initChartService")
+ QDRChartService.init(); // initialize charting service after we are connected
+ });
+ // get the list of nodes
+ QDRService.management.topology.startUpdating(false);
// will have redirected to last known page or /overview
}, function (e) {
failed(e)
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cabc6f07/console/stand-alone/plugin/js/qdrTopology.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrTopology.js b/console/stand-alone/plugin/js/qdrTopology.js
index e3d986b..e67059f 100644
--- a/console/stand-alone/plugin/js/qdrTopology.js
+++ b/console/stand-alone/plugin/js/qdrTopology.js
@@ -1227,13 +1227,62 @@ console.log("showEntityForm " + args.entity)
.value(function(d) { return d.size; });
d3.select("#crosssection svg").remove();
- //var svg = d3.select(document.createElement('div'))
var svg = d3.select("#crosssection").append("svg")
.attr("width", diameter)
.attr("height", diameter)
+
+ var rg = svg.append('svg:defs')
+ .append('radialGradient')
+ .attr("id", "cross-gradient")
+ .attr("gradientTransform", "scale(2.0) translate(-0.5,-0.5)")
+
+ rg
+ .append('stop')
+ .attr("offset", "0%")
+ .attr("stop-color", "#feffff")
+ rg
+ .append('stop')
+ .attr("offset", "40%")
+ .attr("stop-color", "#cfe2f3")
+
var svgg = svg.append("g")
.attr("transform", "translate(2,2)");
+ svgg
+ .append("rect")
+ .attr("x", 0)
+ .attr("y", 0)
+ .attr("width", 200)
+ .attr("height", 200)
+ .attr("class", "cross-rect")
+ .attr("fill", "url("+urlPrefix+"#cross-gradient)")
+
+ svgg
+ .append("line")
+ .attr("class", "cross-line")
+ .attr({x1: 2, y1: 0, x2: 200, y2: 0})
+ svgg
+ .append("line")
+ .attr("class", "cross-line")
+ .attr({x1: 2, y1: 0, x2: 0, y2: 200})
+
+/*
+ var simpleLine = d3.svg.line();
+ svgg
+ .append('path')
+ .attr({
+ d: simpleLine([[0,0],[0,200]]),
+ stroke: '#000',
+ 'stroke-width': '4px'
+ });
+ svgg
+ .append('path')
+ .attr({
+ d: simpleLine([[0,0],[200,0]]),
+ stroke: '#000',
+ 'stroke-width': '4px'
+ });
+*/
var root = {
name: " Links between " + d.source.name + " and " + d.target.name,
children: []
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[2/3] qpid-dispatch git commit: removing rhea since it is
incorporated in dispatch-management.js
Posted by ea...@apache.org.
removing rhea since it is incorporated in dispatch-management.js
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/9b2b64ff
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/9b2b64ff
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/9b2b64ff
Branch: refs/heads/master
Commit: 9b2b64ff913a959db7bcfb749864e5ce3b8ebb94
Parents: 33feac5
Author: Ernest Allen <ea...@redhat.com>
Authored: Thu Jan 11 09:10:11 2018 -0500
Committer: Ernest Allen <ea...@redhat.com>
Committed: Thu Jan 11 09:10:11 2018 -0500
----------------------------------------------------------------------
console/stand-alone/plugin/lib/rhea-min.js | 6 ------
1 file changed, 6 deletions(-)
----------------------------------------------------------------------
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org