amqp 0.8.0.rc13 → 0.8.0.rc14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/.rspec +2 -1
  2. data/.travis.yml +8 -2
  3. data/.yardopts +1 -0
  4. data/CHANGELOG +9 -0
  5. data/Gemfile +17 -11
  6. data/README.md +26 -16
  7. data/amqp.gemspec +2 -2
  8. data/bin/ci/before_build.sh +21 -0
  9. data/docs/08Migration.textile +199 -5
  10. data/docs/AMQP091ModelExplained.textile +322 -0
  11. data/docs/Bindings.textile +24 -4
  12. data/docs/Clustering.textile +1 -1
  13. data/docs/ConnectingToTheBroker.textile +98 -82
  14. data/docs/ConnectionEncryptionWithTLS.textile +65 -5
  15. data/docs/DocumentationGuidesIndex.textile +93 -13
  16. data/docs/Durability.textile +1 -1
  17. data/docs/ErrorHandling.textile +458 -94
  18. data/docs/Exchanges.textile +901 -87
  19. data/docs/GettingStarted.textile +278 -143
  20. data/docs/PatternsAndUseCases.textile +420 -0
  21. data/docs/Queues.textile +730 -178
  22. data/docs/RabbitMQVersions.textile +18 -3
  23. data/docs/RunningTests.textile +1 -1
  24. data/docs/TestingWithEventedSpec.textile +121 -0
  25. data/docs/Troubleshooting.textile +15 -1
  26. data/docs/VendorSpecificExtensions.textile +1 -1
  27. data/docs/diagrams/001_hello_world_example_routing.png +0 -0
  28. data/docs/diagrams/002_blabbr_example_routing.png +0 -0
  29. data/docs/diagrams/003_weathr_example_routing.png +0 -0
  30. data/docs/diagrams/004_fanout_exchange.png +0 -0
  31. data/docs/diagrams/005_direct_exchange.png +0 -0
  32. data/docs/diagrams/redhat/direct_exchange.png +0 -0
  33. data/docs/diagrams/redhat/fanout_exchange.png +0 -0
  34. data/docs/diagrams/redhat/topic_exchange.png +0 -0
  35. data/examples/error_handling/automatic_recovery_of_channel_and_queues.rb +50 -0
  36. data/examples/error_handling/automatically_recovering_hello_world_consumer.rb +51 -0
  37. data/examples/error_handling/automatically_recovering_hello_world_consumer_that_uses_a_server_named_queue.rb +51 -0
  38. data/examples/error_handling/basic_connection_failover.rb +22 -0
  39. data/examples/error_handling/channel_level_exception.rb +9 -2
  40. data/examples/error_handling/connection_level_exception.rb +8 -1
  41. data/examples/error_handling/connection_level_exception_with_objects.rb +49 -0
  42. data/examples/error_handling/connection_loss_handler.rb +1 -5
  43. data/examples/error_handling/hello_world_producer.rb +43 -0
  44. data/examples/error_handling/insufficient_permissions.rb +54 -0
  45. data/examples/error_handling/manual_connection_and_channel_recovery.rb +71 -0
  46. data/examples/error_handling/queue_exclusivity_violation.rb +41 -0
  47. data/examples/error_handling/queue_name_violation.rb +31 -0
  48. data/examples/exchanges/autodeletion_of_exchanges.rb +1 -4
  49. data/examples/guides/queues/01a_declaring_a_server_named_queue_using_queue_constructor.rb +7 -8
  50. data/examples/guides/queues/01b_declaring_a_queue_using_queue_constructor.rb +7 -8
  51. data/examples/guides/queues/02a_declaring_a_durable_shared_queue.rb +5 -8
  52. data/examples/guides/queues/02b_declaring_a_durable_shared_queue.rb +5 -8
  53. data/examples/guides/queues/03a_declaring_a_temporary_exclusive_queue.rb +7 -8
  54. data/examples/guides/queues/04_bind_a_queue_using_exchange_instance.rb +9 -10
  55. data/examples/guides/queues/05_bind_a_queue_using_exchange_name.rb +8 -10
  56. data/examples/guides/queues/06_subscribe_to_receive_messages.rb +10 -12
  57. data/examples/guides/queues/07_fetch_a_message_from_the_queue.rb +14 -14
  58. data/examples/guides/queues/08_unsubscribing_a_consumer.rb +13 -16
  59. data/examples/guides/queues/09_unbinding_from_exchange.rb +16 -22
  60. data/examples/guides/queues/10_purge_a_queue.rb +13 -18
  61. data/examples/guides/queues/11_deleting_a_queue.rb +14 -19
  62. data/examples/guides/queues/12_objects_that_consume_messages.rb +69 -0
  63. data/examples/guides/queues/13_objects_that_consume_messages_take_two.rb +89 -0
  64. data/examples/hello_world.rb +1 -3
  65. data/examples/hello_world_with_an_empty_string.rb +5 -6
  66. data/examples/inspecting_server_information.rb +45 -0
  67. data/examples/issues/issue_93.rb +23 -0
  68. data/examples/issues/issue_94.rb +23 -0
  69. data/examples/patterns/command/consumer.rb +45 -0
  70. data/examples/patterns/command/producer.rb +26 -0
  71. data/examples/patterns/request_reply/client.rb +29 -0
  72. data/examples/patterns/request_reply/server.rb +26 -0
  73. data/examples/publishing/publishing_a_one_off_message.rb +6 -4
  74. data/examples/publishing/returned_messages.rb +2 -10
  75. data/examples/queues/accessing_message_metadata.rb +15 -13
  76. data/examples/queues/queue_status.rb +12 -15
  77. data/examples/routing/fanout_routing.rb +33 -0
  78. data/examples/routing/headers_routing.rb +17 -15
  79. data/examples/routing/round_robin_with_direct_exchange.rb +39 -0
  80. data/examples/routing/round_robin_with_the_default_exchange.rb +38 -0
  81. data/examples/routing/unroutable_mandatory_message_is_returned.rb +33 -0
  82. data/examples/routing/weather_updates.rb +15 -20
  83. data/examples/tls/using_tls.rb +41 -0
  84. data/lib/amqp/bit_set.rb +80 -0
  85. data/lib/amqp/broker.rb +72 -0
  86. data/lib/amqp/channel.rb +93 -13
  87. data/lib/amqp/client.rb +11 -22
  88. data/lib/amqp/compatibility/ruby187_patchlevel_check.rb +2 -0
  89. data/lib/amqp/connection.rb +2 -3
  90. data/lib/amqp/consumer.rb +208 -0
  91. data/lib/amqp/deprecated/fork.rb +2 -0
  92. data/lib/amqp/deprecated/mq.rb +2 -0
  93. data/lib/amqp/exchange.rb +6 -4
  94. data/lib/amqp/extensions/rabbitmq.rb +3 -1
  95. data/lib/amqp/header.rb +76 -14
  96. data/lib/amqp/int_allocator.rb +96 -0
  97. data/lib/amqp/logger.rb +2 -0
  98. data/lib/amqp/queue.rb +242 -86
  99. data/lib/amqp/rpc.rb +2 -0
  100. data/lib/amqp/session.rb +169 -9
  101. data/lib/amqp/utilities/event_loop_helper.rb +2 -0
  102. data/lib/amqp/utilities/server_type.rb +2 -0
  103. data/lib/amqp/version.rb +2 -2
  104. data/lib/mq.rb +4 -2
  105. data/lib/mq/logger.rb +3 -1
  106. data/lib/mq/rpc.rb +3 -1
  107. data/spec/integration/authentication_spec.rb +17 -10
  108. data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +1 -1
  109. data/spec/integration/automatic_recovery_predicate_spec.rb +68 -0
  110. data/spec/integration/basic_get_spec.rb +2 -1
  111. data/spec/integration/{extensions/basic_return_spec.rb → basic_return_spec.rb} +2 -1
  112. data/spec/integration/channel_level_exception_handling_spec.rb +53 -0
  113. data/spec/integration/connection_level_exception_handling_spec.rb +49 -0
  114. data/spec/integration/declare_and_immediately_bind_a_server_named_queue_spec.rb +38 -17
  115. data/spec/integration/declare_one_hundred_server_named_queues_spec.rb +44 -0
  116. data/spec/integration/direct_exchange_routing_spec.rb +125 -0
  117. data/spec/integration/exchange_declaration_spec.rb +75 -46
  118. data/spec/integration/extensions/rabbitmq/publisher_confirmations_spec.rb +180 -0
  119. data/spec/integration/{workload_distribution_spec.rb → fanout_exchange_routing_spec.rb} +10 -9
  120. data/spec/integration/headers_exchange_routing_spec.rb +269 -0
  121. data/spec/integration/hello_world_spec.rb +77 -0
  122. data/spec/integration/immediate_messages_spec.rb +59 -0
  123. data/spec/integration/mandatory_messages_spec.rb +52 -0
  124. data/spec/integration/message_metadata_access_spec.rb +106 -0
  125. data/spec/integration/multiple_consumers_per_queue_spec.rb +319 -0
  126. data/spec/integration/ordering_of_published_messages_spec.rb +96 -0
  127. data/spec/integration/queue_declaration_spec.rb +8 -8
  128. data/spec/integration/queue_status_spec.rb +66 -0
  129. data/spec/integration/recovery/per_channel_automatic_recovery_on_graceful_broker_shutdown_spec.rb +76 -0
  130. data/spec/integration/recovery/per_channel_automatic_recovery_spec.rb +72 -0
  131. data/spec/integration/redelivery_of_unacknowledged_messages_spec.rb +96 -0
  132. data/spec/integration/regressions/concurrent_publishing_on_the_same_channel_spec.rb +91 -0
  133. data/spec/integration/regressions/empty_message_body_spec.rb +56 -0
  134. data/spec/integration/regressions/issue66_spec.rb +2 -1
  135. data/spec/integration/reply_queue_communication_spec.rb +2 -1
  136. data/spec/integration/store_and_forward_spec.rb +4 -3
  137. data/spec/integration/topic_subscription_spec.rb +2 -1
  138. data/spec/integration/tx_commit_spec.rb +124 -0
  139. data/spec/integration/tx_rollback_spec.rb +167 -0
  140. data/spec/spec_helper.rb +44 -71
  141. data/spec/unit/amqp/bit_set_spec.rb +127 -0
  142. data/spec/unit/amqp/channel_id_allocation_spec.rb +40 -0
  143. data/spec/unit/amqp/connection_spec.rb +4 -2
  144. data/spec/unit/amqp/int_allocator_spec.rb +116 -0
  145. metadata +92 -26
  146. data/CONTRIBUTORS +0 -29
  147. data/docs/Routing.textile +0 -30
  148. data/examples/real-world/task-queue/README.textile +0 -3
  149. data/examples/real-world/task-queue/consumer.rb +0 -27
  150. data/examples/real-world/task-queue/producer.rb +0 -22
  151. data/spec/unit/amqp/basic_spec.rb +0 -39
  152. data/tasks.rb +0 -4
