amq-client 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. data/.gitignore +8 -0
  2. data/.gitmodules +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +7 -0
  5. data/.yardopts +1 -0
  6. data/CONTRIBUTORS +3 -0
  7. data/Gemfile +27 -0
  8. data/LICENSE +20 -0
  9. data/README.textile +61 -0
  10. data/amq-client.gemspec +34 -0
  11. data/bin/jenkins.sh +23 -0
  12. data/bin/set_test_suite_realms_up.sh +24 -0
  13. data/examples/coolio_adapter/basic_consume.rb +49 -0
  14. data/examples/coolio_adapter/basic_consume_with_acknowledgements.rb +43 -0
  15. data/examples/coolio_adapter/basic_consume_with_rejections.rb +43 -0
  16. data/examples/coolio_adapter/basic_publish.rb +35 -0
  17. data/examples/coolio_adapter/channel_close.rb +24 -0
  18. data/examples/coolio_adapter/example_helper.rb +39 -0
  19. data/examples/coolio_adapter/exchange_declare.rb +28 -0
  20. data/examples/coolio_adapter/kitchen_sink1.rb +48 -0
  21. data/examples/coolio_adapter/queue_bind.rb +32 -0
  22. data/examples/coolio_adapter/queue_purge.rb +32 -0
  23. data/examples/coolio_adapter/queue_unbind.rb +37 -0
  24. data/examples/eventmachine_adapter/authentication/plain_password_with_custom_role_credentials.rb +36 -0
  25. data/examples/eventmachine_adapter/authentication/plain_password_with_default_role_credentials.rb +27 -0
  26. data/examples/eventmachine_adapter/authentication/plain_password_with_incorrect_credentials.rb +18 -0
  27. data/examples/eventmachine_adapter/basic_cancel.rb +49 -0
  28. data/examples/eventmachine_adapter/basic_consume.rb +51 -0
  29. data/examples/eventmachine_adapter/basic_consume_with_acknowledgements.rb +45 -0
  30. data/examples/eventmachine_adapter/basic_consume_with_rejections.rb +45 -0
  31. data/examples/eventmachine_adapter/basic_get.rb +57 -0
  32. data/examples/eventmachine_adapter/basic_get_with_empty_queue.rb +53 -0
  33. data/examples/eventmachine_adapter/basic_publish.rb +38 -0
  34. data/examples/eventmachine_adapter/basic_qos.rb +29 -0
  35. data/examples/eventmachine_adapter/basic_recover.rb +29 -0
  36. data/examples/eventmachine_adapter/basic_return.rb +34 -0
  37. data/examples/eventmachine_adapter/channel_close.rb +24 -0
  38. data/examples/eventmachine_adapter/channel_flow.rb +36 -0
  39. data/examples/eventmachine_adapter/channel_level_exception_handling.rb +44 -0
  40. data/examples/eventmachine_adapter/example_helper.rb +39 -0
  41. data/examples/eventmachine_adapter/exchange_declare.rb +54 -0
  42. data/examples/eventmachine_adapter/extensions/rabbitmq/handling_confirm_select_ok.rb +31 -0
  43. data/examples/eventmachine_adapter/extensions/rabbitmq/publisher_confirmations_with_transient_messages.rb +56 -0
  44. data/examples/eventmachine_adapter/extensions/rabbitmq/publisher_confirmations_with_unroutable_message.rb +46 -0
  45. data/examples/eventmachine_adapter/kitchen_sink1.rb +50 -0
  46. data/examples/eventmachine_adapter/queue_bind.rb +32 -0
  47. data/examples/eventmachine_adapter/queue_declare.rb +34 -0
  48. data/examples/eventmachine_adapter/queue_purge.rb +32 -0
  49. data/examples/eventmachine_adapter/queue_unbind.rb +37 -0
  50. data/examples/eventmachine_adapter/tx_commit.rb +29 -0
  51. data/examples/eventmachine_adapter/tx_rollback.rb +29 -0
  52. data/examples/eventmachine_adapter/tx_select.rb +27 -0
  53. data/examples/socket_adapter/basics.rb +19 -0
  54. data/examples/socket_adapter/connection.rb +53 -0
  55. data/examples/socket_adapter/multiple_connections.rb +17 -0
  56. data/irb.rb +66 -0
  57. data/lib/amq/client.rb +15 -0
  58. data/lib/amq/client/adapter.rb +356 -0
  59. data/lib/amq/client/adapters/coolio.rb +221 -0
  60. data/lib/amq/client/adapters/event_machine.rb +228 -0
  61. data/lib/amq/client/adapters/socket.rb +89 -0
  62. data/lib/amq/client/channel.rb +338 -0
  63. data/lib/amq/client/connection.rb +246 -0
  64. data/lib/amq/client/entity.rb +117 -0
  65. data/lib/amq/client/exceptions.rb +86 -0
  66. data/lib/amq/client/exchange.rb +163 -0
  67. data/lib/amq/client/extensions/rabbitmq.rb +5 -0
  68. data/lib/amq/client/extensions/rabbitmq/basic.rb +36 -0
  69. data/lib/amq/client/extensions/rabbitmq/confirm.rb +254 -0
  70. data/lib/amq/client/framing/io/frame.rb +32 -0
  71. data/lib/amq/client/framing/string/frame.rb +62 -0
  72. data/lib/amq/client/logging.rb +56 -0
  73. data/lib/amq/client/mixins/anonymous_entity.rb +21 -0
  74. data/lib/amq/client/mixins/status.rb +62 -0
  75. data/lib/amq/client/protocol/get_response.rb +55 -0
  76. data/lib/amq/client/queue.rb +450 -0
  77. data/lib/amq/client/settings.rb +83 -0
  78. data/lib/amq/client/version.rb +5 -0
  79. data/spec/benchmarks/adapters.rb +77 -0
  80. data/spec/client/framing/io_frame_spec.rb +57 -0
  81. data/spec/client/framing/string_frame_spec.rb +57 -0
  82. data/spec/client/protocol/get_response_spec.rb +79 -0
  83. data/spec/integration/coolio/basic_ack_spec.rb +41 -0
  84. data/spec/integration/coolio/basic_get_spec.rb +73 -0
  85. data/spec/integration/coolio/basic_return_spec.rb +33 -0
  86. data/spec/integration/coolio/channel_close_spec.rb +26 -0
  87. data/spec/integration/coolio/channel_flow_spec.rb +46 -0
  88. data/spec/integration/coolio/spec_helper.rb +31 -0
  89. data/spec/integration/coolio/tx_commit_spec.rb +40 -0
  90. data/spec/integration/coolio/tx_rollback_spec.rb +44 -0
  91. data/spec/integration/eventmachine/basic_ack_spec.rb +40 -0
  92. data/spec/integration/eventmachine/basic_get_spec.rb +73 -0
  93. data/spec/integration/eventmachine/basic_return_spec.rb +35 -0
  94. data/spec/integration/eventmachine/channel_close_spec.rb +26 -0
  95. data/spec/integration/eventmachine/channel_flow_spec.rb +32 -0
  96. data/spec/integration/eventmachine/spec_helper.rb +22 -0
  97. data/spec/integration/eventmachine/tx_commit_spec.rb +47 -0
  98. data/spec/integration/eventmachine/tx_rollback_spec.rb +35 -0
  99. data/spec/regression/bad_frame_slicing_in_adapters_spec.rb +59 -0
  100. data/spec/spec_helper.rb +24 -0
  101. data/spec/unit/client/adapter_spec.rb +49 -0
  102. data/spec/unit/client/entity_spec.rb +49 -0
  103. data/spec/unit/client/logging_spec.rb +60 -0
  104. data/spec/unit/client/mixins/status_spec.rb +72 -0
  105. data/spec/unit/client/settings_spec.rb +27 -0
  106. data/spec/unit/client_spec.rb +11 -0
  107. data/tasks.rb +11 -0
  108. metadata +202 -0
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'integration/eventmachine/spec_helper'
4
+
5
+ describe AMQ::Client::EventMachineClient, "Tx.Commit" do
6
+
7
+ #
8
+ # Environment
9
+ #
10
+
11
+ include EventedSpec::SpecHelper
12
+ default_timeout 2
13
+
14
+ let(:message) { "Hello, world!" }
15
+
16
+
17
+ #
18
+ # Examples
19
+ #
20
+
21
+ it "should confirm transaction completeness" do
22
+ received_messages = []
23
+ em_amqp_connect do |client|
24
+ channel = AMQ::Client::Channel.new(client, 1)
25
+ channel.open do
26
+ exchange = AMQ::Client::Exchange.new(client, channel, "amq.fanout", :fanout)
27
+ queue = AMQ::Client::Queue.new(client, channel)
28
+
29
+ queue.declare(false, false, false, true) do
30
+ queue.bind(exchange)
31
+ end
32
+
33
+ channel.tx_select do
34
+ queue.consume(true) do |header, payload, delivery_tag, redelivered, exchange, routing_key, message_count|
35
+ received_messages << message
36
+ done
37
+ end
38
+
39
+ exchange.publish(message)
40
+ channel.tx_commit
41
+ end
42
+ end # em_amqp_connect
43
+
44
+ end
45
+ received_messages.should == [message]
46
+ end # it
47
+ end # describe
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'integration/eventmachine/spec_helper'
4
+
5
+ describe AMQ::Client::EventMachineClient, "Tx.Rollback" do
6
+ include EventedSpec::SpecHelper
7
+ default_timeout 2
8
+ let(:message) { "Hello, world!" }
9
+ it "should cancel all the changes done during transaction" do
10
+ pending("Need to figure out details with AMQP protocol on that matter")
11
+ received_messages = []
12
+ em_amqp_connect do |client|
13
+ channel = AMQ::Client::Channel.new(client, 1)
14
+ channel.open do
15
+ exchange = AMQ::Client::Exchange.new(client, channel, "amq.fanout", :fanout)
16
+ queue = AMQ::Client::Queue.new(client, channel)
17
+
18
+ queue.declare(false, false, false, true) do
19
+ queue.bind(exchange)
20
+ end
21
+
22
+ channel.tx_select do
23
+ done(0.1)
24
+ queue.consume(true) do |header, payload, delivery_tag, redelivered, exchange, routing_key, message_count|
25
+ received_messages << message
26
+ end
27
+
28
+ exchange.publish(message)
29
+ channel.tx_rollback
30
+ end
31
+ end
32
+ end
33
+ received_messages.should == []
34
+ end
35
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'integration/coolio/spec_helper'
3
+ require 'integration/eventmachine/spec_helper'
4
+
5
+ describe "AMQ::Client::Coolio", :nojruby => true do
6
+ include EventedSpec::SpecHelper
7
+ default_timeout 1
8
+
9
+ let(:message) { "Message with xCE \xCE" }
10
+
11
+ it "should receive the message with xCE byte in it without errors" do
12
+ coolio_amqp_connect do |client|
13
+ channel = AMQ::Client::Channel.new(client, 1)
14
+ channel.open do end
15
+ queue = AMQ::Client::Queue.new(client, channel)
16
+ queue.declare(false, false, false, true)
17
+ queue.bind("amq.fanout")
18
+ queue.consume(true) do |_, consumer_tag|
19
+ queue.on_delivery do |method, header, payload|
20
+ @received_message = payload
21
+ done
22
+ end
23
+
24
+ exchange = AMQ::Client::Exchange.new(client, channel, "amq.fanout", :fanout)
25
+ exchange.publish(message)
26
+ end
27
+ end
28
+
29
+ @received_message.should == message
30
+ end
31
+ end
32
+
33
+ describe AMQ::Client::EventMachineClient do
34
+ include EventedSpec::SpecHelper
35
+ default_timeout 1
36
+
37
+ let(:message) { "Message with xCE \xCE" }
38
+
39
+ it "should receive the message with xCE byte in it without errors" do
40
+ em_amqp_connect do |client|
41
+ channel = AMQ::Client::Channel.new(client, 1)
42
+ channel.open do end
43
+ queue = AMQ::Client::Queue.new(client, channel)
44
+ queue.declare(false, false, false, true)
45
+ queue.bind("amq.fanout")
46
+ queue.consume(true) do |_, consumer_tag|
47
+ queue.on_delivery do |method, header, payload|
48
+ @received_message = payload
49
+ done
50
+ end
51
+
52
+ exchange = AMQ::Client::Exchange.new(client, channel, "amq.fanout", :fanout)
53
+ exchange.publish(message)
54
+ end
55
+ end
56
+
57
+ @received_message.should == message
58
+ end
59
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require "bundler"
4
+
5
+ Bundler.setup
6
+ Bundler.require(:default, :test)
7
+
8
+ #
9
+ # Ruby version-specific
10
+ #
11
+
12
+ case RUBY_VERSION
13
+ when "1.8.7" then
14
+ class Array
15
+ alias sample choice
16
+ end
17
+ when /^1.9/ then
18
+ Encoding.default_internal = Encoding::UTF_8
19
+ Encoding.default_external = Encoding::UTF_8
20
+ end
21
+
22
+ RSpec.configure do |c|
23
+ c.filter_run_excluding :nojruby => true if RUBY_PLATFORM =~ /java/
24
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require "ostruct"
4
+ require "spec_helper"
5
+ require "amq/client/adapter"
6
+
7
+ class SampleAdapter
8
+ include AMQ::Client::Adapter
9
+ end
10
+
11
+ describe SampleAdapter do
12
+ before(:all) do
13
+ load "amq/client.rb"
14
+ end
15
+
16
+ describe ".settings" do
17
+ it "should provide some default values" do
18
+ described_class.settings.should_not be_nil
19
+ described_class.settings[:host].should_not be_nil
20
+ end
21
+ end
22
+
23
+ describe ".logger" do
24
+ it "should provide a default logger" do
25
+ described_class.logger.should respond_to(:debug)
26
+ described_class.logger.should respond_to(:info)
27
+ described_class.logger.should respond_to(:error)
28
+ described_class.logger.should respond_to(:fatal)
29
+ end
30
+ end
31
+
32
+ describe ".logger=(logger)" do
33
+ context "when new logger doesn't respond to all the necessary methods" do
34
+ it "should raise an exception" do
35
+ lambda {
36
+ described_class.logger = Object.new
37
+ }.should raise_error(AMQ::Client::Logging::IncompatibleLoggerError)
38
+ end
39
+
40
+ it "should pass if the object provides all the necessary methods" do
41
+ described_class.logging = true
42
+
43
+ mock = OpenStruct.new(:debug => nil, :info => nil, :error => nil, :fatal => nil)
44
+ described_class.logger = mock
45
+ described_class.logger.should eql(mock)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require "spec_helper"
4
+ require "amq/client/entity"
5
+
6
+ describe AMQ::Client::Entity do
7
+ subject do
8
+ AMQ::Client::Entity.new(Object.new)
9
+ end
10
+
11
+ it "should maintain an associative array of callbacks" do
12
+ subject.callbacks.should be_kind_of(Hash)
13
+ end
14
+
15
+ describe "#exec_callback" do
16
+ it "executes callback for given event" do
17
+ proc = Proc.new { |*args, &block|
18
+ @called = true
19
+ }
20
+
21
+ expect {
22
+ subject.define_callback(:init, proc)
23
+ subject.define_callback :init do
24
+ @called2 = true
25
+ end
26
+ }.to change(subject.callbacks, :size).from(0).to(1)
27
+
28
+ subject.callbacks[:init].size.should == 2
29
+
30
+ subject.exec_callback(:init)
31
+
32
+ @called.should be_true
33
+ @called2.should be_true
34
+ end
35
+
36
+
37
+ it "should pass arguments to the callback" do
38
+ subject.define_callback :init, Proc.new { |*args| args.first }
39
+
40
+ subject.exec_callback(:init, 1).should eql([1])
41
+ end
42
+
43
+ it "should pass block to the callback" do
44
+ subject.define_callback :init, Proc.new { |*args, &block| block.call }
45
+
46
+ subject.exec_callback(:init) { "block" }.should == ["block"]
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ require "spec_helper"
4
+
5
+ class TestLogger
6
+ def log(message)
7
+ message
8
+ end
9
+
10
+ alias_method :debug, :log
11
+ alias_method :info, :log
12
+ alias_method :error, :log
13
+ alias_method :fatal, :log
14
+ end
15
+
16
+ class LoggingTestClass
17
+ attr_accessor :logging
18
+
19
+ def client
20
+ OpenStruct.new(:logger => TestLogger.new)
21
+ end
22
+
23
+ include AMQ::Client::Logging
24
+ end
25
+
26
+ describe AMQ::Client::Logging do
27
+ # We have to use Kernel#load so extensions to the
28
+ # Logging module from client.rb will be overridden.
29
+ before(:all) do
30
+ load "amq/client/logging.rb"
31
+
32
+ AMQ::Client::Logging.logging = true
33
+ end
34
+
35
+ after(:all) do
36
+ AMQ::Client::Logging.logging = false
37
+ end
38
+
39
+ context "including to an incompatible class" do
40
+ it "should raise an NotImplementedError if the class doesn't define method client" do
41
+ lambda {
42
+ Class.new { include AMQ::Client::Logging }
43
+ }.should raise_error(NotImplementedError)
44
+ end
45
+ end
46
+
47
+ context "including to a compatible class" do
48
+ subject { LoggingTestClass.new }
49
+
50
+ it "should be able to log via #client#logger of given class" do
51
+ subject.logging = true
52
+ subject.debug("message").should eql("message")
53
+ end
54
+
55
+ it "should not log anything if subject#logging is false" do
56
+ subject.logging = false
57
+ subject.debug("message").should be_nil
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+
3
+ require "spec_helper"
4
+ require "amq/client/mixins/status"
5
+
6
+ describe AMQ::Client::StatusMixin do
7
+ subject do
8
+ Class.new { include AMQ::Client::StatusMixin }.new
9
+ end
10
+
11
+ describe "#status=" do
12
+ context "if it is in the permitted values" do
13
+ it "should be able to store status" do
14
+ lambda { subject.status = :opened }.should_not raise_error
15
+ end
16
+ end
17
+
18
+ context "when given value isn't in the permitted values" do
19
+ it "should raise ImproperStatusError" do
20
+ lambda { subject.status = :sleepy }.should raise_error(AMQ::Client::StatusMixin::ImproperStatusError)
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "#opened?" do
26
+ it "should be true if the status is :opened" do
27
+ subject.status = :opened
28
+ subject.should be_opened
29
+ end
30
+
31
+ it "should be false if the status isn't :opened" do
32
+ subject.status = :opening
33
+ subject.should_not be_opened
34
+ end
35
+ end
36
+
37
+ describe "#closed?" do
38
+ it "should be true if the status is :closed" do
39
+ subject.status = :closed
40
+ subject.should be_closed
41
+ end
42
+
43
+ it "should be false if the status isn't :closed" do
44
+ subject.status = :closing
45
+ subject.should_not be_closed
46
+ end
47
+ end
48
+
49
+ describe "#opening?" do
50
+ it "should be true if the status is :opening" do
51
+ subject.status = :opening
52
+ subject.should be_opening
53
+ end
54
+
55
+ it "should be false if the status isn't :opening" do
56
+ subject.status = :opened
57
+ subject.should_not be_opening
58
+ end
59
+ end
60
+
61
+ describe "#closing?" do
62
+ it "should be true if the status is :closing" do
63
+ subject.status = :closing
64
+ subject.should be_closing
65
+ end
66
+
67
+ it "should be false if the status isn't :closing" do
68
+ subject.status = :opening
69
+ subject.should_not be_closing
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require "spec_helper"
4
+ require "amq/client/settings"
5
+
6
+ describe AMQ::Client::Settings do
7
+ describe ".default" do
8
+ it "should provide some default values" do
9
+ AMQ::Client::Settings.default.should_not be_nil
10
+ AMQ::Client::Settings.default[:host].should_not be_nil
11
+ end
12
+ end
13
+
14
+ describe ".configure(&block)" do
15
+ it "should merge custom settings with default settings" do
16
+ settings = AMQ::Client::Settings.configure(:host => "tagadab")
17
+ settings[:host].should eql("tagadab")
18
+ end
19
+
20
+ it "should merge custom settings from AMQP URL with default settings" do
21
+ pending "AMQP URL parsing" do
22
+ settings = AMQ::Client::Settings.configure("amqp://tagadab")
23
+ settings[:host].should eql("tagadab")
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require "ostruct"
4
+ require "spec_helper"
5
+ require "amq/client"
6
+
7
+ describe AMQ::Client do
8
+ it "should have VERSION" do
9
+ AMQ::Client::const_defined?(:VERSION).should be_true
10
+ end
11
+ end