amq-protocol 0.7.0.alpha7 → 0.7.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +9 -2
- data/Gemfile +0 -2
- data/lib/amq/protocol/table.rb +10 -5
- data/lib/amq/protocol/version.rb +1 -1
- data/spec/amq/protocol/table_spec.rb +39 -5
- metadata +22 -45
- data/CONTRIBUTORS +0 -4
- data/examples/00_manual_test.rb +0 -139
data/.travis.yml
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
# https://github.com/travis-ci/travis-ci/wiki/.travis.yml-options
|
2
|
+
bundler_args: --without development
|
1
3
|
script: "bundle exec rspec spec"
|
2
4
|
rvm:
|
3
5
|
- 1.8.7
|
4
|
-
- 1.8.7-p174
|
5
6
|
- 1.9.2
|
6
7
|
- jruby
|
7
8
|
- rbx
|
8
|
-
- ree
|
9
|
+
- ree
|
10
|
+
- 1.8.7-p174
|
11
|
+
notifications:
|
12
|
+
recipients:
|
13
|
+
- jakub@rabbitmq.com
|
14
|
+
- michaelklishin@me.com
|
15
|
+
- markizko@gmail.com
|
data/Gemfile
CHANGED
data/lib/amq/protocol/table.rb
CHANGED
@@ -29,6 +29,10 @@ module AMQ
|
|
29
29
|
TYPE_BYTE_ARRAY = 'x'.freeze
|
30
30
|
TEN = '10'.freeze
|
31
31
|
|
32
|
+
BOOLEAN_TRUE = "\x01".freeze
|
33
|
+
BOOLEAN_FALSE = "\x00".freeze
|
34
|
+
|
35
|
+
|
32
36
|
def self.encode(table)
|
33
37
|
buffer = String.new
|
34
38
|
table ||= {}
|
@@ -47,10 +51,9 @@ module AMQ
|
|
47
51
|
when Float then
|
48
52
|
buffer << TYPE_64BIT_FLOAT
|
49
53
|
buffer << [value].pack(PACK_64BIT_FLOAT)
|
50
|
-
when
|
51
|
-
|
52
|
-
buffer <<
|
53
|
-
buffer << [value].pack(PACK_UINT32)
|
54
|
+
when true, false then
|
55
|
+
buffer << TYPE_BOOLEAN
|
56
|
+
buffer << (value ? BOOLEAN_TRUE : BOOLEAN_FALSE)
|
54
57
|
when Hash then
|
55
58
|
buffer << TYPE_HASH # TODO: encoding support
|
56
59
|
buffer << self.encode(value)
|
@@ -95,6 +98,7 @@ module AMQ
|
|
95
98
|
offset += key_length
|
96
99
|
type = data.slice(offset, 1)
|
97
100
|
offset += 1
|
101
|
+
|
98
102
|
case type
|
99
103
|
when TYPE_STRING
|
100
104
|
length = data.slice(offset, 4).unpack(PACK_UINT32).first
|
@@ -119,8 +123,9 @@ module AMQ
|
|
119
123
|
when TYPE_BOOLEAN
|
120
124
|
value = data.slice(offset, 2)
|
121
125
|
integer = value.unpack(PACK_CHAR).first # 0 or 1
|
122
|
-
value = integer == 1
|
126
|
+
value = (integer == 1)
|
123
127
|
offset += 1
|
128
|
+
value
|
124
129
|
when TYPE_SIGNED_8BIT then raise NotImplementedError.new
|
125
130
|
when TYPE_SIGNED_16BIT then raise NotImplementedError.new
|
126
131
|
when TYPE_SIGNED_64BIT then raise NotImplementedError.new
|
data/lib/amq/protocol/version.rb
CHANGED
@@ -48,12 +48,20 @@ module AMQ
|
|
48
48
|
Table.encode(nil).should eql(encoded_value)
|
49
49
|
end
|
50
50
|
|
51
|
-
it "should return \
|
52
|
-
Table.encode(:test => true).should eql("\x00\x00\x00\
|
51
|
+
it "should return \x00\x00\x00\a\x04testt\x01 for { :test => true }" do
|
52
|
+
Table.encode(:test => true).should eql("\x00\x00\x00\a\x04testt\x01")
|
53
53
|
end
|
54
54
|
|
55
|
-
it "should return \
|
56
|
-
Table.encode(:
|
55
|
+
it "should return \x00\x00\x00\a\x04testt\x00 for { :test => false }" do
|
56
|
+
Table.encode(:test => false).should eql("\x00\x00\x00\a\x04testt\x00")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return \"\x00\x00\x00\n\x04testI\x00\x00\x00\x01\" for { :coordinates => { :latitude => 59.35 } }" do
|
60
|
+
Table.encode(:coordinates => { :latitude => 59.35 }).should eql("\000\000\000#\vcoordinatesF\000\000\000\022\blatituded\315\314\314\314\314\254M@")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return \"\x00\x00\x00\n\x04testI\x00\x00\x00\x01\" for { :coordinates => { :longitude => 18.066667 } }" do
|
64
|
+
Table.encode(:coordinates => { :longitude => 18.066667 }).should eql("\000\000\000$\vcoordinatesF\000\000\000\023\tlongituded\361\270\250\026\021\0212@")
|
57
65
|
end
|
58
66
|
|
59
67
|
DATA.each do |data, encoded|
|
@@ -72,8 +80,34 @@ module AMQ
|
|
72
80
|
it "is capable of decoding what it encodes" do
|
73
81
|
Table.decode(Table.encode(data)).should == data
|
74
82
|
end
|
83
|
+
end # DATA.each
|
84
|
+
|
85
|
+
|
86
|
+
it "is capable of decoding booleans" do
|
87
|
+
input1 = { "boolval" => true }
|
88
|
+
Table.decode(Table.encode(input1)).should == input1
|
89
|
+
|
90
|
+
|
91
|
+
input2 = { "boolval" => false }
|
92
|
+
Table.decode(Table.encode(input2)).should == input2
|
75
93
|
end
|
76
|
-
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
it "is capable of decoding tables" do
|
98
|
+
input = {
|
99
|
+
"boolval" => true,
|
100
|
+
"intval" => 1,
|
101
|
+
"strval" => "Test",
|
102
|
+
"timestampval" => Time.parse("2011-07-14 01:17:46 +0400"),
|
103
|
+
"floatval" => 3.14,
|
104
|
+
"longval" => 912598613,
|
105
|
+
"hashval" => { "protocol" => "AMQP091" }
|
106
|
+
}
|
107
|
+
Table.decode(Table.encode(input)).should == input
|
108
|
+
end
|
109
|
+
|
110
|
+
end # describe
|
77
111
|
end
|
78
112
|
end
|
79
113
|
end
|
metadata
CHANGED
@@ -1,17 +1,10 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: amq-protocol
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.0.beta1
|
5
5
|
prerelease: 6
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 7
|
9
|
-
- 0
|
10
|
-
- alpha
|
11
|
-
- 7
|
12
|
-
version: 0.7.0.alpha7
|
13
6
|
platform: ruby
|
14
|
-
authors:
|
7
|
+
authors:
|
15
8
|
- Jakub Stastny
|
16
9
|
- Michael S. Klishin
|
17
10
|
- Theo Hultberg
|
@@ -19,26 +12,23 @@ authors:
|
|
19
12
|
autorequire:
|
20
13
|
bindir: bin
|
21
14
|
cert_chain: []
|
22
|
-
|
23
|
-
date: 2011-06-16 00:00:00 Z
|
15
|
+
date: 2011-07-13 00:00:00.000000000Z
|
24
16
|
dependencies: []
|
25
|
-
|
26
|
-
|
27
|
-
|
17
|
+
description: ! " amq-protocol is an AMQP 0.9.1 serialization library for Ruby. It
|
18
|
+
is not an\n AMQP client: amq-protocol only handles serialization and deserialization.\n
|
19
|
+
\ If you want to write your own AMQP client, this gem can help you with that.\n"
|
20
|
+
email:
|
28
21
|
- michael@novemberain.com
|
29
22
|
- stastny@101ideas.cz
|
30
23
|
executables: []
|
31
|
-
|
32
24
|
extensions: []
|
33
|
-
|
34
|
-
extra_rdoc_files:
|
25
|
+
extra_rdoc_files:
|
35
26
|
- README.textile
|
36
|
-
files:
|
27
|
+
files:
|
37
28
|
- .gitignore
|
38
29
|
- .gitmodules
|
39
30
|
- .rspec
|
40
31
|
- .travis.yml
|
41
|
-
- CONTRIBUTORS
|
42
32
|
- Gemfile
|
43
33
|
- LICENSE
|
44
34
|
- PROFILING.md
|
@@ -49,7 +39,6 @@ files:
|
|
49
39
|
- amqp_0.9.1_changes.json
|
50
40
|
- codegen.py
|
51
41
|
- codegen_helpers.py
|
52
|
-
- examples/00_manual_test.rb
|
53
42
|
- irb.rb
|
54
43
|
- lib/amq/hacks.rb
|
55
44
|
- lib/amq/protocol.rb
|
@@ -75,38 +64,26 @@ files:
|
|
75
64
|
- tasks.rb
|
76
65
|
homepage: http://github.com/ruby-amqp/amq-protocol
|
77
66
|
licenses: []
|
78
|
-
|
79
67
|
post_install_message:
|
80
68
|
rdoc_options: []
|
81
|
-
|
82
|
-
require_paths:
|
69
|
+
require_paths:
|
83
70
|
- lib
|
84
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
72
|
none: false
|
86
|
-
requirements:
|
87
|
-
- -
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
|
90
|
-
|
91
|
-
- 0
|
92
|
-
version: "0"
|
93
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
78
|
none: false
|
95
|
-
requirements:
|
96
|
-
- -
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
hash: 25
|
99
|
-
segments:
|
100
|
-
- 1
|
101
|
-
- 3
|
102
|
-
- 1
|
79
|
+
requirements:
|
80
|
+
- - ! '>'
|
81
|
+
- !ruby/object:Gem::Version
|
103
82
|
version: 1.3.1
|
104
83
|
requirements: []
|
105
|
-
|
106
84
|
rubyforge_project: amq-protocol
|
107
|
-
rubygems_version: 1.8.
|
85
|
+
rubygems_version: 1.8.4
|
108
86
|
signing_key:
|
109
87
|
specification_version: 3
|
110
88
|
summary: AMQP 0.9.1 encoder & decoder.
|
111
89
|
test_files: []
|
112
|
-
|
data/CONTRIBUTORS
DELETED
data/examples/00_manual_test.rb
DELETED
@@ -1,139 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
# Usage:
|
5
|
-
# ./examples/00_manual_test.rb
|
6
|
-
# ./examples/00_manual_test.rb 5673
|
7
|
-
|
8
|
-
require "socket"
|
9
|
-
require_relative "../lib/amq/protocol/client.rb"
|
10
|
-
|
11
|
-
include AMQ::Protocol
|
12
|
-
|
13
|
-
# Stolen from amq-client:
|
14
|
-
class AMQ::Protocol::Frame
|
15
|
-
def self.decode(io)
|
16
|
-
header = io.read(7)
|
17
|
-
type, channel, size = self.decode_header(header)
|
18
|
-
data = io.read(size + 1)
|
19
|
-
payload, frame_end = data[0..-2], data[-1]
|
20
|
-
|
21
|
-
if frame_end != FINAL_OCTET
|
22
|
-
raise "Frame has to end with #{FINAL_OCTET.inspect}!"
|
23
|
-
end
|
24
|
-
|
25
|
-
self.new(type, payload, channel)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# NOTE: this doesn't work with "localhost", I don't know why:
|
30
|
-
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
31
|
-
sockaddr = Socket.pack_sockaddr_in((ARGV.first || 5672).to_i, "127.0.0.1")
|
32
|
-
|
33
|
-
# helpers
|
34
|
-
def socket.encode(klass, *args)
|
35
|
-
STDERR.puts "#{klass}.encode(#{args.inspect[1..-2]})"
|
36
|
-
result = klass.encode(*args)
|
37
|
-
STDERR.puts "=> #{result}"
|
38
|
-
if result.is_a?(Frame)
|
39
|
-
self.write(result.encode)
|
40
|
-
else
|
41
|
-
data = result.inject("") do |buffer, frame|
|
42
|
-
self.write(frame.encode) ###
|
43
|
-
buffer += frame.encode
|
44
|
-
end
|
45
|
-
# self.write(data)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def socket.decode
|
50
|
-
frame = Frame.decode(self)
|
51
|
-
STDERR.puts "Frame.decode(#{self.inspect})"
|
52
|
-
STDERR.puts "=> #{frame.inspect}"
|
53
|
-
STDERR.puts "frame.decode_payload"
|
54
|
-
STDERR.puts "=> #{res = frame.decode_payload}\n\n"
|
55
|
-
return res
|
56
|
-
end
|
57
|
-
|
58
|
-
begin
|
59
|
-
socket.connect(sockaddr)
|
60
|
-
rescue Errno::ECONNREFUSED
|
61
|
-
abort "Don't forget to start an AMQP broker first!"
|
62
|
-
end
|
63
|
-
|
64
|
-
begin
|
65
|
-
# AMQP preamble
|
66
|
-
puts "Sending AMQP preamble (#{AMQ::Protocol::PREAMBLE.inspect})\n\n"
|
67
|
-
socket.write AMQ::Protocol::PREAMBLE
|
68
|
-
|
69
|
-
# Connection.Start/Connection.Start-Ok
|
70
|
-
connection_start_response = socket.decode
|
71
|
-
socket.encode Connection::StartOk, {client: "AMQ Protocol"}, "PLAIN", "\0guest\0guest", "en_GB"
|
72
|
-
|
73
|
-
# Connection.Tune/Connection.Tune-Ok
|
74
|
-
connection_tune_response = socket.decode
|
75
|
-
channel_max = connection_tune_response.channel_max
|
76
|
-
frame_max = connection_tune_response.frame_max
|
77
|
-
heartbeat = connection_tune_response.heartbeat
|
78
|
-
socket.encode Connection::TuneOk, channel_max, frame_max, heartbeat
|
79
|
-
puts "Max agreed frame size: #{frame_max}"
|
80
|
-
|
81
|
-
# Connection.Open/Connection.Open-Ok
|
82
|
-
socket.encode Connection::Open, "/"
|
83
|
-
connection_open_ok_response = socket.decode
|
84
|
-
|
85
|
-
begin
|
86
|
-
# Channel.Open/Channel.Open-Ok
|
87
|
-
socket.encode Channel::Open, 1, ""
|
88
|
-
channel_open_ok_response = socket.decode
|
89
|
-
|
90
|
-
begin
|
91
|
-
# Exchange.Declare/Exchange.Declare-Ok
|
92
|
-
socket.encode Exchange::Declare, 1, "tasks", "fanout", false, false, false, false, false, {}
|
93
|
-
exchange_declare_ok_response = socket.decode
|
94
|
-
|
95
|
-
# Queue.Declare/Queue.Declare-Ok
|
96
|
-
socket.encode Queue::Declare, 1, "", false, false, false, false, false, {}
|
97
|
-
queue_declare_ok_response = socket.decode
|
98
|
-
|
99
|
-
puts "Queue name: #{queue_declare_ok_response.queue.inspect}"
|
100
|
-
|
101
|
-
# Queue.Bind/Queue.Bind-Ok
|
102
|
-
socket.encode Queue::Bind, 1, queue_declare_ok_response.queue, "tasks", "", false, {}
|
103
|
-
queue_bind_ok_response = socket.decode
|
104
|
-
|
105
|
-
# Basic.Consume
|
106
|
-
socket.encode Basic::Consume, 1, queue_declare_ok_response.queue, "", false, false, false, false, Hash.new
|
107
|
-
|
108
|
-
# Basic.Publish
|
109
|
-
socket.encode Basic::Publish, 1, "this is a payload", {content_type: "text/plain"}, "tasks", "", false, false, frame_max
|
110
|
-
|
111
|
-
# Basic.Consume-Ok
|
112
|
-
basic_consume_ok_response = socket.decode
|
113
|
-
puts "Consumed successfully, consumer tag: #{basic_consume_ok_response.consumer_tag}"
|
114
|
-
|
115
|
-
# Basic.Deliver
|
116
|
-
basic_deliver = socket.decode
|
117
|
-
basic_deliver_header = socket.decode # header frame: {}
|
118
|
-
basic_deliver_body = socket.decode # body frame: "this is a payload"
|
119
|
-
puts "[Received] headers: #{basic_deliver_header.inspect}, payload: #{basic_deliver_body.inspect}"
|
120
|
-
ensure
|
121
|
-
# Channel.Close/Channel.Close-Ok
|
122
|
-
socket.encode Channel::Close, 1, 200, "bye", 0, 0
|
123
|
-
channel_close_ok_response = socket.decode
|
124
|
-
end
|
125
|
-
ensure
|
126
|
-
# Connection.Close/Connection.Close-Ok
|
127
|
-
socket.encode Connection::Close, 200, "", 0, 0
|
128
|
-
close_ok_response = socket.decode
|
129
|
-
end
|
130
|
-
rescue Exception => exception
|
131
|
-
STDERR.puts "\n\e[1;31m[#{exception.class}] #{exception.message}\e[0m"
|
132
|
-
exception.backtrace.each do |line|
|
133
|
-
line = "\e[0;36m#{line}\e[0m" if line.match(Regexp::quote(File.basename(__FILE__)))
|
134
|
-
STDERR.puts " - " + line
|
135
|
-
end
|
136
|
-
exit 1 # Yes, this works with the ensure block, even though the rescue block run first. Magic.
|
137
|
-
ensure
|
138
|
-
socket.close
|
139
|
-
end
|