data/lib/amqp/client.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require "uri"
3
+ require 'amq/client/settings'
4
4
  require "amqp/session"
5
5
 
6
6
  module AMQP
@@ -33,11 +33,16 @@ module AMQP
33
33
  Hash.new
34
34
  end
35
35
 
36
- if block
37
- AMQP.client.connect(opts.merge(options), &block)
38
- else
39
- AMQP.client.connect(opts.merge(options))
36
+ connection = if block
37
+ AMQP.client.connect(opts.merge(options), &block)
38
+ else
39
+ AMQP.client.connect(opts.merge(options))
40
+ end
41
+
42
+ connection.on_open do
43
+ require "amqp/extensions/rabbitmq" if connection.broker.rabbitmq?
40
44
  end
45
+ connection
41
46
  end
42
47
 
43
48
  # Parses AMQP connection URI and returns its components as a hash.
@@ -80,23 +85,7 @@ module AMQP
80
85
  # @see http://bit.ly/ks8MXK Connecting to The Broker documentation guide
81
86
  # @api public
82
87
  def self.parse_connection_uri(connection_string)
83
- uri = URI.parse(connection_string)
84
- raise ArgumentError.new("Connection URI must use amqp or amqps schema (example: amqp://bus.megacorp.internal:5766), learn more at http://bit.ly/ks8MXK") unless %w{amqp amqps}.include?(uri.scheme)
85
-
86
- opts = {}
87
-
88
- opts[:scheme] = uri.scheme
89
- opts[:user] = URI.unescape(uri.user) if uri.user
90
- opts[:pass] = URI.unescape(uri.password) if uri.password
91
- opts[:host] = uri.host if uri.host
92
- opts[:port] = uri.port || AMQP_PORTS[uri.scheme]
93
- opts[:ssl] = uri.scheme == AMQPS
94
- if uri.path =~ %r{^/(.*)}
95
- raise ArgumentError.new("#{uri} has multiple-segment path; please percent-encode any slashes in the vhost name (e.g. /production => %2Fproduction). Learn more at http://bit.ly/amqp-gem-and-connection-uris") if $1.index('/')
96
- opts[:vhost] = URI.unescape($1)
97
- end
98
-
99
- opts
88
+ AMQ::Client::Settings.parse_amqp_url(connection_string)
100
89
  end
