You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2009/07/06 21:02:12 UTC
svn commit: r791566 - in /qpid/trunk/qpid/ruby/lib/qpid: codec.rb qmf.rb
spec010.rb
Author: tross
Date: Mon Jul 6 19:02:12 2009
New Revision: 791566
URL: http://svn.apache.org/viewvc?rev=791566&view=rev
Log:
QPID-1954 - Patch from Bryan Kearney
Add AM3 features to the ruby console
Modified:
qpid/trunk/qpid/ruby/lib/qpid/codec.rb
qpid/trunk/qpid/ruby/lib/qpid/qmf.rb
qpid/trunk/qpid/ruby/lib/qpid/spec010.rb
Modified: qpid/trunk/qpid/ruby/lib/qpid/codec.rb
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/ruby/lib/qpid/codec.rb?rev=791566&r1=791565&r2=791566&view=diff
==============================================================================
--- qpid/trunk/qpid/ruby/lib/qpid/codec.rb (original)
+++ qpid/trunk/qpid/ruby/lib/qpid/codec.rb Mon Jul 6 19:02:12 2009
@@ -26,6 +26,8 @@
include Qpid::Packer
+ attr_reader :spec
+
def initialize(spec = "")
@spec = spec
end
@@ -415,19 +417,19 @@
end
def read_uuid
- return unpack("A16", 16)
+ return unpack("a16", 16)
end
def write_uuid(s)
- pack("A16", s)
+ pack("a16", s)
end
def read_bin128
- return unpack("A16", 16)
+ return unpack("a16", 16)
end
def write_bin128(b)
- pack("A16", b)
+ pack("a16", b)
end
end
Modified: qpid/trunk/qpid/ruby/lib/qpid/qmf.rb
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/ruby/lib/qpid/qmf.rb?rev=791566&r1=791565&r2=791566&view=diff
==============================================================================
--- qpid/trunk/qpid/ruby/lib/qpid/qmf.rb (original)
+++ qpid/trunk/qpid/ruby/lib/qpid/qmf.rb Mon Jul 6 19:02:12 2009
@@ -238,9 +238,8 @@
# Get the schema for a QMF class
def schema(klass_key)
@brokers.each { |broker| broker.wait_for_stable }
- pname, cname, hash = klass_key
- if @packages.include?(pname)
- @packages[pname][ [cname, hash] ]
+ if @packages.include?(klass_key.package)
+ @packages[klass_key.package][ [klass_key.klass_name, klass_key.hash] ]
end
end
@@ -272,7 +271,7 @@
unless @user_bindings && @rcv_objects
raise "userBindings option not set for Session"
end
- pname, cname, hash = klass_key
+ pname, cname, hash = klass_key.to_a()
@brokers.each do |broker|
args = { :exchange => "qpid.management",
:queue => broker.topic_name,
@@ -361,9 +360,9 @@
cname = nil
if kwargs.include?(:schema)
# FIXME: What kind of object is kwargs[:schema]
- pname, cname, hash = kwargs[:schema].getKey()
+ pname, cname, hash = kwargs[:schema].getKey().to_a
elsif kwargs.include?(:key)
- pname, cname, hash = kwargs[:key]
+ pname, cname, hash = kwargs[:key].to_a
elsif kwargs.include?(:class)
pname, cname, hash = [kwargs[:package], kwargs[:class], nil]
end
@@ -379,7 +378,7 @@
else
map["_class"] = cname
map["_package"] = pname if pname
- map["_hash"] = hash if hash
+ map["_hash"] = hash if hash
kwargs.each do |k,v|
@select << [k, v] if k.is_a?(String)
end
@@ -495,25 +494,22 @@
def handle_class_ind(broker, codec, seq)
kind = codec.read_uint8
- pname = codec.read_str8
- cname = codec.read_str8
- hash = codec.read_bin128
+ classKey = ClassKey.new(codec)
unknown = false
synchronize do
- return unless @packages.include?(pname)
- unknown = true unless @packages[pname].include?([cname, hash])
+ return unless @packages.include?(classKey.package)
+ unknown = true unless @packages[classKey.package].include?([classKey.klass_name, classKey.hash])
end
+
if unknown
# Send a schema request for the unknown class
broker.inc_outstanding
send_codec = Qpid::StringCodec.new(broker.conn.spec)
seq = @seq_mgr.reserve(CONTEXT_STARTUP)
broker.set_header(send_codec, ?S, seq)
- send_codec.write_str8(pname)
- send_codec.write_str8(cname)
- send_codec.write_bin128(hash)
+ classKey.encode(send_codec)
smsg = broker.message(send_codec.encoded)
broker.emit(smsg)
end
@@ -572,31 +568,27 @@
def handle_schema_resp(broker, codec, seq)
kind = codec.read_uint8
- pname = codec.read_str8
- cname = codec.read_str8
- hash = codec.read_bin128
- klass_key = [pname, cname, hash]
- klass = SchemaClass.new(kind, klass_key, codec)
- synchronize { @packages[pname][ [cname, hash] ] = klass }
+ classKey = ClassKey.new(codec)
+ klass = SchemaClass.new(self, kind, classKey, codec)
+ synchronize { @packages[classKey.package][ [classKey.klass_name, classKey.hash] ] = klass }
@seq_mgr.release(seq)
broker.dec_outstanding
- @console.new_class(kind, klass_key) if @console
+ @console.new_class(kind, classKey) if @console
end
def handle_content_ind(broker, codec, seq, prop=false, stat=false)
- pname = codec.read_str8
- cname = codec.read_str8
- hash = codec.read_bin128
- klass_key = [pname, cname, hash]
+ klass_key = ClassKey.new(codec)
+ pname, cname, hash = klass_key.to_a() ;
schema = nil
synchronize do
- return unless @packages.include?(pname)
- return unless @packages[pname].include?([cname, hash])
- schema = @packages[pname][ [cname, hash] ]
+ return unless @packages.include?(klass_key.package)
+ return unless @packages[klass_key.package].include?([klass_key.klass_name, klass_key.hash])
+ schema = @packages[klass_key.package][ [klass_key.klass_name, klass_key.hash] ]
end
+
object = Qpid::Qmf::Object.new(self, broker, schema, codec, prop, stat)
if pname == "org.apache.qpid.broker" && cname == "agent" && prop
broker.update_agent(object)
@@ -641,17 +633,77 @@
when 12: data = codec.read_float # FLOAT
when 13: data = codec.read_double # DOUBLE
when 14: data = codec.read_uuid # UUID
- when 15: data = codec.read_map # FTABLE
+ #when 15: data = codec.read_map # FTABLE
when 16: data = codec.read_int8 # S8
when 17: data = codec.read_int16 # S16
when 18: data = codec.read_int32 # S32
when 19: data = codec.read_int64 # S64
+ when 15: # Ftable
+ data = {}
+ rec_codec = Qpid::StringCodec.new(codec.spec, codec.read_vbin32())
+ if rec_codec.encoded:
+ count = rec_codec.read_uint32()
+ while count > 0 do
+ k = rec_codec.read_str8()
+ code = rec_codec.read_uint8()
+ v = decode_value(rec_codec, code)
+ data[k] = v
+ count -= 1
+ end
+ end
+ when 20: # Object
+ inner_type_code = codec.read_uint8()
+ if (inner_type_code == 20)
+ classKey = ClassKey.new(codec)
+ innerSchema = schema(classKey)
+ data = Object.new(self, @broker, innerSchema, codec, true, true, false) if innerSchema
+ else
+ data = decode_value(codec, inner_type_code)
+ end
+ when 21:
+ data = []
+ rec_codec = Qpid::StringCodec.new(codec.spec, codec.read_vbin32())
+ count = rec_codec.read_uint32()
+ while count > 0 do
+ type = rec_codec.read_uint8()
+ data << (decode_value(rec_codec,type))
+ count -= 1
+ end
+ when 22:
+ data = []
+ rec_codec = Qpid::StringCodec.new(codec.spec, codec.read_vbin32())
+ count = rec_codec.read_uint32()
+ type = rec_codec.read_uint8()
+ while count > 0 do
+ data << (decode_value(rec_codec,type))
+ count -= 1
+ end
else
raise ArgumentError, "Invalid type code: #{typecode} - #{typecode.inspect}"
end
return data
end
+ ENCODINGS = {
+ String => 6,
+ Fixnum => 18,
+ Bignum => 19,
+ Float => 12,
+ Array => 21,
+ Hash => 15
+ }
+
+ def encoding(object)
+ klass = object.class
+ if ENCODINGS.has_key?(klass)
+ return ENCODINGS[klass]
+ end
+ for base in klass.__bases__
+ result = encoding(base)
+ return result unless result.nil?
+ end
+ end
+
# Encode, into the codec, a value based on its typecode
def encode_value(codec, value, typecode)
# FIXME: Python does a lot of magic type conversions
@@ -672,11 +724,46 @@
when 12: codec.write_float(value) # FLOAT
when 13: codec.write_double(value) # DOUBLE
when 14: codec.write_uuid(value) # UUID
- when 15: codec.write_map(value) # FTABLE
+ #when 15: codec.write_map(value) # FTABLE
when 16: codec.write_int8(value) # S8
when 17: codec.write_int16(value) # S16
when 18: codec.write_int32(value) # S32
when 19: codec.write_int64(value) # S64
+ when 20: value.encode(codec)
+ when 15: # FTABLE
+ send_codec = Qpid::StringCodec.new(codec.spec)
+ if !value.nil?
+ send_codec.write_uint32(value.size())
+ value.each do |k,v|
+ mtype = encoding(v)
+ send_codec.write_str8(k.to_s)
+ send_codec.write_uint8(mtype)
+ encode_value(send_codec, v, mtype)
+ end
+ else
+ send_codec.write_uint32(0)
+ codec.write_vbin32(send_codec.encoded)
+ end
+ when 21: # List
+ send_codec = Qpid::StringCodec.new(codec.spec)
+ encode_value(send_codec, value.size, 3)
+ value.each do v
+ ltype = encoding(v)
+ encode_value(send_codec,ltype,1)
+ encode_value(send_codec,v,ltype)
+ end
+ codec.write_vbin32(send_codec.encoded)
+ when 22: # Array
+ send_codec = Qpid::StringCodec.new(codec.spec)
+ encode_value(send_codec, value.size, 3)
+ if value.size > 0
+ ltype = encoding(value[0])
+ encode_value(send_codec,ltype,1)
+ value.each do v
+ encode_value(send_codec,v,ltype)
+ end
+ end
+ codec.write_vbin32(send_codec.encoded)
else
raise ValueError, "Invalid type code: %d" % typecode
end
@@ -702,6 +789,9 @@
when 17: return value.to_s
when 18: return value.to_s
when 19: return value.to_s
+ when 20: return value.to_s
+ when 21: return value.to_s
+ when 22: return value.to_s
else
raise ValueError, "Invalid type code: %d" % typecode
end
@@ -751,10 +841,34 @@
class ClassKey
attr_reader :package, :klass_name, :hash
- def initialize(package, klass_name, hash)
- @package = package
- @klass_name = klass_name
- @hash = hash
+ def initialize(package="", klass_name="", hash=0)
+ if (package.kind_of?(Qpid::Codec))
+ @package = package.read_str8()
+ @klass_name = package.read_str8()
+ @hash = package.read_bin128()
+ else
+ @package = package
+ @klass_name = klass_name
+ @hash = hash
+ end
+ end
+
+ def encode(codec)
+ codec.write_str8(@package)
+ codec.write_str8(@klass_name)
+ codec.write_bin128(@hash)
+ end
+
+ def to_a()
+ return [@package, @klass_name, @hash]
+ end
+
+ def hash_string()
+ "%08x-%08x-%08x-%08x" % hash.unpack("NNNN")
+ end
+
+ def to_s()
+ return "#{@package}:#{@klass_name}(#{hash_string()})"
end
end
@@ -763,11 +877,13 @@
CLASS_KIND_TABLE = 1
CLASS_KIND_EVENT = 2
- attr_reader :klass_key, :properties, :statistics, :methods, :arguments
+ attr_reader :klass_key, :arguments
- def initialize(kind, key, codec)
+ def initialize(session, kind, key, codec)
+ @session = session
@kind = kind
@klass_key = key
+ @super_klass_key = nil
@properties = []
@statistics = []
@methods = []
@@ -779,9 +895,7 @@
stat_count = codec.read_uint16
method_count = codec.read_uint16
if has_supertype == 1
- codec.read_str8
- codec.read_str8
- codec.read_bin128
+ @super_klass_key = ClassKey.new(codec)
end
prop_count.times { |idx|
@properties << SchemaProperty.new(codec) }
@@ -798,8 +912,31 @@
end
end
+ def properties
+ returnValue = @properties
+ if !@super_klass_key.nil?
+ returnValue = @properties + @session.schema(@super_klass_key).properties
+ end
+ return returnValue
+ end
+
+ def statistics
+ returnValue = @statistics
+ if !@super_klass_key.nil?
+ returnValue = @statistics + @session.schema(@super_klass_key).statistics
+ end
+ return returnValue
+ end
+
+ def methods
+ returnValue = @methods
+ if !@super_klass_key.nil?
+ returnValue = @methods + @session.schema(@super_klass_key).methods
+ end
+ return returnValue
+ end
+
def to_s
- pname, cname, hash = @klass_key
if @kind == CLASS_KIND_TABLE
kind_str = "Table"
elsif @kind == CLASS_KIND_EVENT
@@ -807,8 +944,8 @@
else
kind_str = "Unsupported"
end
- result = "%s Class: %s:%s " % [kind_str, pname, cname]
- result += Qpid::UUID::format(hash)
+ result = "%s Class: %s:%s " % [kind_str, @klass_key.package, @klass_key.klass_name]
+ result += Qpid::UUID::format(@klass_key.hash)
return result
end
end
@@ -966,14 +1103,16 @@
attr_reader :object_id, :schema, :properties, :statistics,
:current_time, :create_time, :delete_time, :broker
- def initialize(session, broker, schema, codec, prop, stat)
+ def initialize(session, broker, schema, codec, prop, stat, managed=true)
@session = session
@broker = broker
@schema = schema
- @current_time = codec.read_uint64
- @create_time = codec.read_uint64
- @delete_time = codec.read_uint64
- @object_id = ObjectId.new(codec)
+ if managed
+ @current_time = codec.read_uint64
+ @create_time = codec.read_uint64
+ @delete_time = codec.read_uint64
+ @object_id = ObjectId.new(codec)
+ end
@properties = []
@statistics = []
if prop
@@ -1036,8 +1175,7 @@
end
def to_s
- key = klass_key
- key[0] + ":" + key[1] + "[" + @object_id.to_s() + "] " + index
+ @schema.klass_key.to_s
end
# This must be defined because ruby has this (deprecated) method built in.
@@ -1078,6 +1216,38 @@
raise "Type Object has no attribute '#{name}'"
end
+ def encode(codec)
+ codec.write_uint8(20)
+ @schema.klass_key.encode(codec)
+
+ # emit presence masks for optional properties
+ mask = 0
+ bit = 0
+ schema.properties.each do |property|
+ if prop.optional
+ bit = 1 if bit == 0
+ mask |= bit if value
+ bit = bit << 1
+ if bit == 256
+ bit = 0
+ codec.write_uint8(mask)
+ mask = 0
+ end
+ codec.write_uint8(mask) if bit != 0
+ end
+ end
+
+ # encode properties
+ @properties.each do |property, value|
+ @session.encode_value(codec, value, prop.type) if value
+ end
+
+ # encode statistics
+ @statistics.each do |statistic, value|
+ @session.encode_value(codec, value, stat.type)
+ end
+ end
+
private
def send_method_request(method, name, args, synchronous = false, time_wait = nil)
@@ -1087,10 +1257,7 @@
seq = @session.seq_mgr.reserve([schema_method, synchronous])
@broker.set_header(send_codec, ?M, seq)
@object_id.encode(send_codec)
- pname, cname, hash = @schema.klass_key
- send_codec.write_str8(pname)
- send_codec.write_str8(cname)
- send_codec.write_bin128(hash)
+ @schema.klass_key.encode(send_codec)
send_codec.write_str8(name)
formals = method.arguments.select { |arg| arg.dir.index(?I) }
@@ -1171,7 +1338,7 @@
class MethodResult
- attr_reader :status, :text
+ attr_reader :status, :text, :out_args
def initialize(status, text, out_args)
@status = status
@@ -1189,7 +1356,16 @@
end
def to_s
- "#{text} (#{status}) - #{out_args.inspect}"
+ argsString = ""
+ padding = ""
+ out_args.each do |key,value|
+ argsString += padding
+ padding = " " if padding == ""
+ argsString += key.to_s
+ argsString += " => "
+ argsString += value.to_s()
+ end
+ "MethodResult(Msg: '#{text}' Status: #{status} Return: [#{argsString}])"
end
end
@@ -1579,13 +1755,12 @@
def initialize(session, broker, codec)
@session = session
@broker = broker
- pname = codec.read_str8
- cname = codec.read_str8
- hash = codec.read_bin128
- @klass_key = [pname, cname, hash]
+ @klass_key = ClassKey.new(codec)
@timestamp = codec.read_int64
@severity = codec.read_uint8
@schema = nil
+
+ pname, cname, hash = @klass_key.to_a()
session.packages.keys.each do |pname|
k = [cname, hash]
if session.packages[pname].include?(k)
@@ -1603,7 +1778,7 @@
return "<uninterpretable>" unless @schema
t = Time.at(self.timestamp / 1000000000)
out = t.strftime("%c")
- out += " " + sev_name + " " + @klass_key[0] + ":" + klass_key[1]
+ out += " " + sev_name + " " + @klass_key.package + ":" + @klass_key.klass_name
out += " broker=" + @broker.url
@schema.arguments.each do |arg|
out += " " + arg.name + "=" + @session.display_value(@arguments[arg.name], arg.type)
Modified: qpid/trunk/qpid/ruby/lib/qpid/spec010.rb
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/ruby/lib/qpid/spec010.rb?rev=791566&r1=791565&r2=791566&view=diff
==============================================================================
--- qpid/trunk/qpid/ruby/lib/qpid/spec010.rb (original)
+++ qpid/trunk/qpid/ruby/lib/qpid/spec010.rb Mon Jul 6 19:02:12 2009
@@ -32,7 +32,7 @@
class Spec
ENCODINGS = {
- String => "vbin16",
+ String => "str16",
Fixnum => "int64",
Bignum => "int64",
Float => "float",
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org