:key => 'routing key'* :key => 'routing_key' - Specifies the routing key for
the binding.
* :nowait => true or false (_default_) - Ignored by Bunny, always _false_.
==== RETURNS:
:unbind_ok if successful.
=end
def unbind(exchange, opts = {})
exchange = exchange.respond_to?(:name) ? exchange.name : exchange
# ignore the :nowait option if passed, otherwise program will hang waiting for a
# response that will not be sent by the server
opts.delete(:nowait)
opts = {
:queue => name,
:exchange => exchange,
:routing_key => opts.delete(:key),
:nowait => false
}.merge(opts)
client.send_frame(Qrack::Protocol::Queue::Unbind.new(opts))
method = client.next_method
client.check_response(method, Qrack::Protocol::Queue::UnbindOk, "Error unbinding queue #{name}")
# return message
:unbind_ok
end
private
def exchange
@exchange ||= Bunny::Exchange.new(client, '', {:type => :direct, :key => name})
end
end
end
bunny-0.7.8/lib/bunny.rb 0000644 0000764 0000764 00000005225 11704323672 014154 0 ustar pravi pravi # encoding: utf-8
require "socket"
require "thread"
require "timeout"
require "logger"
require File.expand_path("../bunny/version", __FILE__)
# if we don't require the version file the same way as in the gemspec,
# the version file will be loaded twice. and we hate warnings.
module Bunny
class ConnectionError < StandardError; end
class ForcedChannelCloseError < StandardError; end
class ForcedConnectionCloseError < StandardError; end
class MessageError < StandardError; end
class ProtocolError < StandardError; end
class ServerDownError < StandardError; end
class UnsubscribeError < StandardError; end
class AcknowledgementError < StandardError; end
# Returns the Bunny version number
def self.version
VERSION
end
# Print deprecation warning.
def self.deprecation_warning(method, version, explanation)
warn "~ #{method} will be removed in Bunny #{version}. #{explanation}"
end
# Instantiates new Bunny::Client
def self.new(connection_string_or_opts = Hash.new, opts = Hash.new)
# Set up Bunny according to AMQP spec version required
if connection_string_or_opts.respond_to?(:keys) && opts.empty?
opts = connection_string_or_opts
end
spec_version = opts[:spec] || '08'
# Return client
setup(spec_version, connection_string_or_opts, opts)
end
# Runs a code block using a short-lived connection
def self.run(opts = {}, &block)
raise ArgumentError, 'Bunny#run requires a block' unless block
# Set up Bunny according to AMQP spec version required
spec_version = opts[:spec] || '08'
client = setup(spec_version, opts)
begin
client.start
block.call(client)
ensure
client.stop
end
# Return success
:run_ok
end
Timer = if RUBY_VERSION < "1.9"
begin
require File.expand_path(File.join(File.dirname(__FILE__), 'system_timer.rb'))
Bunny::SystemTimer
rescue LoadError
Timeout
end
else
Timeout
end
private
def self.setup(version, *args)
if version == '08'
# AMQP 0-8 specification
require 'qrack/qrack08'
require 'bunny/client08'
require 'bunny/exchange08'
require 'bunny/queue08'
require 'bunny/channel08'
require 'bunny/subscription08'
client = Bunny::Client.new(*args)
else
# AMQP 0-9-1 specification
require 'qrack/qrack09'
require 'bunny/client09'
require 'bunny/exchange09'
require 'bunny/queue09'
require 'bunny/channel09'
require 'bunny/subscription09'
client = Bunny::Client09.new(*args)
end
include Qrack
client
end
end
bunny-0.7.8/README.textile 0000644 0000764 0000764 00000002641 11704323672 014262 0 ustar pravi pravi h1. About
Bunny is a synchronous "AMQP":http://bit.ly/hw2ELX client. It supports Ruby 1.9.2, 1.8.7, Ruby Enterprise Edition and JRuby. Protocol-wise, Bunny supports AMQP 0.9.1 and 0.8. Support for AMQP 0.8 will be dropped in the next version of Bunny (0.7) because most of popular AMQP brokers such as RabbitMQ already stopped or planning to stop supporting it in the near future.
Bunny is based on a great deal of useful code from the "amqp Ruby gem":http://github.com/ruby-amqp/amqp and "Carrot":http://github.com/famoseagle/carrot.
You can use Bunny to:
* Create and delete exchanges
* Create and delete queues
* Publish and consume messages
h1. Quick Start
require "bunny"
b = Bunny.new(:logging => true)
# start a communication session with the amqp server
b.start
# declare a queue
q = b.queue("test1")
# publish a message to the queue
q.publish("Hello everybody!")
# get message from the queue
msg = q.pop[:payload]
puts "This is the message: " + msg + "\n\n"
# close the connection
b.stop
... or just:
require "bunny"
# Create a direct queue named "my_testq"
Bunny.run { |c| c.queue("my_testq") }
Please see the @examples@ directory for additional usage information.
h1. Links
* "Source code":http://github.com/ruby-amqp/bunny
* "@rubyamqp":http://twitter.com/rubyamqp at Twitter
* "Ruby AMQP Google Group":http://groups.google.com/group/ruby-amqp
* "Blog":http://bunnyamqp.wordpress.com
bunny-0.7.8/examples/ 0000755 0000764 0000764 00000000000 11704323672 013540 5 ustar pravi pravi bunny-0.7.8/examples/simple_08.rb 0000644 0000764 0000764 00000001360 11704323672 015665 0 ustar pravi pravi # encoding: utf-8
# simple_08.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:logging => true)
# start a communication session with the amqp server
b.start
# declare a queue
q = b.queue('test1')
# publish a message to the queue
q.publish('➸ Hello everybody ☺!')
# get message from the queue
msg = q.pop[:payload]
puts 'This is the message: ' + msg + "\n\n"
# close the client connection
b.stop
bunny-0.7.8/examples/simple_topic_08.rb 0000644 0000764 0000764 00000003576 11704323672 017076 0 ustar pravi pravi # encoding: utf-8
# simple_topic_08.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new
# start a communication session with the amqp server
b.start
# declare queues
soccer = b.queue('topic_soccer')
cricket = b.queue('topic_cricket')
rugby = b.queue('topic_rugby')
allsport = b.queue('topic_allsport')
# create a topic exchange
sports_results = b.exchange('sports_results', :type => :topic)
# bind the queues to the exchange
soccer.bind(sports_results, :key => 'soccer.*')
cricket.bind(sports_results, :key => 'cricket.*')
rugby.bind(sports_results, :key => 'rugby.*')
allsport.bind(sports_results, :key => '*.result')
# publish messages to the exchange
sports_results.publish('Manchester United 1 : Hull City 4', :key => 'soccer.result')
sports_results.publish('England beat Australia by 5 wickets in first test', :key => 'cricket.result')
sports_results.publish('British Lions 15 : South Africa 12', :key => 'rugby.result')
# get message from the queues
# soccer queue got the soccer message
msg = soccer.pop[:payload]
puts 'This is a message from the soccer q: ' + msg + "\n\n"
# cricket queue got the cricket message
msg = cricket.pop[:payload]
puts 'This is a message from the cricket q: ' + msg + "\n\n"
# rugby queue got the rugby message
msg = rugby.pop[:payload]
puts 'This is a message from the rugby q: ' + msg + "\n\n"
# allsport queue got all of the messages
until msg == :queue_empty do
msg = allsport.pop[:payload]
puts 'This is a message from the allsport q: ' + msg + "\n\n" unless msg == :queue_empty
end
# close the client connection
b.stop
bunny-0.7.8/examples/simple_publisher_09.rb 0000644 0000764 0000764 00000001530 11704323672 017742 0 ustar pravi pravi # encoding: utf-8
# simple_publisher.rb
# N.B. To be used in conjunction with simple_consumer.rb. See simple_consumer.rb for explanation.
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:logging => true, :spec => '09')
# start a communication session with the amqp server
b.start
# create/get exchange
exch = b.exchange('sorting_room')
# publish message to exchange
exch.publish('This is a message from the publisher', :key => 'fred')
# message should now be picked up by the consumer so we can stop
b.stop
bunny-0.7.8/examples/simple_09.rb 0000644 0000764 0000764 00000001377 11704323672 015676 0 ustar pravi pravi # encoding: utf-8
# simple_09.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:logging => true, :spec => '09')
# start a communication session with the amqp server
b.start
# declare a queue
q = b.queue('test1')
# publish a message to the queue
q.publish('➸ Hello everybody ☺!')
# get message from the queue
msg = q.pop[:payload]
puts 'This is the message: ' + msg + "\n\n"
# close the client connection
b.stop
bunny-0.7.8/examples/simple_publisher_08.rb 0000644 0000764 0000764 00000001517 11704323672 017746 0 ustar pravi pravi # encoding: utf-8
# simple_publisher_08.rb
# N.B. To be used in conjunction with simple_consumer_08.rb. See simple_consumer.rb for explanation.
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:logging => true)
# start a communication session with the amqp server
b.start
# create/get exchange
exch = b.exchange('sorting_room')
# publish message to exchange
exch.publish('This is a message from the publisher', :key => 'fred')
# message should now be picked up by the consumer so we can stop
b.stop
bunny-0.7.8/examples/simple_consumer_08.rb 0000644 0000764 0000764 00000003003 11704323672 017574 0 ustar pravi pravi # encoding: utf-8
# simple_consumer_08.rb
# N.B. To be used in conjunction with simple_publisher.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
# How this example works
#=======================
#
# Open up two console windows start this program in one of them by typing -
#
# ruby simple_consumer_08.rb
#
# Then switch to the other console window and type -
#
# ruby simple_publisher_08.rb
#
# A message will be printed out by the simple_consumer and it will wait for the next message
# until the timeout interval is reached.
#
# Run simple_publisher as many times as you like. When you want the program to stop just stop
# sending messages and the subscribe loop will timeout after 30 seconds, the program will
# unsubscribe from the queue and close the connection to the server.
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:logging => true)
# start a communication session with the amqp server
b.start
# create/get queue
q = b.queue('po_box')
# create/get exchange
exch = b.exchange('sorting_room')
# bind queue to exchange
q.bind(exch, :key => 'fred')
# subscribe to queue
q.subscribe(:consumer_tag => 'testtag1', :timeout => 30) do |msg|
puts "#{q.subscription.message_count}: #{msg[:payload]}"
end
# Close client
b.stop
bunny-0.7.8/examples/simple_headers_08.rb 0000644 0000764 0000764 00000002214 11704323672 017357 0 ustar pravi pravi # encoding: utf-8
# simple_headers_08.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new
# start a communication session with the amqp server
b.start
# declare queues
q = b.queue('header_q1')
# create a headers exchange
header_exch = b.exchange('header_exch', :type => :headers)
# bind the queue to the exchange
q.bind(header_exch, :arguments => {'h1'=>'a','x-match'=>'all'})
# publish messages to the exchange
header_exch.publish('Headers test msg 1', :headers => {'h1'=>'a'})
header_exch.publish('Headers test msg 2', :headers => {'h1'=>'z'})
# get messages from the queue - should only be msg 1 that got through
msg = ""
until msg == :queue_empty do
msg = q.pop[:payload]
puts 'This is a message from the header_q1 queue: ' + msg + "\n" unless msg == :queue_empty
end
# close the client connection
b.stop
bunny-0.7.8/examples/simple_consumer_09.rb 0000644 0000764 0000764 00000003022 11704323672 017576 0 ustar pravi pravi # encoding: utf-8
# simple_consumer_09.rb
# N.B. To be used in conjunction with simple_publisher.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
# How this example works
#=======================
#
# Open up two console windows start this program in one of them by typing -
#
# ruby simple_consumer_09.rb
#
# Then switch to the other console window and type -
#
# ruby simple_publisher_09.rb
#
# A message will be printed out by the simple_consumer and it will wait for the next message
# until the timeout interval is reached.
#
# Run simple_publisher as many times as you like. When you want the program to stop just stop
# sending messages and the subscribe loop will timeout after 30 seconds, the program will
# unsubscribe from the queue and close the connection to the server.
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:logging => true, :spec => '09')
# start a communication session with the amqp server
b.start
# create/get queue
q = b.queue('po_box')
# create/get exchange
exch = b.exchange('sorting_room')
# bind queue to exchange
q.bind(exch, :key => 'fred')
# subscribe to queue
q.subscribe(:consumer_tag => 'testtag1', :timeout => 30) do |msg|
puts "#{q.subscription.message_count}: #{msg[:payload]}"
end
# Close client
b.stop
bunny-0.7.8/examples/simple_ack_09.rb 0000644 0000764 0000764 00000001471 11704323672 016507 0 ustar pravi pravi # encoding: utf-8
# simple_ack_09.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:logging => true, :spec => '09')
# start a communication session with the amqp server
b.start
# declare a queue
q = b.queue('test1')
# publish a message to the queue
q.publish('Testing acknowledgements')
# get message from the queue
msg = q.pop(:ack => true)[:payload]
# acknowledge receipt of message
q.ack
puts 'This is the message: ' + msg + "\n\n"
# close the client connection
b.stop
bunny-0.7.8/examples/simple_fanout_09.rb 0000644 0000764 0000764 00000002020 11704323672 017234 0 ustar pravi pravi # encoding: utf-8
# simple_fanout_09.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:logging => true, :spec => '09')
# start a communication session with the amqp server
b.start
# declare queues
q1 = b.queue('test_fan1')
q2 = b.queue('test_fan2')
# create a fanout exchange
exch = b.exchange('test_fan', :type => :fanout)
# bind the queues to the exchange
q1.bind(exch)
q2.bind(exch)
# publish a message to the exchange
exch.publish('This message will be fanned out')
# get message from the queues
msg = q1.pop[:payload]
puts 'This is the message from q1: ' + msg + "\n\n"
msg = q2.pop[:payload]
puts 'This is the message from q2: ' + msg + "\n\n"
# close the client connection
b.stop
bunny-0.7.8/examples/simple_ack_08.rb 0000644 0000764 0000764 00000001452 11704323672 016505 0 ustar pravi pravi # encoding: utf-8
# simple_ack_08.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:logging => true)
# start a communication session with the amqp server
b.start
# declare a queue
q = b.queue('test1')
# publish a message to the queue
q.publish('Testing acknowledgements')
# get message from the queue
msg = q.pop(:ack => true)[:payload]
# acknowledge receipt of message
q.ack
puts 'This is the message: ' + msg + "\n\n"
# close the client connection
b.stop
bunny-0.7.8/examples/simple_topic_09.rb 0000644 0000764 0000764 00000003615 11704323672 017071 0 ustar pravi pravi # encoding: utf-8
# simple_topic_09.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:spec => '09')
# start a communication session with the amqp server
b.start
# declare queues
soccer = b.queue('topic_soccer')
cricket = b.queue('topic_cricket')
rugby = b.queue('topic_rugby')
allsport = b.queue('topic_allsport')
# create a topic exchange
sports_results = b.exchange('sports_results', :type => :topic)
# bind the queues to the exchange
soccer.bind(sports_results, :key => 'soccer.*')
cricket.bind(sports_results, :key => 'cricket.*')
rugby.bind(sports_results, :key => 'rugby.*')
allsport.bind(sports_results, :key => '*.result')
# publish messages to the exchange
sports_results.publish('Manchester United 1 : Hull City 4', :key => 'soccer.result')
sports_results.publish('England beat Australia by 5 wickets in first test', :key => 'cricket.result')
sports_results.publish('British Lions 15 : South Africa 12', :key => 'rugby.result')
# get message from the queues
# soccer queue got the soccer message
msg = soccer.pop[:payload]
puts 'This is a message from the soccer q: ' + msg + "\n\n"
# cricket queue got the cricket message
msg = cricket.pop[:payload]
puts 'This is a message from the cricket q: ' + msg + "\n\n"
# rugby queue got the rugby message
msg = rugby.pop[:payload]
puts 'This is a message from the rugby q: ' + msg + "\n\n"
# allsport queue got all of the messages
until msg == :queue_empty do
msg = allsport.pop[:payload]
puts 'This is a message from the allsport q: ' + msg + "\n\n" unless msg == :queue_empty
end
# close the client connection
b.stop
bunny-0.7.8/examples/simple_headers_09.rb 0000644 0000764 0000764 00000002233 11704323672 017361 0 ustar pravi pravi # encoding: utf-8
# simple_headers_09.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:spec => '09')
# start a communication session with the amqp server
b.start
# declare queues
q = b.queue('header_q1')
# create a headers exchange
header_exch = b.exchange('header_exch', :type => :headers)
# bind the queue to the exchange
q.bind(header_exch, :arguments => {'h1'=>'a','x-match'=>'all'})
# publish messages to the exchange
header_exch.publish('Headers test msg 1', :headers => {'h1'=>'a'})
header_exch.publish('Headers test msg 2', :headers => {'h1'=>'z'})
# get messages from the queue - should only be msg 1 that got through
msg = ""
until msg == :queue_empty do
msg = q.pop[:payload]
puts 'This is a message from the header_q1 queue: ' + msg + "\n" unless msg == :queue_empty
end
# close the client connection
b.stop
bunny-0.7.8/examples/simple_fanout_08.rb 0000644 0000764 0000764 00000002001 11704323672 017232 0 ustar pravi pravi # encoding: utf-8
# simple_fanout_08.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'bunny'
b = Bunny.new(:logging => true)
# start a communication session with the amqp server
b.start
# declare queues
q1 = b.queue('test_fan1')
q2 = b.queue('test_fan2')
# create a fanout exchange
exch = b.exchange('test_fan', :type => :fanout)
# bind the queues to the exchange
q1.bind(exch)
q2.bind(exch)
# publish a message to the exchange
exch.publish('This message will be fanned out')
# get message from the queues
msg = q1.pop[:payload]
puts 'This is the message from q1: ' + msg + "\n\n"
msg = q2.pop[:payload]
puts 'This is the message from q2: ' + msg + "\n\n"
# close the client connection
b.stop
bunny-0.7.8/metadata.yml 0000644 0000764 0000764 00000006452 11704323672 014234 0 ustar pravi pravi --- !ruby/object:Gem::Specification
name: bunny
version: !ruby/object:Gem::Version
version: 0.7.8
prerelease:
platform: ruby
authors:
- Chris Duncan
- Eric Lindvall
- Jakub Stastny aka botanicus
- Michael S. Klishin
- Stefan Kaes
autorequire:
bindir: bin
cert_chain: []
date: 2011-10-11 00:00:00.000000000 +02:00
default_executable:
dependencies: []
description: A synchronous Ruby AMQP client that enables interaction with AMQP-compliant
brokers.
email:
- celldee@gmail.com
- eric@5stops.com
- stastny@101ideas.cz
- michael@novemberain.com
- skaes@railsexpress.de
executables: []
extensions: []
extra_rdoc_files:
- README.textile
files:
- .gitignore
- .rspec
- .travis.yml
- .yardopts
- CHANGELOG
- Gemfile
- LICENSE
- README.textile
- Rakefile
- bunny.gemspec
- examples/simple_08.rb
- examples/simple_09.rb
- examples/simple_ack_08.rb
- examples/simple_ack_09.rb
- examples/simple_consumer_08.rb
- examples/simple_consumer_09.rb
- examples/simple_fanout_08.rb
- examples/simple_fanout_09.rb
- examples/simple_headers_08.rb
- examples/simple_headers_09.rb
- examples/simple_publisher_08.rb
- examples/simple_publisher_09.rb
- examples/simple_topic_08.rb
- examples/simple_topic_09.rb
- ext/amqp-0.8.json
- ext/amqp-0.9.1.json
- ext/config.yml
- ext/qparser.rb
- lib/bunny.rb
- lib/bunny/channel08.rb
- lib/bunny/channel09.rb
- lib/bunny/client08.rb
- lib/bunny/client09.rb
- lib/bunny/consumer.rb
- lib/bunny/exchange08.rb
- lib/bunny/exchange09.rb
- lib/bunny/queue08.rb
- lib/bunny/queue09.rb
- lib/bunny/subscription08.rb
- lib/bunny/subscription09.rb
- lib/bunny/system_timer.rb
- lib/bunny/version.rb
- lib/qrack/amq-client-url.rb
- lib/qrack/channel.rb
- lib/qrack/client.rb
- lib/qrack/errors.rb
- lib/qrack/protocol/protocol08.rb
- lib/qrack/protocol/protocol09.rb
- lib/qrack/protocol/spec08.rb
- lib/qrack/protocol/spec09.rb
- lib/qrack/qrack08.rb
- lib/qrack/qrack09.rb
- lib/qrack/queue.rb
- lib/qrack/subscription.rb
- lib/qrack/transport/buffer08.rb
- lib/qrack/transport/buffer09.rb
- lib/qrack/transport/frame08.rb
- lib/qrack/transport/frame09.rb
- spec/spec_08/bunny_spec.rb
- spec/spec_08/connection_spec.rb
- spec/spec_08/exchange_spec.rb
- spec/spec_08/queue_spec.rb
- spec/spec_09/amqp_url_spec.rb
- spec/spec_09/bunny_spec.rb
- spec/spec_09/connection_spec.rb
- spec/spec_09/exchange_spec.rb
- spec/spec_09/queue_spec.rb
has_rdoc: true
homepage: http://github.com/ruby-amqp/bunny
licenses: []
post_install_message: ! "[\e[32mVersion 0.7.8\e[0m] test suite cleanup (eliminated
some race conditions related to queue.message_count)\n"
rdoc_options:
- --main
- README.rdoc
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
none: false
requirements:
- - ! '>='
- !ruby/object:Gem::Version
version: '0'
required_rubygems_version: !ruby/object:Gem::Requirement
none: false
requirements:
- - ! '>='
- !ruby/object:Gem::Version
version: '0'
requirements: []
rubyforge_project: bunny-amqp
rubygems_version: 1.6.2
signing_key:
specification_version: 3
summary: Synchronous Ruby AMQP 0.9.1 client
test_files:
- spec/spec_08/bunny_spec.rb
- spec/spec_08/connection_spec.rb
- spec/spec_08/exchange_spec.rb
- spec/spec_08/queue_spec.rb
- spec/spec_09/amqp_url_spec.rb
- spec/spec_09/bunny_spec.rb
- spec/spec_09/connection_spec.rb
- spec/spec_09/exchange_spec.rb
- spec/spec_09/queue_spec.rb
bunny-0.7.8/LICENSE 0000644 0000764 0000764 00000002210 11704323672 012722 0 ustar pravi pravi Copyright (c) 2009 – 2011 Chris Duncan, Jakub Stastny aka botanicus,
Michael S. Klishin, Eric Lindvall, Stefan Kaes and contributors.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
bunny-0.7.8/ext/ 0000755 0000764 0000764 00000000000 11704323672 012522 5 ustar pravi pravi bunny-0.7.8/ext/qparser.rb 0000644 0000764 0000764 00000031206 11704323672 014526 0 ustar pravi pravi # encoding: utf-8
require 'json'
require 'erb'
require 'pathname'
require 'yaml'
def spec_v8_0_0?(spec)
spec['major'] == '8' && spec['minor'] == '0' && spec['revision'] == '0'
end
def spec_details(spec)
meta = {}
meta['major'] = spec['major-version']
meta['minor'] = spec['minor-version']
meta['revision'] = spec['revision'] || '0'
meta['port'] = spec['port']
meta['comment'] = "AMQ Protocol version #{meta['major']}.#{meta['minor']}.#{meta['revision']}"
meta
end
def process_constants(spec)
# AMQP constants
frame_constants = {}
other_constants = {}
spec['constants'].each do |constant|
if constant['name'].match(/^frame/i)
frame_constants[constant['value'].to_i] =
constant['name'].sub(/^frame./i,'').split(/\s|-/).map{|w| w.downcase.capitalize}.join
else
other_constants[constant['value']] = constant['name']
end
end
[frame_constants.sort, other_constants.sort]
end
def domain_types(spec, major, minor, revision)
# AMQP domain types
# add types that may be missing in the spec version
dt_arr = add_types(spec)
spec["domains"].each do |domain|
# JSON spec gives domain types as two element arrays like ["channel-id", "longstr"]
dt_arr << domain.last
end
# Return sorted array
dt_arr.uniq.sort
end
def classes(spec, major, minor, revision)
# AMQP classes
spec['classes'].map do |amqp_class|
cls_hash = {}
cls_hash[:name] = amqp_class['name']
cls_hash[:index] = amqp_class['id']
# Get fields for class
cls_hash[:fields] = fields(amqp_class) # are these amqp_class["properties"] ?
# Get methods for class
meth_arr = class_methods(amqp_class)
# Add missing methods
add_arr =[]
add_arr = add_methods(spec) if cls_hash[:name] == 'queue'
method_arr = meth_arr + add_arr
# Add array to class hash
cls_hash[:methods] = method_arr
cls_hash
end
end
# Get methods for class
def class_methods(amqp_class)
amqp_class['methods'].map do |method|
meth_hash = {}
meth_hash[:name] = method['name']
meth_hash[:index] = method['id']
# Get fields for method
meth_hash[:fields] = fields(method)
meth_hash
end
end
# Get the fields for a class or method
def fields(element)
# The JSON spec puts these in "properties" for a class and "arguments" for a
# method
(element['arguments'] || element['properties'] || []).map do |field|
field_hash = {}
field_hash[:name] = field['name'].tr(' ', '-')
field_hash[:domain] = field['type'] || field['domain']
# Convert domain type if necessary
conv_arr = convert_type(field_hash[:domain])
field_hash[:domain] = conv_arr.last unless conv_arr.empty?
field_hash
end
end
def add_types(spec)
spec_v8_0_0?(spec) ? ['long', 'longstr', 'octet', 'timestamp'] : []
end
def add_methods(spec)
meth_arr = []
if spec_v8_0_0?(spec)
# Add Queue Unbind method
meth_hash = {:name => 'unbind',
:index => '50',
:fields => [{:name => 'ticket', :domain => 'short'},
{:name => 'queue', :domain => 'shortstr'},
{:name => 'exchange', :domain => 'shortstr'},
{:name => 'routing_key', :domain => 'shortstr'},
{:name => 'arguments', :domain => 'table'}
]
}
meth_arr << meth_hash
# Add Queue Unbind-ok method
meth_hash = {:name => 'unbind-ok',
:index => '51',
:fields => []
}
meth_arr << meth_hash
end
# Return methods
meth_arr
end
def convert_type(name)
type_arr = @type_conversion.select {|k,v| k == name}.flatten
end
# Start of Main program
# Read in config options
CONFIG = YAML::load(File.read('config.yml'))
# Get path to the spec file and the spec file name on its own
specpath = CONFIG[:spec_in]
path = Pathname.new(specpath)
specfile = path.basename.to_s
# Read in the spec file
spec = JSON.parse(IO.read(specpath))
# Declare type conversion hash
@type_conversion = {'path' => 'shortstr',
'known hosts' => 'shortstr',
'known-hosts' => 'shortstr',
'reply code' => 'short',
'reply-code' => 'short',
'reply text' => 'shortstr',
'reply-text' => 'shortstr',
'class id' => 'short',
'class-id' => 'short',
'method id' => 'short',
'method-id' => 'short',
'channel-id' => 'longstr',
'access ticket' => 'short',
'access-ticket' => 'short',
'exchange name' => 'shortstr',
'exchange-name' => 'shortstr',
'queue name' => 'shortstr',
'queue-name' => 'shortstr',
'consumer tag' => 'shortstr',
'consumer-tag' => 'shortstr',
'delivery tag' => 'longlong',
'delivery-tag' => 'longlong',
'redelivered' => 'bit',
'no ack' => 'bit',
'no-ack' => 'bit',
'no local' => 'bit',
'no-local' => 'bit',
'peer properties' => 'table',
'peer-properties' => 'table',
'destination' => 'shortstr',
'duration' => 'longlong',
'security-token' => 'longstr',
'reject-code' => 'short',
'reject-text' => 'shortstr',
'offset' => 'longlong',
'no-wait' => 'bit',
'message-count' => 'long'
}
# Spec details
spec_info = spec_details(spec)
# Constants
constants = process_constants(spec)
# Frame constants
frame_constants = constants[0].select {|k,v| k <= 8}
frame_footer = constants[0].select {|k,v| v == 'End'}[0][0]
# Other constants
other_constants = constants[1]
# Domain types
data_types = domain_types(spec, spec_info['major'], spec_info['minor'], spec_info['revision'])
# Classes
class_defs = classes(spec, spec_info['major'], spec_info['minor'], spec_info['revision'])
# Generate spec.rb
spec_rb = File.open(CONFIG[:spec_out], 'w')
spec_rb.puts(
ERB.new(%q[
# encoding: utf-8
#:stopdoc:
# this file was autogenerated on <%= Time.now.to_s %>
# using <%= specfile.ljust(16) %> (mtime: <%= File.mtime(specpath) %>)
#
# DO NOT EDIT! (edit ext/qparser.rb and config.yml instead, and run 'ruby qparser.rb')
module Qrack
module Protocol
HEADER = "AMQP".freeze
VERSION_MAJOR = <%= spec_info['major'] %>
VERSION_MINOR = <%= spec_info['minor'] %>
REVISION = <%= spec_info['revision'] %>
PORT = <%= spec_info['port'] %>
RESPONSES = {
<%- other_constants.each do |value, name| -%>
<%= value %> => :<%= name.gsub(/\s|-/, '_').upcase -%>,
<%- end -%>
}
FIELDS = [
<%- data_types.each do |d| -%>
:<%= d -%>,
<%- end -%>
]
class Class
class << self
FIELDS.each do |f|
class_eval %[
def #{f} name
properties << [ :#{f}, name ] unless properties.include?([:#{f}, name])
attr_accessor name
end
]
end
def properties() @properties ||= [] end
def id() self::ID end
def name() self::NAME.to_s end
end
class Method
class << self
FIELDS.each do |f|
class_eval %[
def #{f} name
arguments << [ :#{f}, name ] unless arguments.include?([:#{f}, name])
attr_accessor name
end
]
end
def arguments() @arguments ||= [] end
def parent() Protocol.const_get(self.to_s[/Protocol::(.+?)::/,1]) end
def id() self::ID end
def name() self::NAME.to_s end
end
def == b
self.class.arguments.inject(true) do |eql, (type, name)|
eql and __send__("#{name}") == b.__send__("#{name}")
end
end
end
def self.methods() @methods ||= {} end
def self.Method(id, name)
@_base_methods ||= {}
@_base_methods[id] ||= ::Class.new(Method) do
class_eval %[
def self.inherited klass
klass.const_set(:ID, #{id})
klass.const_set(:NAME, :#{name.to_s})
klass.parent.methods[#{id}] = klass
klass.parent.methods[klass::NAME] = klass
end
]
end
end
end
def self.classes() @classes ||= {} end
def self.Class(id, name)
@_base_classes ||= {}
@_base_classes[id] ||= ::Class.new(Class) do
class_eval %[
def self.inherited klass
klass.const_set(:ID, #{id})
klass.const_set(:NAME, :#{name.to_s})
Protocol.classes[#{id}] = klass
Protocol.classes[klass::NAME] = klass
end
]
end
end
end
end
module Qrack
module Protocol
<%- class_defs.each do |h| -%>
class <%= h[:name].capitalize.ljust(12) %> < Class( <%= h[:index].to_s.rjust(3) %>, :<%= h[:name].ljust(12) %> ); end
<%- end -%>
<%- class_defs.each do |c| -%>
class <%= c[:name].capitalize %>
<%- c[:fields].each do |p| -%>
<%= p[:domain].ljust(10) %> :<%= p[:name].tr('-','_') %>
<%- end if c[:fields] -%>
<%- c[:methods].each do |m| -%>
class <%= m[:name].capitalize.gsub(/-(.)/){ "#{$1.upcase}"}.ljust(12) %> < Method( <%= m[:index].to_s.rjust(3) %>, :<%= m[:name].tr('- ','_').ljust(14) %> ); end
<%- end -%>
<%- c[:methods].each do |m| -%>
class <%= m[:name].capitalize.gsub(/-(.)/){ "#{$1.upcase}"} %>
<%- m[:fields].each do |a| -%>
<%- if a[:domain] -%>
<%= a[:domain].ljust(16) %> :<%= a[:name].tr('- ','_') %>
<%- end -%>
<%- end -%>
end
<%- end -%>
end
<%- end -%>
end
end
].gsub!(/^ /,''), nil, '>-%').result(binding)
)
# Close spec.rb file
spec_rb.close
# Generate frame.rb file
frame_rb = File.open(CONFIG[:frame_out], 'w')
frame_rb.puts(
ERB.new(%q[
# encoding: utf-8
#:stopdoc:
# this file was autogenerated on <%= Time.now.to_s %>
#
# DO NOT EDIT! (edit ext/qparser.rb and config.yml instead, and run 'ruby qparser.rb')
module Qrack
module Transport
class Frame
FOOTER = <%= frame_footer %>
ID = 0
@types = {
<%- frame_constants.each do |value, name| -%>
<%= value %> => '<%= name %>',
<%- end -%>
}
attr_accessor :channel, :payload
def initialize payload = nil, channel = 0
@channel, @payload = channel, payload
end
def id
self.class::ID
end
def to_binary
buf = Transport::Buffer.new
buf.write :octet, id
buf.write :short, channel
buf.write :longstr, payload
buf.write :octet, FOOTER
buf.rewind
buf
end
def to_s
to_binary.to_s
end
def == frame
[ :id, :channel, :payload ].inject(true) do |eql, field|
eql and __send__(field) == frame.__send__(field)
end
end
def self.parse buf
buf = Transport::Buffer.new(buf) unless buf.is_a? Transport::Buffer
buf.extract do
id, channel, payload, footer = buf.read(:octet, :short, :longstr, :octet)
Qrack::Transport.const_get(@types[id]).new(payload, channel) if footer == FOOTER
end
end
end
class Method < Frame
ID = 1
def initialize payload = nil, channel = 0
super
unless @payload.is_a? Protocol::Class::Method or @payload.nil?
@payload = Protocol.parse(@payload)
end
end
end
class Header < Frame
ID = 2
def initialize payload = nil, channel = 0
super
unless @payload.is_a? Protocol::Header or @payload.nil?
@payload = Protocol::Header.new(@payload)
end
end
end
<%- frame_constants.each do |value, name| -%>
<%- if value > 2 -%>
class <%= name %> < Frame
ID = <%= value %>
end
<%- end -%>
<%- end -%>
end
end
].gsub!(/^ /,''), nil, '>-%').result(binding)
)
# Close frame.rb file
frame_rb.close
bunny-0.7.8/ext/amqp-0.9.1.json 0000644 0000764 0000764 00000037604 11704323672 015030 0 ustar pravi pravi {
"name": "AMQP",
"major-version": 0,
"minor-version": 9,
"revision": 1,
"port": 5672,
"copyright": [
"Copyright (C) 2008-2009 LShift Ltd, Cohesive Financial Technologies LLC,\n",
"and Rabbit Technologies Ltd\n",
"\n",
"Permission is hereby granted, free of charge, to any person\n",
"obtaining a copy of this file (the \"Software\"), to deal in the\n",
"Software without restriction, including without limitation the \n",
"rights to use, copy, modify, merge, publish, distribute, \n",
"sublicense, and/or sell copies of the Software, and to permit \n",
"persons to whom the Software is furnished to do so, subject to \n",
"the following conditions:\n",
"\n",
"The above copyright notice and this permission notice shall be\n",
"included in all copies or substantial portions of the Software.\n",
"\n",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n",
"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n",
"OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n",
"NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n",
"HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n",
"WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
"FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n",
"OTHER DEALINGS IN THE SOFTWARE.\n",
"\n",
"Class information entered from amqp_xml0-8.pdf and domain types from amqp-xml-doc0-9.pdf\n",
"Updated for 0-9-1 by Tony Garnock-Jones\n",
"\n",
"b3cb053f15e7b98808c0ccc67f23cb3e amqp_xml0-8.pdf\n",
"http://www.twiststandards.org/index.php?option=com_docman&task=cat_view&gid=28&&Itemid=90\n",
"8444db91e2949dbecfb2585e9eef6d64 amqp-xml-doc0-9.pdf\n",
"https://jira.amqp.org/confluence/download/attachments/720900/amqp-xml-doc0-9.pdf?version=1\n"],
"domains": [
["bit", "bit"],
["channel-id", "longstr"],
["class-id", "short"],
["consumer-tag", "shortstr"],
["delivery-tag", "longlong"],
["destination", "shortstr"],
["duration", "longlong"],
["exchange-name", "shortstr"],
["long", "long"],
["longlong", "longlong"],
["longstr", "longstr"],
["method-id", "short"],
["no-ack", "bit"],
["no-local", "bit"],
["octet", "octet"],
["offset", "longlong"],
["path", "shortstr"],
["peer-properties", "table"],
["queue-name", "shortstr"],
["redelivered", "bit"],
["reference", "longstr"],
["reject-code", "short"],
["reject-text", "shortstr"],
["reply-code", "short"],
["reply-text", "shortstr"],
["security-token", "longstr"],
["short", "short"],
["shortstr", "shortstr"],
["table", "table"],
["timestamp", "timestamp"]
],
"constants": [
{"name": "FRAME-METHOD", "value": 1},
{"name": "FRAME-HEADER", "value": 2},
{"name": "FRAME-BODY", "value": 3},
{"name": "FRAME-HEARTBEAT", "value": 8},
{"name": "FRAME-MIN-SIZE", "value": 4096},
{"name": "FRAME-END", "value": 206},
{"name": "REPLY-SUCCESS", "value": 200},
{"name": "CONTENT-TOO-LARGE", "value": 311, "class": "soft-error"},
{"name": "NO-ROUTE", "value": 312, "class": "soft-error"},
{"name": "NO-CONSUMERS", "value": 313, "class": "soft-error"},
{"name": "ACCESS-REFUSED", "value": 403, "class": "soft-error"},
{"name": "NOT-FOUND", "value": 404, "class": "soft-error"},
{"name": "RESOURCE-LOCKED", "value": 405, "class": "soft-error"},
{"name": "PRECONDITION-FAILED", "value": 406, "class": "soft-error"},
{"name": "CONNECTION-FORCED", "value": 320, "class": "hard-error"},
{"name": "INVALID-PATH", "value": 402, "class": "hard-error"},
{"name": "FRAME-ERROR", "value": 501, "class": "hard-error"},
{"name": "SYNTAX-ERROR", "value": 502, "class": "hard-error"},
{"name": "COMMAND-INVALID", "value": 503, "class": "hard-error"},
{"name": "CHANNEL-ERROR", "value": 504, "class": "hard-error"},
{"name": "UNEXPECTED-FRAME", "value": 505, "class": "hard-error"},
{"name": "RESOURCE-ERROR", "value": 506, "class": "hard-error"},
{"name": "NOT-ALLOWED", "value": 530, "class": "hard-error"},
{"name": "NOT-IMPLEMENTED", "value": 540, "class": "hard-error"},
{"name": "INTERNAL-ERROR", "value": 541, "class": "hard-error"}
],
"classes": [
{
"id": 10,
"methods": [{"id": 10,
"arguments": [{"type": "octet", "name": "version-major", "default-value": 0},
{"type": "octet", "name": "version-minor", "default-value": 8},
{"domain": "peer-properties", "name": "server properties"},
{"type": "longstr", "name": "mechanisms", "default-value": "PLAIN"},
{"type": "longstr", "name": "locales", "default-value": "en_US"}],
"name": "start"},
{"id": 11,
"arguments": [{"domain": "peer-properties", "name": "client-properties"},
{"type": "shortstr", "name": "mechanism", "default-value": "PLAIN"},
{"type": "longstr", "name": "response"},
{"type": "shortstr", "name": "locale", "default-value": "en_US"}],
"name": "start-ok"},
{"id": 20,
"arguments": [{"type": "longstr", "name": "challenge"}],
"name": "secure"},
{"id": 21,
"arguments": [{"type": "longstr", "name": "response"}],
"name": "secure-ok"},
{"id": 30,
"arguments": [{"type": "short", "name": "channel-max", "default-value": 0},
{"type": "long", "name": "frame-max", "default-value": 0},
{"type": "short", "name": "heartbeat", "default-value": 0}],
"name": "tune"},
{"id": 31,
"arguments": [{"type": "short", "name": "channel-max", "default-value": 0},
{"type": "long", "name": "frame-max", "default-value": 0},
{"type": "short", "name": "heartbeat", "default-value": 0}],
"name": "tune-ok"},
{"id": 40,
"arguments": [{"type": "shortstr", "name": "virtual-host", "default-value": "/"},
{"type": "shortstr", "name": "deprecated-capabilities", "default-value": ""},
{"type": "bit", "name": "deprecated-insist", "default-value": false}],
"name": "open"},
{"id": 41,
"arguments": [{"type": "shortstr", "name": "deprecated-known-hosts", "default-value": ""}],
"name": "open-ok"},
{"id": 50,
"arguments": [{"type": "short", "name": "reply-code"},
{"type": "shortstr", "name": "reply-text", "default-value": ""},
{"type": "short", "name": "class-id"},
{"type": "short", "name": "method-id"}],
"name": "close"},
{"id": 51,
"arguments": [],
"name": "close-ok"}],
"name": "connection",
"properties": []
},
{
"id": 20,
"methods": [{"id": 10,
"arguments": [{"type": "shortstr", "name": "deprecated-out-of-band", "default-value": ""}],
"name": "open"},
{"id": 11,
"arguments": [{"type": "longstr", "name": "deprecated-channel-id", "default-value": ""}],
"name": "open-ok"},
{"id": 20,
"arguments": [{"type": "bit", "name": "active"}],
"name": "flow"},
{"id": 21,
"arguments": [{"type": "bit", "name": "active"}],
"name": "flow-ok"},
{"id": 40,
"arguments": [{"type": "short", "name": "reply-code"},
{"type": "shortstr", "name": "reply-text", "default-value": ""},
{"type": "short", "name": "class-id"},
{"type": "short", "name": "method-id"}],
"name": "close"},
{"id": 41,
"arguments": [],
"name": "close-ok"}],
"name": "channel"
},
{
"id": 40,
"methods": [{"id": 10,
"arguments": [{"type": "short", "name": "deprecated-ticket", "default-value": 1},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "type", "default-value": "direct"},
{"type": "bit", "name": "passive", "default-value": false},
{"type": "bit", "name": "durable", "default-value": false},
{"type": "bit", "name": "deprecated-auto-delete", "default-value": false},
{"type": "bit", "name": "deprecated-internal", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false},
{"type": "table", "name": "arguments", "default-value": {}}],
"name": "declare"},
{"id": 11,
"arguments": [],
"name": "declare-ok"},
{"id": 20,
"arguments": [{"type": "short", "name": "deprecated-ticket", "default-value": 1},
{"type": "shortstr", "name": "exchange"},
{"type": "bit", "name": "if-unused", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "delete"},
{"id": 21,
"arguments": [],
"name": "delete-ok"}],
"name": "exchange"
},
{
"id": 50,
"methods": [{"id": 10,
"arguments": [{"type": "short", "name": "deprecated-ticket", "default-value": 1},
{"type": "shortstr", "name": "queue", "default-value": ""},
{"type": "bit", "name": "passive", "default-value": false},
{"type": "bit", "name": "durable", "default-value": false},
{"type": "bit", "name": "exclusive", "default-value": false},
{"type": "bit", "name": "auto-delete", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false},
{"type": "table", "name": "arguments", "default-value": {}}],
"name": "declare"},
{"id": 11,
"arguments": [{"type": "shortstr", "name": "queue"},
{"type": "long", "name": "message-count"},
{"type": "long", "name": "consumer-count"}],
"name": "declare-ok"},
{"id": 20,
"arguments": [{"type": "short", "name": "deprecated-ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"},
{"type": "bit", "name": "nowait", "default-value": false},
{"type": "table", "name": "arguments", "default-value": {}}],
"name": "bind"},
{"id": 21,
"arguments": [],
"name": "bind-ok"},
{"id": 30,
"arguments": [{"type": "short", "name": "deprecated-ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "purge"},
{"id": 31,
"arguments": [{"type": "long", "name": "message-count"}],
"name": "purge-ok"},
{"id": 40,
"arguments": [{"type": "short", "name": "deprecated-ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "bit", "name": "if-unused", "default-value": false},
{"type": "bit", "name": "if-empty", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "delete"},
{"id": 41,
"arguments": [{"type": "long", "name": "message-count"}],
"name": "delete-ok"},
{"id": 50,
"arguments": [{"type": "short", "name": "deprecated-ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"},
{"type": "table", "name": "arguments"}],
"name": "unbind"},
{"id": 51,
"arguments": [],
"name": "unbind-ok"}
],
"name": "queue"
},
{
"id": 60,
"methods": [{"id": 10,
"arguments": [{"type": "long", "name": "prefetch-size", "default-value": 0},
{"type": "short", "name": "prefetch-count", "default-value": 0},
{"type": "bit", "name": "global", "default-value": false}],
"name": "qos"},
{"id": 11,
"arguments": [],
"name": "qos-ok"},
{"id": 20,
"arguments": [{"domain": "short", "name": "deprecated-ticket", "default-value": 1},
{"domain": "queue-name", "name": "queue"},
{"type": "shortstr", "name": "consumer-tag"},
{"type": "bit", "name": "no-local", "default-value": false},
{"type": "bit", "name": "no-ack", "default-value": false},
{"type": "bit", "name": "exclusive", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false},
{"type": "table", "name": "filter", "default-value": {}}],
"name": "consume"},
{"id": 21,
"arguments": [{"type": "shortstr", "name": "consumer-tag"}],
"name": "consume-ok"},
{"id": 30,
"arguments": [{"type": "shortstr", "name": "consumer-tag"},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "cancel"},
{"id": 31,
"arguments": [{"type": "shortstr", "name": "consumer-tag"}],
"name": "cancel-ok"},
{"content": true,
"id": 40,
"arguments": [{"type": "short", "name": "deprecated-ticket", "default-value": 1},
{"type": "shortstr", "name": "exchange", "default-value": ""},
{"type": "shortstr", "name": "routing-key"},
{"type": "bit", "name": "mandatory", "default-value": false},
{"type": "bit", "name": "immediate", "default-value": false}],
"name": "publish"},
{"content": true,
"id": 50,
"arguments": [{"type": "short", "name": "reply-code"},
{"type": "shortstr", "name": "reply-text", "default-value": ""},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"}],
"name": "return"},
{"content": true,
"id": 60,
"arguments": [{"type": "shortstr", "name": "consumer-tag"},
{"type": "longlong", "name": "delivery-tag"},
{"type": "bit", "name": "redelivered", "default-value": false},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"}],
"name": "deliver"},
{"id": 70,
"arguments": [{"type": "short", "name": "deprecated-ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "bit", "name": "no-ack", "default-value": false}],
"name": "get"},
{"content": true,
"id": 71,
"arguments": [{"type": "longlong", "name": "delivery-tag"},
{"type": "bit", "name": "redelivered", "default-value": false},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"},
{"type": "long", "name": "message-count"}],
"name": "get-ok"},
{"id": 72,
"arguments": [{"type": "shortstr", "name": "deprecated-cluster-id", "default-value": ""}],
"name": "get-empty"},
{"id": 80,
"arguments": [{"type": "longlong", "name": "delivery-tag", "default-value": 0},
{"type": "bit", "name": "multiple", "default-value": true}],
"name": "ack"},
{"id": 90,
"arguments": [{"type": "longlong", "name": "delivery-tag"},
{"type": "bit", "name": "requeue", "default-value": true}],
"name": "reject"},
{"id": 100,
"arguments": [{"type": "bit", "name": "requeue", "default-value": false}],
"name": "recover-async"},
{"id": 110,
"arguments": [{"type": "bit", "name": "requeue", "default-value": false}],
"name": "recover"},
{"id": 111,
"arguments": [],
"name": "recover-ok"}],
"name": "basic",
"properties": [{"type": "shortstr", "name": "content-type"},
{"type": "shortstr", "name": "content-encoding"},
{"type": "table", "name": "headers"},
{"type": "octet", "name": "delivery-mode"},
{"type": "octet", "name": "priority"},
{"type": "shortstr", "name": "correlation-id"},
{"type": "shortstr", "name": "reply-to"},
{"type": "shortstr", "name": "expiration"},
{"type": "shortstr", "name": "message-id"},
{"type": "timestamp", "name": "timestamp"},
{"type": "shortstr", "name": "type"},
{"type": "shortstr", "name": "user-id"},
{"type": "shortstr", "name": "app-id"},
{"type": "shortstr", "name": "deprecated-cluster-id"}]
},
{
"id": 90,
"methods": [{"id": 10,
"arguments": [],
"name": "select"},
{"id": 11,
"arguments": [],
"name": "select-ok"},
{"id": 20,
"arguments": [],
"name": "commit"},
{"id": 21,
"arguments": [],
"name": "commit-ok"},
{"id": 30,
"arguments": [],
"name": "rollback"},
{"id": 31,
"arguments": [],
"name": "rollback-ok"}],
"name": "tx"
}
]
}
bunny-0.7.8/ext/config.yml 0000644 0000764 0000764 00000000173 11704323672 014513 0 ustar pravi pravi ---
:spec_out: '../lib/qrack/protocol/spec08.rb'
:frame_out: '../lib/qrack/transport/frame08.rb'
:spec_in: 'amqp-0.8.json'
bunny-0.7.8/ext/amqp-0.8.json 0000644 0000764 0000764 00000061227 11704323672 014666 0 ustar pravi pravi {
"name": "AMQP",
"major-version": 8,
"minor-version": 0,
"port": 5672,
"copyright": [
"Copyright (C) 2008-2009 LShift Ltd, Cohesive Financial Technologies LLC,\n",
"and Rabbit Technologies Ltd\n",
"\n",
"Permission is hereby granted, free of charge, to any person\n",
"obtaining a copy of this file (the \"Software\"), to deal in the\n",
"Software without restriction, including without limitation the \n",
"rights to use, copy, modify, merge, publish, distribute, \n",
"sublicense, and/or sell copies of the Software, and to permit \n",
"persons to whom the Software is furnished to do so, subject to \n",
"the following conditions:\n",
"\n",
"The above copyright notice and this permission notice shall be\n",
"included in all copies or substantial portions of the Software.\n",
"\n",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n",
"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n",
"OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n",
"NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n",
"HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n",
"WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
"FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n",
"OTHER DEALINGS IN THE SOFTWARE.\n",
"\n",
"Class information entered from amqp_xml0-8.pdf and domain types from amqp-xml-doc0-9.pdf\n",
"\n",
"b3cb053f15e7b98808c0ccc67f23cb3e amqp_xml0-8.pdf\n",
"http://www.twiststandards.org/index.php?option=com_docman&task=cat_view&gid=28&&Itemid=90\n",
"8444db91e2949dbecfb2585e9eef6d64 amqp-xml-doc0-9.pdf\n",
"https://jira.amqp.org/confluence/download/attachments/720900/amqp-xml-doc0-9.pdf?version=1\n"],
"domains": [
["access-ticket", "short"],
["bit", "bit"],
["channel-id", "longstr"],
["class-id", "short"],
["consumer-tag", "shortstr"],
["delivery-tag", "longlong"],
["destination", "shortstr"],
["duration", "longlong"],
["exchange-name", "shortstr"],
["known-hosts", "shortstr"],
["long", "long"],
["longlong", "longlong"],
["longstr", "longstr"],
["method-id", "short"],
["no-ack", "bit"],
["no-local", "bit"],
["octet", "octet"],
["offset", "longlong"],
["path", "shortstr"],
["peer-properties", "table"],
["queue-name", "shortstr"],
["redelivered", "bit"],
["reference", "longstr"],
["reject-code", "short"],
["reject-text", "shortstr"],
["reply-code", "short"],
["reply-text", "shortstr"],
["security-token", "longstr"],
["short", "short"],
["shortstr", "shortstr"],
["table", "table"],
["timestamp", "timestamp"]
],
"constants": [
{"name": "FRAME-METHOD", "value": 1},
{"name": "FRAME-HEADER", "value": 2},
{"name": "FRAME-BODY", "value": 3},
{"name": "FRAME-OOB-METHOD", "value": 4},
{"name": "FRAME-OOB-HEADER", "value": 5},
{"name": "FRAME-OOB-BODY", "value": 6},
{"name": "FRAME-TRACE", "value": 7},
{"name": "FRAME-HEARTBEAT", "value": 8},
{"name": "FRAME-MIN-SIZE", "value": 4096},
{"name": "FRAME-END", "value": 206},
{"name": "REPLY-SUCCESS", "value": 200},
{"name": "NOT-DELIVERED", "value": 310, "class": "soft-error"},
{"name": "CONTENT-TOO-LARGE", "value": 311, "class": "soft-error"},
{"name": "NO-ROUTE", "value": 312, "class": "soft-error"},
{"name": "NO-CONSUMERS", "value": 313, "class": "soft-error"},
{"name": "ACCESS-REFUSED", "value": 403, "class": "soft-error"},
{"name": "NOT-FOUND", "value": 404, "class": "soft-error"},
{"name": "RESOURCE-LOCKED", "value": 405, "class": "soft-error"},
{"name": "PRECONDITION-FAILED", "value": 406, "class": "soft-error"},
{"name": "CONNECTION-FORCED", "value": 320, "class": "hard-error"},
{"name": "INVALID-PATH", "value": 402, "class": "hard-error"},
{"name": "FRAME-ERROR", "value": 501, "class": "hard-error"},
{"name": "SYNTAX-ERROR", "value": 502, "class": "hard-error"},
{"name": "COMMAND-INVALID", "value": 503, "class": "hard-error"},
{"name": "CHANNEL-ERROR", "value": 504, "class": "hard-error"},
{"name": "RESOURCE-ERROR", "value": 506, "class": "hard-error"},
{"name": "NOT-ALLOWED", "value": 530, "class": "hard-error"},
{"name": "NOT-IMPLEMENTED", "value": 540, "class": "hard-error"},
{"name": "INTERNAL-ERROR", "value": 541, "class": "hard-error"}
],
"classes": [
{
"id": 10,
"methods": [{"id": 10,
"arguments": [{"type": "octet", "name": "version-major", "default-value": 0},
{"type": "octet", "name": "version-minor", "default-value": 8},
{"domain": "peer-properties", "name": "server properties"},
{"type": "longstr", "name": "mechanisms", "default-value": "PLAIN"},
{"type": "longstr", "name": "locales", "default-value": "en_US"}],
"name": "start"},
{"id": 11,
"arguments": [{"domain": "peer-properties", "name": "client-properties"},
{"type": "shortstr", "name": "mechanism", "default-value": "PLAIN"},
{"type": "longstr", "name": "response"},
{"type": "shortstr", "name": "locale", "default-value": "en_US"}],
"name": "start-ok"},
{"id": 20,
"arguments": [{"type": "longstr", "name": "challenge"}],
"name": "secure"},
{"id": 21,
"arguments": [{"type": "longstr", "name": "response"}],
"name": "secure-ok"},
{"id": 30,
"arguments": [{"type": "short", "name": "channel-max", "default-value": 0},
{"type": "long", "name": "frame-max", "default-value": 0},
{"type": "short", "name": "heartbeat", "default-value": 0}],
"name": "tune"},
{"id": 31,
"arguments": [{"type": "short", "name": "channel-max", "default-value": 0},
{"type": "long", "name": "frame-max", "default-value": 0},
{"type": "short", "name": "heartbeat", "default-value": 0}],
"name": "tune-ok"},
{"id": 40,
"arguments": [{"type": "shortstr", "name": "virtual-host", "default-value": "/"},
{"type": "shortstr", "name": "capabilities", "default-value": ""},
{"type": "bit", "name": "insist", "default-value": false}],
"name": "open"},
{"id": 41,
"arguments": [{"type": "shortstr", "name": "known-hosts", "default-value": ""}],
"name": "open-ok"},
{"id": 50,
"arguments": [{"type": "shortstr", "name": "host"},
{"type": "shortstr", "name": "known-hosts", "default-value": ""}],
"name": "redirect"},
{"id": 60,
"arguments": [{"type": "short", "name": "reply-code"},
{"type": "shortstr", "name": "reply-text", "default-value": ""},
{"type": "short", "name": "class-id"},
{"type": "short", "name": "method-id"}],
"name": "close"},
{"id": 61,
"arguments": [],
"name": "close-ok"}],
"name": "connection",
"properties": []
},
{
"id": 20,
"methods": [{"id": 10,
"arguments": [{"type": "shortstr", "name": "out-of-band", "default-value": ""}],
"name": "open"},
{"id": 11,
"arguments": [],
"name": "open-ok"},
{"id": 20,
"arguments": [{"type": "bit", "name": "active"}],
"name": "flow"},
{"id": 21,
"arguments": [{"type": "bit", "name": "active"}],
"name": "flow-ok"},
{"id": 30,
"arguments": [{"type": "short", "name": "reply-code"},
{"type": "shortstr", "name": "reply-text", "default-value": ""},
{"type": "table", "name": "details", "default-value": {}}],
"name": "alert"},
{"id": 40,
"arguments": [{"type": "short", "name": "reply-code"},
{"type": "shortstr", "name": "reply-text", "default-value": ""},
{"type": "short", "name": "class-id"},
{"type": "short", "name": "method-id"}],
"name": "close"},
{"id": 41,
"arguments": [],
"name": "close-ok"}],
"name": "channel"
},
{
"id": 30,
"methods": [{"id": 10,
"arguments": [{"type": "shortstr", "name": "realm", "default-value": "/data"},
{"type": "bit", "name": "exclusive", "default-value": false},
{"type": "bit", "name": "passive", "default-value": true},
{"type": "bit", "name": "active", "default-value": true},
{"type": "bit", "name": "write", "default-value": true},
{"type": "bit", "name": "read", "default-value": true}],
"name": "request"},
{"id": 11,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1}],
"name": "request-ok"}],
"name": "access"
},
{
"id": 40,
"methods": [{"id": 10,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "type", "default-value": "direct"},
{"type": "bit", "name": "passive", "default-value": false},
{"type": "bit", "name": "durable", "default-value": false},
{"type": "bit", "name": "auto-delete", "default-value": false},
{"type": "bit", "name": "internal", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false},
{"type": "table", "name": "arguments", "default-value": {}}],
"name": "declare"},
{"id": 11,
"arguments": [],
"name": "declare-ok"},
{"id": 20,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "exchange"},
{"type": "bit", "name": "if-unused", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "delete"},
{"id": 21,
"arguments": [],
"name": "delete-ok"}],
"name": "exchange"
},
{
"id": 50,
"methods": [{"id": 10,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "queue", "default-value": ""},
{"type": "bit", "name": "passive", "default-value": false},
{"type": "bit", "name": "durable", "default-value": false},
{"type": "bit", "name": "exclusive", "default-value": false},
{"type": "bit", "name": "auto-delete", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false},
{"type": "table", "name": "arguments", "default-value": {}}],
"name": "declare"},
{"id": 11,
"arguments": [{"type": "shortstr", "name": "queue"},
{"type": "long", "name": "message-count"},
{"type": "long", "name": "consumer-count"}],
"name": "declare-ok"},
{"id": 20,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"},
{"type": "bit", "name": "nowait", "default-value": false},
{"type": "table", "name": "arguments", "default-value": {}}],
"name": "bind"},
{"id": 21,
"arguments": [],
"name": "bind-ok"},
{"id": 30,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "purge"},
{"id": 31,
"arguments": [{"type": "long", "name": "message-count"}],
"name": "purge-ok"},
{"id": 40,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "bit", "name": "if-unused", "default-value": false},
{"type": "bit", "name": "if-empty", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "delete"},
{"id": 41,
"arguments": [{"type": "long", "name": "message-count"}],
"name": "delete-ok"},
{"id": 50,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"},
{"type": "table", "name": "arguments"}],
"name": "unbind"},
{"id": 51,
"arguments": [],
"name": "unbind-ok"}
],
"name": "queue"
},
{
"id": 60,
"methods": [{"id": 10,
"arguments": [{"type": "long", "name": "prefetch-size", "default-value": 0},
{"type": "short", "name": "prefetch-count", "default-value": 0},
{"type": "bit", "name": "global", "default-value": false}],
"name": "qos"},
{"id": 11,
"arguments": [],
"name": "qos-ok"},
{"id": 20,
"arguments": [{"domain": "access-ticket", "name": "ticket", "default-value": 1},
{"domain": "queue-name", "name": "queue"},
{"type": "shortstr", "name": "consumer-tag"},
{"type": "bit", "name": "no-local", "default-value": false},
{"type": "bit", "name": "no-ack", "default-value": false},
{"type": "bit", "name": "exclusive", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "consume"},
{"id": 21,
"arguments": [{"type": "shortstr", "name": "consumer-tag"}],
"name": "consume-ok"},
{"id": 30,
"arguments": [{"type": "shortstr", "name": "consumer-tag"},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "cancel"},
{"id": 31,
"arguments": [{"type": "shortstr", "name": "consumer-tag"}],
"name": "cancel-ok"},
{"content": true,
"id": 40,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "exchange", "default-value": ""},
{"type": "shortstr", "name": "routing-key"},
{"type": "bit", "name": "mandatory", "default-value": false},
{"type": "bit", "name": "immediate", "default-value": false}],
"name": "publish"},
{"content": true,
"id": 50,
"arguments": [{"type": "short", "name": "reply-code"},
{"type": "shortstr", "name": "reply-text", "default-value": ""},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"}],
"name": "return"},
{"content": true,
"id": 60,
"arguments": [{"type": "shortstr", "name": "consumer-tag"},
{"type": "longlong", "name": "delivery-tag"},
{"type": "bit", "name": "redelivered", "default-value": false},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"}],
"name": "deliver"},
{"id": 70,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "bit", "name": "no-ack", "default-value": false}],
"name": "get"},
{"content": true,
"id": 71,
"arguments": [{"type": "longlong", "name": "delivery-tag"},
{"type": "bit", "name": "redelivered", "default-value": false},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"},
{"type": "long", "name": "message-count"}],
"name": "get-ok"},
{"id": 72,
"arguments": [{"type": "shortstr", "name": "cluster-id", "default-value": ""}],
"name": "get-empty"},
{"id": 80,
"arguments": [{"type": "longlong", "name": "delivery-tag", "default-value": 0},
{"type": "bit", "name": "multiple", "default-value": true}],
"name": "ack"},
{"id": 90,
"arguments": [{"type": "longlong", "name": "delivery-tag"},
{"type": "bit", "name": "requeue", "default-value": true}],
"name": "reject"},
{"id": 100,
"arguments": [{"type": "bit", "name": "requeue", "default-value": false}],
"name": "recover"}],
"name": "basic",
"properties": [{"type": "shortstr", "name": "content-type"},
{"type": "shortstr", "name": "content-encoding"},
{"type": "table", "name": "headers"},
{"type": "octet", "name": "delivery-mode"},
{"type": "octet", "name": "priority"},
{"type": "shortstr", "name": "correlation-id"},
{"type": "shortstr", "name": "reply-to"},
{"type": "shortstr", "name": "expiration"},
{"type": "shortstr", "name": "message-id"},
{"type": "timestamp", "name": "timestamp"},
{"type": "shortstr", "name": "type"},
{"type": "shortstr", "name": "user-id"},
{"type": "shortstr", "name": "app-id"},
{"type": "shortstr", "name": "cluster-id"}]
},
{
"id": 70,
"methods": [{"id": 10,
"arguments": [{"type": "long", "name": "prefetch-size", "default-value": 0},
{"type": "short", "name": "prefetch-count", "default-value": 0},
{"type": "bit", "name": "global", "default-value": false}],
"name": "qos"},
{"id": 11,
"arguments": [],
"name": "qos-ok"},
{"id": 20,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "shortstr", "name": "consumer-tag"},
{"type": "bit", "name": "no-local", "default-value": false},
{"type": "bit", "name": "no-ack", "default-value": false},
{"type": "bit", "name": "exclusive", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "consume"},
{"id": 21,
"arguments": [{"type": "shortstr", "name": "consumer-tag"}],
"name": "consume-ok"},
{"id": 30,
"arguments": [{"type": "shortstr", "name": "consumer-tag"},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "cancel"},
{"id": 31,
"arguments": [{"type": "shortstr", "name": "consumer-tag"}],
"name": "cancel-ok"},
{"id": 40,
"arguments": [{"type": "shortstr", "name": "identifier"},
{"type": "longlong", "name": "content-size"}],
"name": "open"},
{"id": 41,
"arguments": [{"type": "longlong", "name": "staged-size"}],
"name": "open-ok"},
{"content": true,
"id": 50,
"arguments": [],
"name": "stage"},
{"id": 60,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "exchange", "default-value": ""},
{"type": "shortstr", "name": "routing-key"},
{"type": "bit", "name": "mandatory", "default-value": false},
{"type": "bit", "name": "immediate", "default-value": false},
{"type": "shortstr", "name": "identifier"}],
"name": "publish"},
{"content": true,
"id": 70,
"arguments": [{"type": "short", "name": "reply-code", "default-value": 200},
{"type": "shortstr", "name": "reply-text", "default-value": ""},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"}],
"name": "return"},
{"id": 80,
"arguments": [{"type": "shortstr", "name": "consumer-tag"},
{"type": "longlong", "name": "delivery-tag"},
{"type": "bit", "name": "redelivered", "default-value": false},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"},
{"type": "shortstr", "name": "identifier"}],
"name": "deliver"},
{"id": 90,
"arguments": [{"type": "longlong", "name": "delivery-tag", "default-value": 0},
{"type": "bit", "name": "multiple", "default-value": true}],
"name": "ack"},
{"id": 100,
"arguments": [{"type": "longlong", "name": "delivery-tag"},
{"type": "bit", "name": "requeue", "default-value": true}],
"name": "reject"}],
"name": "file",
"properties": [{"type": "shortstr", "name": "content-type"},
{"type": "shortstr", "name": "content-encoding"},
{"type": "table", "name": "headers"},
{"type": "octet", "name": "priority"},
{"type": "shortstr", "name": "reply-to"},
{"type": "shortstr", "name": "message-id"},
{"type": "shortstr", "name": "filename"},
{"type": "timestamp", "name": "timestamp"},
{"type": "shortstr", "name": "cluster-id"}]
},
{
"id": 80,
"methods": [{"id": 10,
"arguments": [{"type": "long", "name": "prefetch-size", "default-value": 0},
{"type": "short", "name": "prefetch-count", "default-value": 0},
{"type": "long", "name": "consume-rate", "default-value": 0},
{"type": "bit", "name": "global", "default-value": false}],
"name": "qos"},
{"id": 11,
"arguments": [],
"name": "qos-ok"},
{"id": 20,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "queue"},
{"type": "shortstr", "name": "consumer-tag", "default-value": ""},
{"type": "bit", "name": "no-local", "default-value": false},
{"type": "bit", "name": "exclusive", "default-value": false},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "consume"},
{"id": 21,
"arguments": [{"type": "shortstr", "name": "consumer-tag"}],
"name": "consume-ok"},
{"id": 30,
"arguments": [{"type": "shortstr", "name": "consumer-tag"},
{"type": "bit", "name": "nowait", "default-value": false}],
"name": "cancel"},
{"id": 31,
"arguments": [{"type": "shortstr", "name": "consumer-tag"}],
"name": "cancel-ok"},
{"content": true,
"id": 40,
"arguments": [{"type": "short", "name": "ticket", "default-value": 1},
{"type": "shortstr", "name": "exchange", "default-value": ""},
{"type": "shortstr", "name": "routing-key"},
{"type": "bit", "name": "mandatory", "default-value": false},
{"type": "bit", "name": "immediate", "default-value": false}],
"name": "publish"},
{"content": true,
"id": 50,
"arguments": [{"type": "short", "name": "reply-code", "default-value": 200},
{"type": "shortstr", "name": "reply-text", "default-value": ""},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "routing-key"}],
"name": "return"},
{"content": true,
"id": 60,
"arguments": [{"type": "shortstr", "name": "consumer-tag"},
{"type": "longlong", "name": "delivery-tag"},
{"type": "shortstr", "name": "exchange"},
{"type": "shortstr", "name": "queue"}],
"name": "deliver"}],
"name": "stream",
"properties": [{"type": "shortstr", "name": "content-type"},
{"type": "shortstr", "name": "content-encoding"},
{"type": "table", "name": "headers"},
{"type": "octet", "name": "priority"},
{"type": "timestamp", "name": "timestamp"}]
},
{
"id": 90,
"methods": [{"id": 10,
"arguments": [],
"name": "select"},
{"id": 11,
"arguments": [],
"name": "select-ok"},
{"id": 20,
"arguments": [],
"name": "commit"},
{"id": 21,
"arguments": [],
"name": "commit-ok"},
{"id": 30,
"arguments": [],
"name": "rollback"},
{"id": 31,
"arguments": [],
"name": "rollback-ok"}],
"name": "tx"
},
{
"id": 100,
"methods": [{"id": 10,
"arguments": [],
"name": "select"},
{"id": 11,
"arguments": [],
"name": "select-ok"},
{"id": 20,
"arguments": [{"type": "shortstr", "name": "dtx-identifier"}],
"name": "start"},
{"id": 21,
"arguments": [], "name": "start-ok"}],
"name": "dtx"
},
{
"id": 110,
"methods": [{"content": true,
"id": 10,
"arguments": [{"type": "table", "name": "meta-data"}],
"name": "request"}],
"name": "tunnel",
"properties": [{"type": "table", "name": "headers"},
{"type": "shortstr", "name": "proxy-name"},
{"type": "shortstr", "name": "data-name"},
{"type": "octet", "name": "durable"},
{"type": "octet", "name": "broadcast"}]
},
{
"id": 120,
"methods": [{"id": 10,
"arguments": [{"type": "octet", "name": "integer-1"},
{"type": "short", "name": "integer-2"},
{"type": "long", "name": "integer-3"},
{"type": "longlong", "name": "integer-4"},
{"type": "octet", "name": "operation"}],
"name": "integer"},
{"id": 11,
"arguments": [{"type": "longlong", "name": "result"}],
"name": "integer-ok"},
{"id": 20,
"arguments": [{"type": "shortstr", "name": "string-1"},
{"type": "longstr", "name": "string-2"},
{"type": "octet", "name": "operation"}],
"name": "string"},
{"id": 21,
"arguments": [{"type": "longstr", "name": "result"}],
"name": "string-ok"},
{"id": 30,
"arguments": [{"type": "table", "name": "table"},
{"type": "octet", "name": "integer-op"},
{"type": "octet", "name": "string-op"}],
"name": "table"},
{"id": 31,
"arguments": [{"type": "longlong", "name": "integer-result"},
{"type": "longstr", "name": "string-result"}],
"name": "table-ok"},
{"content": true,
"id": 40,
"arguments": [],
"name": "content"},
{"content": true,
"id": 41,
"arguments": [{"type": "long", "name": "content-checksum"}],
"name": "content-ok"}],
"name": "test"
}
]
}
bunny-0.7.8/.gitignore 0000644 0000764 0000764 00000000116 11704323672 013710 0 ustar pravi pravi .DS_Store
.*.swp
*.class
*.rbc
*.gem
/doc/
.yardoc
.rvmrc
Gemfile.lock
.rbx/*
bunny-0.7.8/bunny.gemspec 0000755 0000764 0000764 00000002326 11704323672 014430 0 ustar pravi pravi #!/usr/bin/env gem build
# encoding: utf-8
require "base64"
require File.expand_path("../lib/bunny/version", __FILE__)
Gem::Specification.new do |s|
s.name = "bunny"
s.version = Bunny::VERSION.dup
s.homepage = "http://github.com/ruby-amqp/bunny"
s.summary = "Synchronous Ruby AMQP 0.9.1 client"
s.description = "A synchronous Ruby AMQP client that enables interaction with AMQP-compliant brokers."
# Sorted alphabetically.
s.authors = [
"Chris Duncan",
"Eric Lindvall",
"Jakub Stastny aka botanicus",
"Michael S. Klishin",
"Stefan Kaes"]
s.email = [
"Y2VsbGRlZUBnbWFpbC5jb20=\n",
"ZXJpY0A1c3RvcHMuY29t\n",
"c3Rhc3RueUAxMDFpZGVhcy5jeg==\n",
"bWljaGFlbEBub3ZlbWJlcmFpbi5jb20=\n",
"c2thZXNAcmFpbHNleHByZXNzLmRl\n"].
map { |mail| Base64.decode64(mail) }
# Files.
s.has_rdoc = true
s.extra_rdoc_files = ["README.textile"]
s.rdoc_options = ["--main", "README.rdoc"]
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- spec/*`.split("\n")
s.require_paths = ["lib"]
begin
require "changelog"
s.post_install_message = CHANGELOG.new.version_changes
rescue LoadError
end
# RubyForge
s.rubyforge_project = "bunny-amqp"
end
bunny-0.7.8/spec/ 0000755 0000764 0000764 00000000000 11704323672 012654 5 ustar pravi pravi bunny-0.7.8/spec/spec_08/ 0000755 0000764 0000764 00000000000 11704323672 014115 5 ustar pravi pravi bunny-0.7.8/spec/spec_08/bunny_spec.rb 0000644 0000764 0000764 00000003764 11704323672 016621 0 ustar pravi pravi # encoding: utf-8
# bunny_spec.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. lib bunny]))
describe Bunny do
before(:each) do
@b = Bunny.new
@b.start
end
after(:each) do
begin
@b.stop
rescue Exception
ensure
@b = nil
end
end
it "should connect to an AMQP server" do
@b.status.should == :connected
end
it "should be able to create and open a new channel" do
c = @b.create_channel
c.number.should == 2
c.should be_an_instance_of(Bunny::Channel)
@b.channels.size.should == 3
c.open.should == :open_ok
@b.channel.number.should == 2
end
it "should be able to switch between channels" do
@b.channel.number.should == 1
@b.switch_channel(0)
@b.channel.number.should == 0
end
it "should raise an error if trying to switch to a non-existent channel" do
lambda { @b.switch_channel(5)}.should raise_error(RuntimeError)
end
it "should be able to create an exchange" do
exch = @b.exchange('test_exchange')
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'test_exchange'
@b.exchanges.has_key?('test_exchange').should be(true)
end
it "should be able to create a queue" do
q = @b.queue('test1')
q.should be_an_instance_of(Bunny::Queue)
q.name.should == 'test1'
@b.queues.has_key?('test1').should be(true)
end
# Current RabbitMQ has not implemented some functionality
it "should raise an error if setting of QoS fails" do
lambda { @b.qos(:global => true) }.should raise_error(Bunny::ForcedConnectionCloseError)
@b.status.should == :not_connected
end
it "should be able to set QoS" do
@b.qos.should == :qos_ok
end
end
bunny-0.7.8/spec/spec_08/queue_spec.rb 0000644 0000764 0000764 00000015713 11704323672 016607 0 ustar pravi pravi # encoding: utf-8
# queue_spec.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. lib bunny]))
describe 'Queue' do
def expect_deprecation_warning_for_publishing_on_queue(q, n=1)
Bunny.should_receive(:deprecation_warning).with("Qrack::Queue#publish", "0.8", anything).exactly(n).times
end
def message_count(queue, sleep_time = 0.1)
sleep sleep_time
queue.message_count
end
before(:each) do
@b = Bunny.new
@b.start
end
after(:each) do
begin
@b.stop
rescue Exception
ensure
@b = nil
end
end
it "should ignore the :nowait option when instantiated" do
q = @b.queue('test0', :nowait => true)
end
it "should ignore the :nowait option when binding to an exchange" do
exch = @b.exchange('direct_exch')
q = @b.queue('test0')
q.bind(exch, :nowait => true).should == :bind_ok
end
it "should raise an error when trying to bind to a non-existent exchange" do
q = @b.queue('test1')
lambda {q.bind('bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
@b.channel.active.should == false
end
it "should be able to bind to an existing exchange" do
exch = @b.exchange('direct_exch')
q = @b.queue('test1')
q.bind(exch).should == :bind_ok
end
it "should ignore the :nowait option when unbinding from an exchange" do
exch = @b.exchange('direct_exch')
q = @b.queue('test0')
q.unbind(exch, :nowait => true).should == :unbind_ok
end
it "should raise an error if unbinding from a non-existent exchange" do
q = @b.queue('test1')
lambda {q.unbind('bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
@b.channel.active.should == false
end
it "should be able to unbind from an existing exchange" do
exch = @b.exchange('direct_exch')
q = @b.queue('test1')
q.unbind(exch).should == :unbind_ok
end
it "should be able to publish a message" do
q = @b.queue('test1')
expect_deprecation_warning_for_publishing_on_queue(q)
q.publish('This is a test message')
message_count(q).should == 1
end
it "should be able to pop a message complete with header and delivery details" do
q = @b.queue('test1')
msg = q.pop()
msg.should be_an_instance_of(Hash)
msg[:header].should be_an_instance_of(Bunny::Protocol::Header)
msg[:payload].should == 'This is a test message'
msg[:delivery_details].should be_an_instance_of(Hash)
message_count(q).should == 0
end
it "should be able to pop a message and just get the payload" do
q = @b.queue('test1')
expect_deprecation_warning_for_publishing_on_queue(q)
q.publish('This is another test message')
msg = q.pop[:payload]
msg.should == 'This is another test message'
message_count(q).should == 0
end
it "should be able to pop a message where body length exceeds max frame size" do
q = @b.queue('test1')
lg_msg = 'z' * 142000
expect_deprecation_warning_for_publishing_on_queue(q)
q.publish(lg_msg)
msg = q.pop[:payload]
msg.should == lg_msg
end
it "should be able call a block when popping a message" do
q = @b.queue('test1')
expect_deprecation_warning_for_publishing_on_queue(q)
q.publish('This is another test message')
q.pop { |msg| msg[:payload].should == 'This is another test message' }
q.pop { |msg| msg[:payload].should == :queue_empty }
end
it "should raise an error if purge fails" do
q = @b.queue('test1')
expect_deprecation_warning_for_publishing_on_queue(q, 5)
5.times {q.publish('This is another test message')}
message_count(q).should == 5
lambda {q.purge(:queue => 'bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
end
it "should be able to be purged to remove all of its messages" do
q = @b.queue('test1')
message_count(q).should == 5
q.purge.should == :purge_ok
message_count(q).should == 0
end
it "should return an empty message when popping an empty queue" do
q = @b.queue('test1')
expect_deprecation_warning_for_publishing_on_queue(q)
q.publish('This is another test message')
q.pop
msg = q.pop[:payload]
msg.should == :queue_empty
end
it "should stop subscription without processing messages if max specified is 0" do
q = @b.queue('test1')
expect_deprecation_warning_for_publishing_on_queue(q, 5)
5.times {q.publish('Yet another test message')}
message_count(q).should == 5
q.subscribe(:message_max => 0)
message_count(q).should == 5
q.purge.should == :purge_ok
end
it "should stop subscription after processing number of messages specified > 0" do
q = @b.queue('test1')
expect_deprecation_warning_for_publishing_on_queue(q, 5)
5.times {q.publish('Yet another test message')}
message_count(q).should == 5
q.subscribe(:message_max => 5)
end
it "should stop subscription after processing message_max messages < total in queue" do
q = @b.queue('test1')
@b.qos()
expect_deprecation_warning_for_publishing_on_queue(q, 10)
10.times {q.publish('Yet another test message')}
message_count(q).should == 10
q.subscribe(:message_max => 5, :ack => true)
message_count(q).should == 5
q.purge.should == :purge_ok
end
it "should raise an error when delete fails" do
q = @b.queue('test1')
lambda {q.delete(:queue => 'bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
@b.channel.active.should == false
end
it "should pass correct block parameters through on subscribe" do
q = @b.queue('test1')
expect_deprecation_warning_for_publishing_on_queue(q)
q.publish("messages pop\'n")
q.subscribe do |msg|
msg[:header].should be_an_instance_of Qrack::Protocol::Header
msg[:payload].should == "messages pop'n"
msg[:delivery_details].should_not be_nil
q.unsubscribe
break
end
end
it "should finish processing subscription messages if break is called in block" do
q = @b.queue('test1')
expect_deprecation_warning_for_publishing_on_queue(q, 6)
q.publish('messages in my quezen')
q.subscribe do |msg|
msg[:payload].should == 'messages in my quezen'
q.unsubscribe
break
end
5.times {|i| q.publish("#{i}")}
q.subscribe do |msg|
if msg[:payload] == '4'
q.unsubscribe
break
end
end
end
it "should be able to be deleted" do
q = @b.queue('test1')
res = q.delete
res.should == :delete_ok
@b.queues.has_key?('test1').should be(false)
end
it "should ignore the :nowait option when deleted" do
q = @b.queue('test0')
q.delete(:nowait => true)
end
it "should support server named queues" do
q = @b.queue
q.name.should_not == nil
@b.queue(q.name).should == q
q.delete
end
end
bunny-0.7.8/spec/spec_08/connection_spec.rb 0000644 0000764 0000764 00000001164 11704323672 017615 0 ustar pravi pravi # encoding: utf-8
# connection_spec.rb
require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. lib bunny]))
describe Bunny do
it "should raise an error if the wrong user name or password is used" do
b = Bunny.new(:user => 'wrong')
lambda { b.start}.should raise_error(Bunny::ProtocolError)
end
it "should be able to open a TCPSocket with a timeout" do
b = Bunny.new(:spec => "0.8")
connect_timeout = 5
lambda {
Bunny::Timer::timeout(connect_timeout, Qrack::ConnectionTimeout) do
TCPSocket.new(b.host, b.port)
end
}.should_not raise_error(Exception)
end
end
bunny-0.7.8/spec/spec_08/exchange_spec.rb 0000644 0000764 0000764 00000013673 11704323672 017250 0 ustar pravi pravi # encoding: utf-8
# exchange_spec.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. lib bunny]))
describe 'Exchange' do
before(:each) do
@b = Bunny.new
@b.start
end
after(:each) do
begin
@b.stop
rescue Exception
ensure
@b = nil
end
end
it "should raise an error if instantiated as non-existent type" do
lambda { @b.exchange('bogus_ex', :type => :bogus) }.should raise_error(Bunny::ForcedConnectionCloseError)
@b.status.should == :not_connected
end
it "should allow a default direct exchange to be instantiated by specifying :type" do
exch = @b.exchange('amq.direct', :type => :direct)
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'amq.direct'
exch.type.should == :direct
@b.exchanges.has_key?('amq.direct').should be(true)
end
it "should allow a default direct exchange to be instantiated without specifying :type" do
exch = @b.exchange('amq.direct')
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'amq.direct'
exch.type.should == :direct
@b.exchanges.has_key?('amq.direct').should be(true)
end
it "should allow a default fanout exchange to be instantiated without specifying :type" do
exch = @b.exchange('amq.fanout')
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'amq.fanout'
exch.type.should == :fanout
@b.exchanges.has_key?('amq.fanout').should be(true)
end
it "should allow a default topic exchange to be instantiated without specifying :type" do
exch = @b.exchange('amq.topic')
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'amq.topic'
exch.type.should == :topic
@b.exchanges.has_key?('amq.topic').should be(true)
end
it "should allow a default headers (amq.match) exchange to be instantiated without specifying :type" do
exch = @b.exchange('amq.match')
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'amq.match'
exch.type.should == :headers
@b.exchanges.has_key?('amq.match').should be(true)
end
it "should allow a default headers (amq.headers) exchange to be instantiated without specifying :type" do
exch = @b.exchange('amq.headers')
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'amq.headers'
exch.type.should == :headers
@b.exchanges.has_key?('amq.headers').should be(true)
end
it "should create an exchange as direct by default" do
exch = @b.exchange('direct_defaultex')
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'direct_defaultex'
exch.type.should == :direct
@b.exchanges.has_key?('direct_defaultex').should be(true)
end
it "should be able to be instantiated as a direct exchange" do
exch = @b.exchange('direct_exchange', :type => :direct)
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'direct_exchange'
exch.type.should == :direct
@b.exchanges.has_key?('direct_exchange').should be(true)
end
it "should be able to be instantiated as a topic exchange" do
exch = @b.exchange('topic_exchange', :type => :topic)
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'topic_exchange'
exch.type.should == :topic
@b.exchanges.has_key?('topic_exchange').should be(true)
end
it "should be able to be instantiated as a fanout exchange" do
exch = @b.exchange('fanout_exchange', :type => :fanout)
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'fanout_exchange'
exch.type.should == :fanout
@b.exchanges.has_key?('fanout_exchange').should be(true)
end
it "should be able to be instantiated as a headers exchange" do
exch = @b.exchange('headers_exchange', :type => :headers)
exch.should be_an_instance_of(Bunny::Exchange)
exch.name.should == 'headers_exchange'
exch.type.should == :headers
@b.exchanges.has_key?('headers_exchange').should be(true)
end
it "should ignore the :nowait option when instantiated" do
exch = @b.exchange('direct2_exchange', :nowait => true)
end
it "should be able to publish a message" do
exch = @b.exchange('direct_exchange')
exch.publish('This is a published message')
end
it "should not modify the passed options hash when publishing a message" do
exch = @b.exchange('direct_exchange')
opts = {:key => 'a', :persistent => true}
exch.publish('', opts)
opts.should == {:key => 'a', :persistent => true}
end
it "should be able to return an undeliverable message" do
exch = @b.exchange('return_exch')
exch.publish('This message should be undeliverable', :immediate => true)
ret_msg = @b.returned_message
ret_msg.should be_an_instance_of(Hash)
ret_msg[:payload].should == 'This message should be undeliverable'
end
it "should be able to return a message that exceeds maximum frame size" do
exch = @b.exchange('return_exch')
lg_msg = 'z' * 142000
exch.publish(lg_msg, :immediate => true)
ret_msg = @b.returned_message
ret_msg.should be_an_instance_of(Hash)
ret_msg[:payload].should == lg_msg
end
it "should report an error if delete fails" do
exch = @b.exchange('direct_exchange')
lambda { exch.delete(:exchange => 'bogus_ex') }.should raise_error(Bunny::ForcedChannelCloseError)
@b.channel.active.should == false
end
it "should be able to be deleted" do
exch = @b.exchange('direct_exchange')
res = exch.delete
res.should == :delete_ok
@b.exchanges.has_key?('direct_exchange').should be(false)
end
it "should ignore the :nowait option when deleted" do
exch = @b.exchange('direct2_exchange')
exch.delete(:nowait => true)
end
end
bunny-0.7.8/spec/spec_09/ 0000755 0000764 0000764 00000000000 11704323672 014116 5 ustar pravi pravi bunny-0.7.8/spec/spec_09/bunny_spec.rb 0000644 0000764 0000764 00000003710 11704323672 016611 0 ustar pravi pravi # encoding: utf-8
# bunny_spec.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
require "bunny"
describe Bunny do
before(:each) do
@b = Bunny.new(:spec => '09')
@b.start
end
after(:each) do
begin
@b.stop
rescue Exception
ensure
@b = nil
end
end
it "should connect to an AMQP server" do
@b.status.should == :connected
end
it "should be able to create and open a new channel" do
c = @b.create_channel
c.number.should == 2
c.should be_an_instance_of(Bunny::Channel09)
@b.channels.size.should == 3
c.open.should == :open_ok
@b.channel.number.should == 2
end
it "should be able to switch between channels" do
@b.channel.number.should == 1
@b.switch_channel(0)
@b.channel.number.should == 0
end
it "should raise an error if trying to switch to a non-existent channel" do
lambda { @b.switch_channel(5) }.should raise_error(RuntimeError)
end
it "should be able to create an exchange" do
exch = @b.exchange('test_exchange')
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'test_exchange'
@b.exchanges.has_key?('test_exchange').should be(true)
end
it "should be able to create a queue" do
q = @b.queue('test1')
q.should be_an_instance_of(Bunny::Queue09)
q.name.should == 'test1'
@b.queues.has_key?('test1').should be(true)
end
# Current RabbitMQ has not implemented some functionality
it "should raise an error if setting of QoS fails" do
lambda { @b.qos(:global => true) }.should raise_error(Bunny::ForcedConnectionCloseError)
@b.status.should == :not_connected
end
it "should be able to set QoS" do
@b.qos.should == :qos_ok
end
end
bunny-0.7.8/spec/spec_09/queue_spec.rb 0000644 0000764 0000764 00000014646 11704323672 016614 0 ustar pravi pravi # encoding: utf-8
# queue_spec.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
require "bunny"
describe 'Queue' do
before(:each) do
@b = Bunny.new(:spec => '09')
@b.start
@default_exchange = @b.exchange("")
end
after(:each) do
begin
@b.stop
rescue Exception
ensure
@b = nil
end
end
def message_count(queue, sleep_time = 0.1)
sleep sleep_time
queue.message_count
end
it "should ignore the :nowait option when instantiated" do
q = @b.queue('test0', :nowait => true)
end
it "should ignore the :nowait option when binding to an exchange" do
exch = @b.exchange('direct_exch')
q = @b.queue('test0')
q.bind(exch, :nowait => true).should == :bind_ok
end
it "should raise an error when trying to bind to a non-existent exchange" do
q = @b.queue('test1')
lambda {q.bind('bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
@b.channel.active.should == false
end
it "should be able to bind to an existing exchange" do
exch = @b.exchange('direct_exch')
q = @b.queue('test1')
q.bind(exch).should == :bind_ok
end
it "should ignore the :nowait option when unbinding from an existing exchange" do
exch = @b.exchange('direct_exch')
q = @b.queue('test0')
q.unbind(exch, :nowait => true).should == :unbind_ok
end
it "should raise an error if unbinding from a non-existent exchange" do
q = @b.queue('test1')
lambda {q.unbind('bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
@b.channel.active.should == false
end
it "should be able to unbind from an exchange" do
exch = @b.exchange('direct_exch')
q = @b.queue('test1')
q.unbind(exch).should == :unbind_ok
end
it "should be able to pop a message complete with header and delivery details" do
q = @b.queue('test1')
@default_exchange.publish('This is a test message', :key => 'test1')
msg = q.pop()
msg.should be_an_instance_of(Hash)
msg[:header].should be_an_instance_of(Bunny::Protocol09::Header)
msg[:payload].should == 'This is a test message'
msg[:delivery_details].should be_an_instance_of(Hash)
message_count(q).should == 0
end
it "should be able to pop a message and just get the payload" do
q = @b.queue('test1')
@default_exchange.publish('This is another test message', :key => 'test1')
msg = q.pop[:payload]
msg.should == 'This is another test message'
message_count(q).should == 0
end
it "should be able to pop a message where body length exceeds max frame size" do
q = @b.queue('test1')
lg_msg = 'z' * 142000
@default_exchange.publish(lg_msg, :key => 'test1')
msg = q.pop[:payload]
msg.should == lg_msg
end
it "should be able call a block when popping a message" do
q = @b.queue('test1')
@default_exchange.publish('This is another test message', :key => 'test1')
q.pop { |msg| msg[:payload].should == 'This is another test message' }
q.pop { |msg| msg[:payload].should == :queue_empty }
end
it "should raise an error if purge fails" do
q = @b.queue('test1')
5.times { @default_exchange.publish('This is another test message', :key => 'test1') }
message_count(q).should == 5
lambda {q.purge(:queue => 'bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
end
it "should be able to be purged to remove all of its messages" do
q = @b.queue('test1')
message_count(q).should == 5
q.purge.should == :purge_ok
message_count(q).should == 0
end
it "should return an empty message when popping an empty queue" do
q = @b.queue('test1')
@default_exchange.publish('This is another test message', :key => 'test1')
q.pop
msg = q.pop[:payload]
msg.should == :queue_empty
end
it "should stop subscription without processing messages if max specified is 0" do
q = @b.queue('test1')
5.times { @default_exchange.publish('Yet another test message', :key => 'test1') }
message_count(q).should == 5
q.subscribe(:message_max => 0)
message_count(q).should == 5
q.purge.should == :purge_ok
end
it "should stop subscription after processing number of messages specified > 0" do
q = @b.queue('test1')
5.times { @default_exchange.publish('Yet another test message', :key => 'test1') }
message_count(q).should == 5
q.subscribe(:message_max => 5)
end
it "should stop subscription after processing message_max messages < total in queue" do
q = @b.queue('test1')
@b.qos()
10.times { @default_exchange.publish('Yet another test message', :key => 'test1') }
message_count(q).should == 10
q.subscribe(:message_max => 5, :ack => true)
message_count(q).should == 5
q.purge.should == :purge_ok
end
it "should raise an error when delete fails" do
q = @b.queue('test1')
lambda {q.delete(:queue => 'bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
@b.channel.active.should == false
end
it "should pass correct block parameters through on subscribe" do
q = @b.queue('test1')
@default_exchange.publish("messages pop'n", :key => 'test1')
q.subscribe do |msg|
msg[:header].should be_an_instance_of Qrack::Protocol09::Header
msg[:payload].should == "messages pop'n"
msg[:delivery_details].should_not be_nil
q.unsubscribe
break
end
end
it "should finish processing subscription messages if break is called in block" do
q = @b.queue('test1')
@default_exchange.publish('messages in my quezen', :key => 'test1')
q.subscribe do |msg|
msg[:payload].should == 'messages in my quezen'
q.unsubscribe
break
end
5.times {|i| @default_exchange.publish("#{i}", :key => 'test1') }
q.subscribe do |msg|
if msg[:payload] == '4'
q.unsubscribe
break
end
end
end
it "should be able to be deleted" do
q = @b.queue('test1')
res = q.delete
res.should == :delete_ok
@b.queues.has_key?('test1').should be(false)
end
it "should ignore the :nowait option when deleted" do
q = @b.queue('test0')
q.delete(:nowait => true)
end
it "should support server named queues" do
q = @b.queue
q.name.should_not == nil
@b.queue(q.name).should == q
q.delete
end
end
bunny-0.7.8/spec/spec_09/connection_spec.rb 0000644 0000764 0000764 00000001351 11704323672 017614 0 ustar pravi pravi # encoding: utf-8
# connection_spec.rb
require "bunny"
describe Bunny do
it "should raise an error if the wrong user name or password is used" do
b = Bunny.new(:spec => '0.9', :user => 'wrong')
lambda { b.start}.should raise_error(Bunny::ProtocolError)
end
it "should merge custom settings from AMQP URL with default settings" do
b = Bunny.new("amqp://tagadab", :spec => "0.9")
b.host.should eql("tagadab")
end
it "should be able to open a TCPSocket with a timeout" do
b = Bunny.new(:spec => "0.9")
connect_timeout = 5
lambda {
Bunny::Timer::timeout(connect_timeout, Qrack::ConnectionTimeout) do
TCPSocket.new(b.host, b.port)
end
}.should_not raise_error(Exception)
end
end
bunny-0.7.8/spec/spec_09/exchange_spec.rb 0000644 0000764 0000764 00000013637 11704323672 017251 0 ustar pravi pravi # encoding: utf-8
# exchange_spec.rb
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
require "bunny"
describe 'Exchange' do
before(:each) do
@b = Bunny.new(:spec => '09')
@b.start
end
after(:each) do
begin
@b.stop
rescue Exception
ensure
@b = nil
end
end
it "should raise an error if instantiated as non-existent type" do
lambda { @b.exchange('bogus_ex', :type => :bogus) }.should raise_error(Bunny::ForcedConnectionCloseError)
@b.status.should == :not_connected
end
it "should allow a default direct exchange to be instantiated by specifying :type" do
exch = @b.exchange('amq.direct', :type => :direct)
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'amq.direct'
exch.type.should == :direct
@b.exchanges.has_key?('amq.direct').should be(true)
end
it "should allow a default direct exchange to be instantiated without specifying :type" do
exch = @b.exchange('amq.direct')
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'amq.direct'
exch.type.should == :direct
@b.exchanges.has_key?('amq.direct').should be(true)
end
it "should allow a default fanout exchange to be instantiated without specifying :type" do
exch = @b.exchange('amq.fanout')
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'amq.fanout'
exch.type.should == :fanout
@b.exchanges.has_key?('amq.fanout').should be(true)
end
it "should allow a default topic exchange to be instantiated without specifying :type" do
exch = @b.exchange('amq.topic')
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'amq.topic'
exch.type.should == :topic
@b.exchanges.has_key?('amq.topic').should be(true)
end
it "should allow a default headers (amq.match) exchange to be instantiated without specifying :type" do
exch = @b.exchange('amq.match')
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'amq.match'
exch.type.should == :headers
@b.exchanges.has_key?('amq.match').should be(true)
end
it "should allow a default headers (amq.headers) exchange to be instantiated without specifying :type" do
exch = @b.exchange('amq.headers')
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'amq.headers'
exch.type.should == :headers
@b.exchanges.has_key?('amq.headers').should be(true)
end
it "should create an exchange as direct by default" do
exch = @b.exchange('direct_defaultex')
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'direct_defaultex'
exch.type.should == :direct
@b.exchanges.has_key?('direct_defaultex').should be(true)
end
it "should be able to be instantiated as a direct exchange" do
exch = @b.exchange('direct_exchange', :type => :direct)
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'direct_exchange'
exch.type.should == :direct
@b.exchanges.has_key?('direct_exchange').should be(true)
end
it "should be able to be instantiated as a topic exchange" do
exch = @b.exchange('topic_exchange', :type => :topic)
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'topic_exchange'
exch.type.should == :topic
@b.exchanges.has_key?('topic_exchange').should be(true)
end
it "should be able to be instantiated as a fanout exchange" do
exch = @b.exchange('fanout_exchange', :type => :fanout)
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'fanout_exchange'
exch.type.should == :fanout
@b.exchanges.has_key?('fanout_exchange').should be(true)
end
it "should be able to be instantiated as a headers exchange" do
exch = @b.exchange('headers_exchange', :type => :headers)
exch.should be_an_instance_of(Bunny::Exchange09)
exch.name.should == 'headers_exchange'
exch.type.should == :headers
@b.exchanges.has_key?('headers_exchange').should be(true)
end
it "should ignore the :nowait option when instantiated" do
exch = @b.exchange('direct2_exchange', :nowait => true)
end
it "should be able to publish a message" do
exch = @b.exchange('direct_exchange')
exch.publish('This is a published message')
end
it "should not modify the passed options hash when publishing a message" do
exch = @b.exchange('direct_exchange')
opts = {:key => 'a', :persistent => true}
exch.publish('', opts)
opts.should == {:key => 'a', :persistent => true}
end
it "should be able to return an undeliverable message" do
exch = @b.exchange('return_exch')
exch.publish('This message should be undeliverable', :immediate => true)
ret_msg = @b.returned_message
ret_msg.should be_an_instance_of(Hash)
ret_msg[:payload].should == 'This message should be undeliverable'
end
it "should be able to return a message that exceeds maximum frame size" do
exch = @b.exchange('return_exch')
lg_msg = 'z' * 142000
exch.publish(lg_msg, :immediate => true)
ret_msg = @b.returned_message
ret_msg.should be_an_instance_of(Hash)
ret_msg[:payload].should == lg_msg
end
it "should report an error if delete fails" do
exch = @b.exchange('direct_exchange')
lambda { exch.delete(:exchange => 'bogus_ex') }.should raise_error(Bunny::ForcedChannelCloseError)
@b.channel.active.should == false
end
it "should be able to be deleted" do
exch = @b.exchange('direct_exchange')
res = exch.delete
res.should == :delete_ok
@b.exchanges.has_key?('direct_exchange').should be(false)
end
it "should ignore the :nowait option when deleted" do
exch = @b.exchange('direct2_exchange')
exch.delete(:nowait => true)
end
end
bunny-0.7.8/spec/spec_09/amqp_url_spec.rb 0000644 0000764 0000764 00000001056 11704323672 017277 0 ustar pravi pravi # encoding: utf-8
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
# and that it is running on 'localhost'.
# If this is not the case, please change the 'Bunny.new' call below to include
# the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
require "bunny"
describe Bunny do
context "AMQP URL parsing" do
it "handles port properly" do
bunny = Bunny.new("amqp://dev.rabbitmq.com:1212")
bunny.port.should eql(1212)
bunny.stop
end
end
end
bunny-0.7.8/Gemfile 0000644 0000764 0000764 00000001464 11704323672 013222 0 ustar pravi pravi # encoding: utf-8
source :rubygems
# Use local clones if possible.
# If you want to use your local copy, just symlink it to vendor.
# See http://blog.101ideas.cz/posts/custom-gems-in-gemfile.html
extend Module.new {
def gem(name, *args)
options = args.last.is_a?(Hash) ? args.last : Hash.new
local_path = File.expand_path("../vendor/#{name}", __FILE__)
if File.exist?(local_path)
super name, options.merge(:path => local_path).
delete_if { |key, _| [:git, :branch].include?(key) }
else
super name, *args
end
end
}
gem "SystemTimer", "1.2", :platform => :ruby_18
group :development do
gem "rake"
gem "yard", ">= 0.7.2"
# Yard tags this buddy along.
gem "RedCloth", :platform => :mri
gem "changelog"
end
group :test do
gem "rspec", "~> 2.6.0"
end
gemspec
bunny-0.7.8/.yardopts 0000644 0000764 0000764 00000000214 11704323672 013565 0 ustar pravi pravi --no-private
--protected
--markup="textile" lib/**/*.rb
--main README.textile
--asset examples:examples
--hide-tag todo
-
LICENSE
CHANGELOG
bunny-0.7.8/CHANGELOG 0000644 0000764 0000764 00000001073 11704323672 013135 0 ustar pravi pravi = Version 0.7.8
* test suite cleanup (eliminated some race conditions related to queue.message_count)
= Version 0.7.7
* avoid warnings caused by duplicating code from the amq-client gem
= Version 0.7.6
* API mismatch between Timer/SystemTimer on Ruby 1.9 vs Ruby 1.8 is resolved.
= Version 0.7.3
* AMQP connection URI parser now respects port
= Version 0.7.2
* Fixes for irb tab completion
= Version 0.7.0
* Added :content_type option to Exchange#publish
* Lots of minor fixes
= Version 0.6.3
* Encoding of source files is set to UTF-8 on Ruby 1.9.
bunny-0.7.8/.rspec 0000644 0000764 0000764 00000000032 11704323672 013032 0 ustar pravi pravi --color
--format
progress