101
90
  end # Client
102
91
 
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  if RUBY_VERSION =~ /^1.8.7/
2
4
  require "rbconfig"
3
5
  conf = RbConfig::CONFIG
@@ -13,9 +13,8 @@ module AMQP
13
13
 
14
14
  # Starts EventMachine event loop unless it is already running and connects
15
15
  # to AMQP broker using {AMQP.connect}. It is generally a good idea to
16
- # start EventMachine event loop in a separate thread and use {AMQP.connect}.
17
- # That said, for applications that do not publish or handle large volumes of
18
- # data {AMQP.start} works very well and its use is not discouraged.
16
+ # start EventMachine event loop in a separate thread and use {AMQP.connect}
17
+ # (for Web applications that do not use Thin or Goliath, it is the only option).
19
18
  #
20
19
  # See {AMQP.connect} for information about arguments this method takes and
21
20
  # information about relevant topics such as authentication failure handling.
@@ -0,0 +1,208 @@
1
+ # encoding: utf-8
2
+
3
+ require "amq/client/async/consumer"
4
+
5
+ module AMQP
6
+ # AMQP consumers are entities that handle messages delivered to them ("push API" as opposed to "pull API") by AMQP broker.
7
+ # Every consumer is associated with a queue. Consumers can be exclusive (no other consumers can be registered for the same queue)
8
+ # or not (consumers share the queue). In the case of multiple consumers per queue, messages are distributed in round robin
9
+ # manner with respect to channel-level prefetch setting).
10
+ #
11
+ # @see AMQP::Queue
12
+ # @see AMQP::Queue#subscribe
13
+ # @see AMQP::Queue#cancel
14
+ class Consumer < AMQ::Client::Async::Consumer
15
+
16
+ #
17
+ # API
18
+ #
19
+
20
+ # @return [AMQP::Channel] Channel this consumer uses
21
+ attr_reader :channel
22
+ # @return [AMQP::Queue] Queue messages are consumed from
23
+ attr_reader :queue
24
+ # @return [String] Consumer tag, unique consumer identifier
25
+ attr_reader :consumer_tag
26
+ # @return [Hash] Custom subscription metadata
27
+ attr_reader :arguments
28
+
29
+
30
+ # @return [AMQ::Client::ConsumerTagGenerator] Consumer tag generator
31
+ def self.tag_generator
32
+ @tag_generator ||= AMQ::Client::ConsumerTagGenerator.new
33
+ end # self.tag_generator
34
+
35
+ # @param [AMQ::Client::ConsumerTagGenerator] Assigns consumer tag generator that will be used by consumer instances
36
+ # @return [AMQ::Client::ConsumerTagGenerator] Provided argument
37
+ def self.tag_generator=(generator)
38
+ @tag_generator = generator
39
+ end
40
+
41
+
42
+ def initialize(channel, queue, consumer_tag = nil, exclusive = false, no_ack = false, arguments = {}, no_local = false)
43
+ super(channel, queue, (consumer_tag || self.class.tag_generator.generate_for(queue)), exclusive, no_ack, arguments, no_local)
44
+ end # initialize
45
+
46
+ # @return [Boolean] true if this consumer is exclusive (other consumers for the same queue are not allowed)
47
+ def exclusive?
48
+ super
49
+ end # exclusive?
50
+
51
+
52
+
53
+ # Begin consuming messages from the queue
54
+ # @return [AMQP::Consumer] self
55
+ def consume(nowait = false, &block)
56
+ @channel.once_open do
57
+ @queue.once_declared do
58
+ super(nowait, &block)
59
+ end
60
+ end
61
+
62
+ self
63
+ end # consume(nowait = false, &block)
64
+
65
+ # Used by automatic recovery code.
66
+ # @api plugin
67
+ # @return [AMQP::Consumer] self
68
+ def resubscribe(&block)
69
+ @channel.once_open do
70
+ @queue.once_declared do
71
+ self.unregister_with_channel
72
+ @consumer_tag = self.class.tag_generator.generate_for(@queue)
73
+ self.register_with_channel
74
+
75
+ super(&block)
76
+ end
77
+ end
78
+
79
+ self
80
+ end # resubscribe(&block)
81
+
82
+ # @return [AMQP::Consumer] self
83
+ def cancel(nowait = false, &block)
84
+ @channel.once_open do
85
+ @queue.once_declared do
86
+ super(nowait, &block)
87
+ end
88
+ end
89
+
90
+ self
91
+ end # cancel(nowait = false, &block)
92
+
93
+ # {AMQP::Queue} API compatibility.
94
+ #
95
+ # @return [Boolean] true if this consumer is active (subscribed for message delivery)
96
+ # @api public
97
+ def subscribed?
98
+ !@callbacks[:delivery].empty?
99
+ end # subscribed?
100
+
101
+ # Legacy {AMQP::Queue} API compatibility.
102
+ # @private
103
+ # @deprecated
104
+ def callback
105
+ if @callbacks[:delivery]
106
+ @callbacks[:delivery].first
107
+ end
108
+ end # callback
109
+
110
+
111
+ # Register a block that will be used to handle delivered messages.
112
+ #
113
+ # @return [AMQP::Consumer] self
114
+ # @see AMQP::Queue#subscribe
115
+ def on_delivery(&block)
116
+ # We have to maintain this multiple arities jazz
117
+ # because older versions this gem are used in examples in at least 3
118
+ # books published by O'Reilly :(. MK.
119
+ delivery_shim = Proc.new { |basic_deliver, headers, payload|
120
+ case block.arity
121
+ when 1 then
122
+ block.call(payload)
123
+ when 2 then
124
+ h = Header.new(@channel, basic_deliver, headers.decode_payload)
125
+ block.call(h, payload)
126
+ else
127
+ h = Header.new(@channel, basic_deliver, headers.decode_payload)
128
+ block.call(h, payload, basic_deliver.consumer_tag, basic_deliver.delivery_tag, basic_deliver.redelivered, basic_deliver.exchange, basic_deliver.routing_key)
129
+ end
130
+ }
131
+
132
+ super(&delivery_shim)
133
+ end # on_delivery(&block)
134
+
135
+
136
+ # @group Acknowledging & Rejecting Messages
137
+
138
+ # Acknowledge a delivery tag.
139
+ # @return [Consumer] self
140
+ #
141
+ # @api public
142
+ # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.8.3.13.)
143
+ def acknowledge(delivery_tag)
144
+ super(delivery_tag)
145
+ end # acknowledge(delivery_tag)
146
+
147
+ #
148
+ # @return [Consumer] self
149
+ #
150
+ # @api public
151
+ # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.8.3.14.)
152
+ def reject(delivery_tag, requeue = true)
153
+ super(delivery_tag, requeue)
154
+ end # reject(delivery_tag, requeue = true)
155
+
156
+ # @endgroup
157
+
158
+
159
+ # @group Error Handling & Recovery
160
+
161
+ # Defines a callback that will be executed after TCP connection is interrupted (typically because of a network failure).
162
+ # Only one callback can be defined (the one defined last replaces previously added ones).
163
+ #
164
+ # @api public
165
+ def on_connection_interruption(&block)
166
+ super(&block)
167
+ end # on_connection_interruption(&block)
168
+ alias after_connection_interruption on_connection_interruption
169
+
170
+
171
+ # Defines a callback that will be executed after TCP connection is recovered after a network failure
172
+ # but before AMQP connection is re-opened.
173
+ # Only one callback can be defined (the one defined last replaces previously added ones).
174
+ #
175
+ # @api public
176
+ def before_recovery(&block)
177
+ super(&block)
178
+ end # before_recovery(&block)
179
+
180
+ # Defines a callback that will be executed when AMQP connection is recovered after a network failure..
181
+ # Only one callback can be defined (the one defined last replaces previously added ones).
182
+ #
183
+ # @api public
184
+ def on_recovery(&block)
185
+ super(&block)
186
+ end # on_recovery(&block)
187
+ alias after_recovery on_recovery
188
+
189
+
190
+ # Called by associated connection object when AMQP connection has been re-established
191
+ # (for example, after a network failure).
192
+ #
193
+ # @api plugin
194
+ def auto_recover
195
+ super
196
+ end # auto_recover
197
+
198
+ # @endgroup
199
+
200
+
201
+ # @return [String] Readable representation of relevant object state.
202
+ def inspect
203
+ "#<AMQP::Consumer:#{@consumer_tag}> queue=#{@queue.name} channel=#{@channel.id} callbacks=#{@callbacks.inspect}"
204
+ end # inspect
205
+
206
+
207
+ end # Consumer
208
+ end # AMQP
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require "amqp/ext/em"
2
4
 
