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,45 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ __dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(__dir, "example_helper")
6
+
7
+ amq_client_example "Reject a message using basic.reject" do |client|
8
+ channel = AMQ::Client::Channel.new(client, 1)
9
+ channel.open do
10
+ puts "Channel #{channel.id} is now open!"
11
+ end
12
+
13
+ queue = AMQ::Client::Queue.new(client, channel)
14
+ queue.declare
15
+
16
+ queue.bind("amq.fanout") do
17
+ puts "Queue #{queue.name} is now bound to amq.fanout"
18
+ end
19
+
20
+ queue.consume do |consumer_tag|
21
+ queue.on_delivery do |method, header, payload|
22
+ puts "Got a delivery: #{payload} (delivery tag: #{method.delivery_tag}), rejecting..."
23
+
24
+ queue.reject(method.delivery_tag, false)
25
+ end
26
+
27
+ exchange = AMQ::Client::Exchange.new(client, channel, "amq.fanout", :fanout)
28
+ 10.times do |i|
29
+ exchange.publish("Message ##{i}")
30
+ end
31
+ end
32
+
33
+ show_stopper = Proc.new {
34
+ client.disconnect do
35
+ puts
36
+ puts "AMQP connection is now properly closed"
37
+ EM.stop
38
+ end
39
+ }
40
+
41
+ Signal.trap "INT", show_stopper
42
+ Signal.trap "TERM", show_stopper
43
+
44
+ EM.add_timer(1, show_stopper)
45
+ end
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ __dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(__dir, "example_helper")
6
+
7
+ amq_client_example "Set a queue up for message delivery" do |client|
8
+ channel = AMQ::Client::Channel.new(client, 1)
9
+ channel.open do
10
+ puts "Channel #{channel.id} is now open!"
11
+ end
12
+
13
+ queue = AMQ::Client::Queue.new(client, channel)
14
+ queue.declare(false, false, false, true) do
15
+ puts "Server-named, auto-deletable Queue #{queue.name.inspect} is ready"
16
+ end
17
+
18
+ queue.bind("amq.fanout") do
19
+ puts "Queue #{queue.name} is now bound to amq.fanout"
20
+ end
21
+
22
+ exchange = AMQ::Client::Exchange.new(client, channel, "amq.fanout", :fanout)
23
+ 30.times do |i|
24
+ puts "Publishing message ##{i}"
25
+ exchange.publish("Message ##{i}")
26
+ end
27
+ sleep 0.1
28
+
29
+ 30.times do |i|
30
+ queue.get(true) do |method, header, payload|
31
+ puts "basic.get callback has fired"
32
+ puts
33
+ puts " => Payload is #{payload}"
34
+ puts " => header is #{header.decode_payload.inspect}"
35
+ puts " => delivery_tag is #{method.delivery_tag}"
36
+ puts " => redelivered is #{method.redelivered}"
37
+ puts " => exchange is #{method.exchange}"
38
+ puts " => routing_key is #{method.routing_key}"
39
+ puts " => message_count is #{method.message_count}"
40
+ puts
41
+ puts
42
+ end
43
+ end
44
+
45
+ show_stopper = Proc.new {
46
+ client.disconnect do
47
+ puts
48
+ puts "AMQP connection is now properly closed"
49
+ EM.stop
50
+ end
51
+ }
52
+
53
+ Signal.trap "INT", show_stopper
54
+ Signal.trap "TERM", show_stopper
55
+
56
+ EM.add_timer(1, show_stopper)
57
+ end
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ __dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(__dir, "example_helper")
6
+
7
+ amq_client_example "Set a queue up for message delivery" do |client|
8
+ channel = AMQ::Client::Channel.new(client, 1)
9
+ channel.open do
10
+ puts "Channel #{channel.id} is now open!"
11
+ end
12
+
13
+ queue = AMQ::Client::Queue.new(client, channel)
14
+ queue.declare(false, false, false, true) do
15
+ puts "Server-named, auto-deletable Queue #{queue.name.inspect} is ready"
16
+ end
17
+
18
+ queue.bind("amq.fanout") do
19
+ puts "Queue #{queue.name} is now bound to amq.fanout"
20
+ end
21
+ sleep 0.1
22
+
23
+ 10.times do |i|
24
+ queue.get(true) do |method, header, payload|
25
+ puts "basic.get callback has fired"
26
+ puts
27
+ puts "Payload is #{payload}"
28
+ if header
29
+ puts "header is #{header.decode_payload.inspect}"
30
+ else
31
+ puts "header is nil"
32
+ end
33
+ puts "delivery_tag is #{method.delivery_tag.inspect}"
34
+ puts "redelivered is #{method.redelivered.inspect}"
35
+ puts "exchange is #{method.exchange.inspect}"
36
+ puts "routing_key is #{method.routing_key.inspect}"
37
+ puts "message_count is #{method.message_count.inspect}"
38
+ end
39
+ end
40
+
41
+ show_stopper = Proc.new {
42
+ client.disconnect do
43
+ puts
44
+ puts "AMQP connection is now properly closed"
45
+ EM.stop
46
+ end
47
+ }
48
+
49
+ Signal.trap "INT", show_stopper
50
+ Signal.trap "TERM", show_stopper
51
+
52
+ EM.add_timer(1, show_stopper)
53
+ end
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ __dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(__dir, "example_helper")
6
+
7
+ amq_client_example "Publish 100 messages using basic.publish" do |client|
8
+ puts "AMQP connection is open: #{client.connection.server_properties.inspect}"
9
+
10
+ channel = AMQ::Client::Channel.new(client, 1)
11
+ channel.open do
12
+ puts "Channel #{channel.id} is now open!"
13
+ end
14
+
15
+ exchange = AMQ::Client::Exchange.new(client, channel, "amqclient.adapters.em.exchange1", :fanout)
16
+ exchange.declare do
17
+ 100.times do
18
+ # exchange.publish("à bientôt!")
19
+ exchange.publish("See you soon!")
20
+ print "."
21
+ end
22
+
23
+ $stdout.flush
24
+ end
25
+
26
+ show_stopper = Proc.new {
27
+ client.disconnect do
28
+ puts
29
+ puts "AMQP connection is now properly closed"
30
+ EM.stop
31
+ end
32
+ }
33
+
34
+ EM.add_periodic_timer(1, show_stopper)
35
+
36
+ Signal.trap "INT", show_stopper
37
+ Signal.trap "TERM", show_stopper
38
+ end
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ __dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(__dir, "example_helper")
6
+
7
+ amq_client_example "Alter prefetching settings using basic.qos" do |client|
8
+ channel = AMQ::Client::Channel.new(client, 1)
9
+ channel.open do
10
+ AMQ::Client::Queue.new(client, channel).declare(false, false, false, true) do |q, _, _, _|
11
+ channel.qos do |_|
12
+ puts "basic.qos callback has fired"
13
+ end
14
+ end
15
+
16
+ show_stopper = Proc.new {
17
+ client.disconnect do
18
+ puts
19
+ puts "AMQP connection is now properly closed"
20
+ EM.stop
21
+ end
22
+ }
23
+
24
+ Signal.trap "INT", show_stopper
25
+ Signal.trap "TERM", show_stopper
26
+
27
+ EM.add_timer(1, show_stopper)
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ __dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(__dir, "example_helper")
6
+
7
+ amq_client_example "Notify broker about consumer recovery using basic.recover" do |client|
8
+ channel = AMQ::Client::Channel.new(client, 1)
9
+ channel.open do
10
+ AMQ::Client::Queue.new(client, channel).declare(false, false, false, true) do |q, _, _, _|
11
+ channel.recover do |_|
12
+ puts "basic.recover callback has fired"
13
+ end
14
+ end
15
+
16
+ show_stopper = Proc.new {
17
+ client.disconnect do
18
+ puts
19
+ puts "AMQP connection is now properly closed"
20
+ EM.stop
21
+ end
22
+ }
23
+
24
+ Signal.trap "INT", show_stopper
25
+ Signal.trap "TERM", show_stopper
26
+
27
+ EM.add_timer(1, show_stopper)
28
+ end
29
+ end
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ __dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(__dir, "example_helper")
6
+
7
+ amq_client_example "basic.return example" do |client|
8
+ channel = AMQ::Client::Channel.new(client, 1)
9
+ channel.open do
10
+ queue = AMQ::Client::Queue.new(client, channel).declare(false, false, false, true)
11
+
12
+ exchange = AMQ::Client::Exchange.new(client, channel, "amq.fanout", :fanout)
13
+ exchange.on_return do |method|
14
+ puts "Handling a returned message: exchange = #{method.exchange}, reply_code = #{method.reply_code}, reply_text = #{method.reply_text}"
15
+ end
16
+
17
+ 10.times do |i|
18
+ exchange.publish("Message ##{i}", AMQ::Protocol::EMPTY_STRING, {}, false, true)
19
+ end
20
+
21
+ show_stopper = Proc.new {
22
+ client.disconnect do
23
+ puts
24
+ puts "AMQP connection is now properly closed"
25
+ EM.stop
26
+ end
27
+ }
28
+
29
+ Signal.trap "INT", show_stopper
30
+ Signal.trap "TERM", show_stopper
31
+
32
+ EM.add_timer(1, show_stopper)
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ __dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(__dir, "example_helper")
6
+
7
+ amq_client_example "Open and then close AMQ channel" do |client|
8
+ puts "AMQP connection is open: #{client.connection.server_properties.inspect}"
9
+
10
+ channel = AMQ::Client::Channel.new(client, 1)
11
+ channel.open do
12
+ puts "Channel #{channel.id} is now open!"
13
+ puts "Lets close it."
14
+ channel.close do
15
+ puts "Closed channel ##{channel.id}"
16
+ puts
17
+ client.disconnect do
18
+ puts
19
+ puts "AMQP connection is now properly closed"
20
+ EM.stop
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ __dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(__dir, "example_helper")
6
+
7
+ amq_client_example "Activate or deactivate channel delivery using channel.flow" do |client|
8
+ channel = AMQ::Client::Channel.new(client, 1)
9
+ channel.open do
10
+ AMQ::Client::Queue.new(client, channel).declare(false, false, false, true) do |q, _, _, _|
11
+ puts "flow is now #{channel.flow_is_active? ? 'on' : 'off'}"
12
+
13
+ channel.flow(false) do |method|
14
+ puts "flow is now #{method.active ? 'on' : 'off'}"
15
+ end
16
+
17
+ sleep 0.1
18
+ channel.flow(true) do |method|
19
+ puts "flow is now #{method.active ? 'on' : 'off'}"
20
+ end
21
+ end
22
+
23
+ show_stopper = Proc.new {
24
+ client.disconnect do
25
+ puts
26
+ puts "AMQP connection is now properly closed"
27
+ EM.stop
28
+ end
29
+ }
30
+
31
+ Signal.trap "INT", show_stopper
32
+ Signal.trap "TERM", show_stopper
33
+
34
+ EM.add_timer(1, show_stopper)
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ __dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(__dir, "example_helper")
6
+
7
+ amq_client_example "Channel-level exception handling" do |client|
8
+ channel = AMQ::Client::Channel.new(client, 1)
9
+ channel.open do
10
+ puts "Channel #{channel.id} is now open"
11
+
12
+ show_stopper = Proc.new {
13
+ client.disconnect do
14
+ puts
15
+ puts "AMQP connection is now properly closed"
16
+ EM.stop
17
+ end
18
+ }
19
+
20
+
21
+
22
+ channel.on_error do
23
+ puts "Oops, there is a channel-levle exceptions!"
24
+
25
+ EM.add_timer(1.2) { show_stopper.call }
26
+ end
27
+
28
+ # amq.* names are reserevd so this causes a channel-level exception. MK.
29
+ x = AMQ::Client::Exchange.new(client, channel, "amq.client.examples.extensions.x1", :direct)
30
+ x.declare(false, false, false, true, false)
31
+
32
+
33
+ EM.add_timer(1) do
34
+ if channel.closed?
35
+ puts "1 second later channel #{channel.id} is closed"
36
+ end
37
+ end
38
+
39
+ Signal.trap "INT", show_stopper
40
+ Signal.trap "TERM", show_stopper
41
+
42
+ EM.add_timer(2, show_stopper)
43
+ end
44
+ end
@@ -0,0 +1,39 @@
1
+ require "bundler"
2
+
3
+ Bundler.setup
4
+ Bundler.require(:default)
5
+
6
+ $LOAD_PATH.unshift(File.expand_path("../../../lib", __FILE__))
7
+
8
+ require "amq/client/adapters/event_machine"
9
+ require "amq/client/queue"
10
+ require "amq/client/exchange"
11
+
12
+
13
+ if RUBY_VERSION.to_s =~ /^1.9/
14
+ Encoding.default_internal = Encoding::UTF_8
15
+ Encoding.default_external = Encoding::UTF_8
16
+ end
17
+
18
+
19
+ def amq_client_example(description = "", &block)
20
+ EM.run do
21
+ AMQ::Client::EventMachineClient.connect(:port => 5672, :vhost => "/amq_client_testbed", :frame_max => 65536, :heartbeat_interval => 1) do |client|
22
+ begin
23
+ puts
24
+ puts
25
+ puts "=============> #{description}"
26
+
27
+ block.call(client)
28
+ rescue Interrupt
29
+ warn "Manually interrupted, terminating ..."
30
+ rescue Exception => exception
31
+ STDERR.puts "\n\e[1;31m[#{exception.class}] #{exception.message}\e[0m"
32
+ exception.backtrace.each do |line|
33
+ line = "\e[0;36m#{line}\e[0m" if line.match(Regexp::quote(File.basename(__FILE__)))
34
+ STDERR.puts " - " + line
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end