3
5
  module AMQP
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # Alias for AMQP::Channel.
2
4
  #
3
5
  # @note This class will be removed before 1.0 release.
data/lib/amqp/exchange.rb CHANGED
@@ -374,10 +374,10 @@ module AMQP
374
374
  #
375
375
  # h2. Data serialization
376
376
  #
377
- # Note that this method calls #to_s on payload argument value. You are encouraged to take care of
377
+ # Note that this method calls #to_s on payload argument value. Applications are encouraged of
378
378
  # data serialization before publishing (using JSON, Thrift, Protocol Buffers or other serialization library).
379
- # Note that because AMQP is a binary protocol, text formats like JSON lose lose their strong point of being easy
380
- # to inspect data as it travels across network. For the same reason BSON may be a good fit.
379
+ # Note that because AMQP is a binary protocol, text formats like JSON largely lose their strong point of being easy
380
+ # to inspect as data travels across network, so "BSON":http://bsonspec.org may be a good fit.
381
381
  #
382
382
  #
383
383
  # h2. Publishing and message persistence
@@ -477,7 +477,9 @@ module AMQP
477
477
  opts = @default_publish_options.merge(options)
478
478
 
479
479
  @channel.once_open do
480
- super(payload.to_s, opts[:key] || opts[:routing_key] || @default_routing_key, @default_headers.merge(options), opts[:mandatory], opts[:immediate])
480
+ properties = @default_headers.merge(options)
481
+ properties[:delivery_mode] = properties.delete(:persistent) ? 2 : 1
482
+ super(payload.to_s, opts[:key] || opts[:routing_key] || @default_routing_key, properties, opts[:mandatory], opts[:immediate])
481
483
 
482
484
  # don't pass block to AMQ::Client::Exchange#publish because it will be executed
483
485
  # immediately and we want to do it later. See ruby-amqp/amqp/#67 MK.
@@ -1 +1,3 @@
1
- require "amq/client/extensions/rabbitmq"
1
+ # encoding: utf-8
2
+
3
+ require "amq/client/extensions/rabbitmq"
data/lib/amqp/header.rb CHANGED
@@ -1,27 +1,31 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module AMQP
4
- # We keep this class around for sake of API compatibility with 0.7.x series.
5
- #
6
- # @note This class is not part of the public API and may be removed in the future without any warning.
4
+ # Message metadata (aka envelope).
7
5
  class Header
8
6
 
9
7
  #
10
8
  # API
11
9
  #
12
10
 
11
+ # @api public
13
12
  # @return [AMQP::Channel]
14
13
  attr_reader :channel
15
- # AMQP method frame this header is associated with. Carries additional information that varies between AMQP methods.
14
+
15
+ # AMQP method frame this header is associated with.
16
+ # Carries additional information that varies between AMQP methods.
17
+ #
18
+ # @api public
16
19
  # @return [AMQ::Protocol::Method]
17
20
  attr_reader :method
18
- # AMQP message header as a hash
21
+
22
+ # AMQP message attributes
19
23
  # @return [Hash]
20
- attr_reader :header
24
+ attr_reader :attributes
21
25
 
22
26
  # @api public
23
- def initialize(channel, method, header)
24
- @channel, @method, @header = channel, method, header
27
+ def initialize(channel, method, attributes)
28
+ @channel, @method, @attributes = channel, method, attributes
25
29
  end
26
30
 
27
31
  # Acknowledges the receipt of this message with the server.
@@ -41,18 +45,76 @@ module AMQP
41
45
  # @return [Hash] AMQP message header w/o method-specific information.
42
46
  # @api public
43
47
  def to_hash
44
- @header
48
+ @attributes
45
49
  end # to_hash
46
50
 
47
- def respond_to_missing?(meth, _)
48
- (@header && args.empty? && blk.nil? && @header.has_key?(meth)) || @method.respond_to?(meth)
49
- end
51
+ def delivery_tag
52
+ @method.delivery_tag
53
+ end # delivery_tag
54
+
55
+ def consumer_tag
56
+ @method.consumer_tag
57
+ end # consumer_tag
58
+
59
+ def redelivered
60
+ @method.redelivered
61
+ end # redelivered
62
+
63
+ def redelivered?
64
+ @method.redelivered
65
+ end # redelivered?
66
+
67
+ def exchange
68
+ @method.exchange
69
+ end # exchange
70
+
71
+ # @deprecated
72
+ def header
73
+ @attributes
74
+ end # header
75
+
76
+ def headers
77
+ @attributes[:headers]
78
+ end # headers
79
+
80
+ def delivery_mode
81
+ @attributes[:delivery_mode]
82
+ end # delivery_mode
83
+
84
+ def content_type
85
+ @attributes[:content_type]
86
+ end # content_type
87
+
88
+ def timestamp
89
+ @attributes[:timestamp]
90
+ end # timestamp
91
+
92
+ def type
93
+ @attributes[:type]
94
+ end # type
95
+
96
+ def priority
97
+ @attributes[:priority]
98
+ end # priority
99
+
100
+ def reply_to
101
+ @attributes[:reply_to]
102
+ end # reply_to
103
+
104
+ def correlation_id
105
+ @attributes[:correlation_id]
106
+ end # correlation_id
107
+
108
+ def message_id
109
+ @attributes[:message_id]
110
+ end # message_id
111
+
50
112
 
51
113
  # Returns AMQP message attributes.
52
114
  # @api public
53
115
  def method_missing(meth, *args, &blk)
54
- if @header && args.empty? && blk.nil? && @header.has_key?(meth)
55
- @header[meth]
116
+ if @attributes && args.empty? && blk.nil? && @attributes.has_key?(meth)
117
+ @attributes[meth]
56
118
  else
57
119
  @method.__send__(meth, *args, &blk)
58
120
  end