qpid_proton 0.9.0 → 0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codec/data.rb +912 -0
  3. data/lib/codec/mapping.rb +169 -0
  4. data/lib/{qpid_proton/tracker.rb → core/base_handler.rb} +4 -15
  5. data/lib/core/connection.rb +328 -0
  6. data/lib/core/delivery.rb +271 -0
  7. data/lib/core/disposition.rb +158 -0
  8. data/lib/core/endpoint.rb +140 -0
  9. data/lib/{qpid_proton → core}/exceptions.rb +43 -2
  10. data/lib/core/link.rb +387 -0
  11. data/lib/core/message.rb +633 -0
  12. data/lib/core/receiver.rb +95 -0
  13. data/lib/core/sasl.rb +94 -0
  14. data/lib/core/selectable.rb +130 -0
  15. data/lib/core/sender.rb +76 -0
  16. data/lib/core/session.rb +163 -0
  17. data/lib/core/ssl.rb +164 -0
  18. data/lib/{qpid_proton/version.rb → core/ssl_details.rb} +7 -6
  19. data/lib/core/ssl_domain.rb +156 -0
  20. data/lib/core/terminus.rb +218 -0
  21. data/lib/core/transport.rb +411 -0
  22. data/lib/core/url.rb +77 -0
  23. data/lib/event/collector.rb +148 -0
  24. data/lib/event/event.rb +318 -0
  25. data/lib/event/event_base.rb +91 -0
  26. data/lib/event/event_type.rb +71 -0
  27. data/lib/handler/acking.rb +70 -0
  28. data/lib/handler/c_adaptor.rb +47 -0
  29. data/lib/handler/c_flow_controller.rb +33 -0
  30. data/lib/handler/endpoint_state_handler.rb +217 -0
  31. data/lib/handler/incoming_message_handler.rb +74 -0
  32. data/lib/handler/messaging_handler.rb +218 -0
  33. data/lib/handler/outgoing_message_handler.rb +98 -0
  34. data/lib/handler/wrapped_handler.rb +76 -0
  35. data/lib/messenger/messenger.rb +702 -0
  36. data/lib/messenger/subscription.rb +37 -0
  37. data/lib/messenger/tracker.rb +38 -0
  38. data/lib/messenger/tracker_status.rb +69 -0
  39. data/lib/qpid_proton.rb +106 -16
  40. data/lib/reactor/acceptor.rb +41 -0
  41. data/lib/reactor/backoff.rb +41 -0
  42. data/lib/reactor/connector.rb +98 -0
  43. data/lib/reactor/container.rb +272 -0
  44. data/lib/reactor/global_overrides.rb +44 -0
  45. data/lib/reactor/link_option.rb +90 -0
  46. data/lib/reactor/reactor.rb +198 -0
  47. data/lib/reactor/session_per_connection.rb +45 -0
  48. data/lib/reactor/ssl_config.rb +41 -0
  49. data/lib/reactor/task.rb +39 -0
  50. data/lib/{qpid_proton/subscription.rb → reactor/urls.rb} +12 -13
  51. data/lib/{qpid_proton → types}/array.rb +28 -29
  52. data/lib/types/described.rb +63 -0
  53. data/lib/{qpid_proton → types}/hash.rb +4 -3
  54. data/lib/types/strings.rb +62 -0
  55. data/lib/util/class_wrapper.rb +54 -0
  56. data/lib/util/condition.rb +45 -0
  57. data/lib/util/constants.rb +85 -0
  58. data/lib/util/engine.rb +82 -0
  59. data/lib/util/error_handler.rb +127 -0
  60. data/lib/util/handler.rb +41 -0
  61. data/lib/util/reactor.rb +32 -0
  62. data/lib/util/swig_helper.rb +114 -0
  63. data/lib/util/timeout.rb +50 -0
  64. data/lib/util/uuid.rb +32 -0
  65. data/lib/util/version.rb +30 -0
  66. data/lib/util/wrapper.rb +124 -0
  67. metadata +67 -21
  68. data/ext/cproton/cproton.c +0 -22196
  69. data/lib/qpid_proton/data.rb +0 -788
  70. data/lib/qpid_proton/described.rb +0 -66
  71. data/lib/qpid_proton/exception_handling.rb +0 -127
  72. data/lib/qpid_proton/filters.rb +0 -67
  73. data/lib/qpid_proton/mapping.rb +0 -170
  74. data/lib/qpid_proton/message.rb +0 -621
  75. data/lib/qpid_proton/messenger.rb +0 -702
  76. data/lib/qpid_proton/selectable.rb +0 -126
  77. data/lib/qpid_proton/strings.rb +0 -65
  78. data/lib/qpid_proton/tracker_status.rb +0 -73
@@ -17,9 +17,9 @@
17
17
  # under the License.
18
18
  #++
19
19
 
20
- module Qpid # :nodoc:
20
+ module Qpid
21
21
 
22
- module Proton # :nodoc:
22
+ module Proton
23
23
 
24
24
  module Error
25
25
 
@@ -80,6 +80,47 @@ module Qpid # :nodoc:
80
80
  class InProgressError < ProtonError
81
81
  end
82
82
 
83
+ # Raised by instances of Transport.
84
+ #
85
+ class TransportError < ProtonError
86
+ end
87
+
88
+ # Raised by instances of SASL
89
+ #
90
+ class SASLError < TransportError
91
+ end
92
+
93
+ # Raised by Session.
94
+ #
95
+ class SessionError < ProtonError
96
+ end
97
+
98
+ # Raised when an attempt is made to change an attribute that is read-only.
99
+ #
100
+ class AttributeError < ProtonError
101
+ end
102
+
103
+ # Raised by link components.
104
+ #
105
+ class LinkError < ProtonError
106
+ end
107
+
108
+ class SSLError < TransportError
109
+ end
110
+
111
+ class SSLUnavailableError < SSLError
112
+ end
113
+
114
+ # Raised when a message is rejected.
115
+ #
116
+ class Reject < ProtonError
117
+ end
118
+
119
+ # Raised when a message is released.
120
+ #
121
+ class Release < ProtonError
122
+ end
123
+
83
124
  end
84
125
 
85
126
  end
data/lib/core/link.rb ADDED
@@ -0,0 +1,387 @@
1
+ #--
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #++
19
+
20
+ module Qpid::Proton
21
+
22
+ # The base for both Sender and Receiver, providing common functionality
23
+ # between both ends.
24
+ #
25
+ # A Link has a single parent Qpid::Proton::Session instance.
26
+ #
27
+ class Link < Endpoint
28
+
29
+ # The sender will send all deliveries initially unsettled.
30
+ SND_UNSETTLED = Cproton::PN_SND_UNSETTLED
31
+ # The sender will send all deliveries settled to the receiver.
32
+ SND_SETTLED = Cproton::PN_SND_SETTLED
33
+ # The sender may send a mixture of settled and unsettled deliveries.
34
+ SND_MIXED = Cproton::PN_SND_MIXED
35
+
36
+ # The receiver will settle deliveries regardless of what the sender does.
37
+ RCV_FIRST = Cproton::PN_RCV_FIRST
38
+ # The receiver will only settle deliveries after the sender settles.
39
+ RCV_SECOND = Cproton::PN_RCV_SECOND
40
+
41
+ # @private
42
+ include Util::SwigHelper
43
+
44
+ # @private
45
+ PROTON_METHOD_PREFIX = "pn_link"
46
+
47
+ # @!attribute [r] state
48
+ #
49
+ # Returns the endpoint state flags.
50
+ #
51
+ proton_caller :state
52
+
53
+ # @!method open
54
+ #
55
+ # Opens the link. Once this operation has completed, the state flag will be
56
+ # set.
57
+ #
58
+ # @see Endpoint::LOCAL_ACTIVE
59
+ proton_caller :open
60
+
61
+ # @!method close
62
+ #
63
+ # Closes the link.
64
+ #
65
+ # Once this operation has completed, the state flag will be set.
66
+ # This may be called without first calling #open, which is the equivalent to
67
+ # calling #open and then #close.
68
+ #
69
+ # @see Endpoint::LOCAL_CLOSED
70
+ proton_caller :close
71
+
72
+ # @!method detach
73
+ #
74
+ # Detaches the link.
75
+ proton_caller :detach
76
+
77
+ # Advance the current delivery to the next on the link.
78
+ #
79
+ # For sending links, this operation is used to finish sending message data
80
+ # for the current outgoing delivery and move on to the next outgoing
81
+ # delivery (if any).
82
+ #
83
+ # For receiving links, this operatoin is used to finish accessing message
84
+ # data from the current incoming delivery and move on to the next incoming
85
+ # delivery (if any).
86
+ #
87
+ # @return [Boolean] True if the current delivery was changed.
88
+ #
89
+ # @see #current
90
+ #
91
+ proton_caller :advance
92
+
93
+ proton_caller :unsettled
94
+
95
+ # @!attribute [r] credit
96
+ #
97
+ # Returns the credit balance for a link.
98
+ #
99
+ # Links use a credit based flow control scheme. Every receiver maintains a
100
+ # credit balance that corresponds to the number of deliveries that the
101
+ # receiver can accept at any given moment.
102
+ #
103
+ # As more capacity becomes available at the receiver, it adds credit to this
104
+ # balance and communicates the new balance to the sender. Whenever a
105
+ # delivery is sent/received, the credit balance maintained by the link is
106
+ # decremented by one.
107
+ #
108
+ # Once the credit balance at the sender reaches zero, the sender must pause
109
+ # sending until more credit is obtained from the receiver.
110
+ #
111
+ # NOte that a sending link may still be used to send deliveries eve if
112
+ # credit reaches zero. However those deliveries will end up being buffer by
113
+ # the link until enough credit is obtained from the receiver to send them
114
+ # over the wire. In this case the balance reported will go negative.
115
+ #
116
+ # @return [Fixnum] The credit balance.
117
+ #
118
+ # @see #flow
119
+ #
120
+ proton_caller :credit
121
+
122
+ # @!attribute [r] remote_credit
123
+ #
124
+ # Returns the remote view of the credit.
125
+ #
126
+ # The remote view of the credit for a link differs from the local view of
127
+ # credit for a link by the number of queued deliveries. In other words,
128
+ # remote credit is defined as credit - queued.
129
+ #
130
+ # @see #queued
131
+ # @see #credit
132
+ #
133
+ # @return [Fixnum] The remove view of the credit.
134
+ #
135
+ proton_caller :remote_credit
136
+
137
+ # @!attribute [r] available
138
+ #
139
+ # Returns the available deliveries hint for a link.
140
+ #
141
+ # The available count for a link provides a hint as to the number of
142
+ # deliveries that might be able to be sent if sufficient credit were issued
143
+ # by the receiving link endpoint.
144
+ #
145
+ # @return [Fixnum] The available deliveries hint.
146
+ #
147
+ # @see Sender#offered
148
+ #
149
+ proton_caller :available
150
+
151
+ # @!attribute [r] queued
152
+ #
153
+ # Returns the number of queued deliveries for a link.
154
+ #
155
+ # Links may queue deliveries for a number of reasons. For example, there may
156
+ # be insufficient credit to send them to the receiver, or they simply may
157
+ # not have yet had a chance to be written to the wire.
158
+ #
159
+ # @return [Fixnum] The number of queued deliveries.
160
+ #
161
+ # @see #credit
162
+ #
163
+ proton_caller :queued
164
+
165
+ # @!attribute [r] name
166
+ #
167
+ # Returns the name of the link.
168
+ #
169
+ # @return [String] The name.
170
+ #
171
+ proton_caller :name
172
+
173
+ # @!attribute [r] sender?
174
+ #
175
+ # Returns if the link is a sender.
176
+ #
177
+ # @return [Boolean] True if the link is a sender.
178
+ #
179
+ proton_reader :sender, :is_or_get => :is
180
+
181
+ # @!attribute [r] receiver?
182
+ #
183
+ # Returns if the link is a receiver.
184
+ #
185
+ # @return [Boolean] True if the link is a receiver.
186
+ #
187
+ proton_reader :receiver, :is_or_get => :is
188
+
189
+ # @private
190
+ proton_reader :attachments
191
+
192
+ # Drains excess credit.
193
+ #
194
+ # When a link is in drain mode, the sender must use all excess credit
195
+ # immediately and release any excess credit back to the receiver if there
196
+ # are no deliveries available to send.
197
+ #
198
+ # When invoked on a Sender that is in drain mode, this operation will
199
+ # release all excess credit back to the receiver and return the number of
200
+ # credits released back to the sender. If the link is not in drain mode,
201
+ # this operation is a noop.
202
+ #
203
+ # When invoked on a Receiver, this operation will return and reset the
204
+ # number of credits the sender has released back to it.
205
+ #
206
+ # @return [Fixnum] The number of credits drained.
207
+ #
208
+ proton_caller :drained
209
+
210
+ # @private
211
+ include Util::Wrapper
212
+
213
+ # @private
214
+ def self.wrap(impl)
215
+ return nil if impl.nil?
216
+
217
+ result = self.fetch_instance(impl, :pn_link_attachments)
218
+ return result unless result.nil?
219
+ if Cproton.pn_link_is_sender(impl)
220
+ return Sender.new(impl)
221
+ elsif Cproton.pn_link_is_receiver(impl)
222
+ return Receiver.new(impl)
223
+ end
224
+ end
225
+
226
+ # @private
227
+ def initialize(impl)
228
+ @impl = impl
229
+ self.class.store_instance(self, :pn_link_attachments)
230
+ end
231
+
232
+ # Returns additional error information.
233
+ #
234
+ # Whenever a link operation fails (i.e., returns an error code) additional
235
+ # error details can be obtained from this method. Ther error object that is
236
+ # returned may also be used to clear the error condition.
237
+ #
238
+ # @return [Error] The error.
239
+ #
240
+ def error
241
+ Cproton.pn_link_error(@impl)
242
+ end
243
+
244
+ # Returns the next link that matches the given state mask.
245
+ #
246
+ # @param state_mask [Fixnum] The state mask.
247
+ #
248
+ # @return [Sender, Receiver] The next link.
249
+ #
250
+ def next(state_mask)
251
+ return Link.wrap(Cproton.pn_link_next(@impl, state_mask))
252
+ end
253
+
254
+ # Returns the locally defined source terminus.
255
+ #
256
+ # @return [Terminus] The terminus
257
+ def source
258
+ Terminus.new(Cproton.pn_link_source(@impl))
259
+ end
260
+
261
+ # Returns the locally defined target terminus.
262
+ #
263
+ # @return [Terminus] The terminus.
264
+ #
265
+ def target
266
+ Terminus.new(Cproton.pn_link_target(@impl))
267
+ end
268
+
269
+ # Returns a representation of the remotely defined source terminus.
270
+ #
271
+ # @return [Terminus] The terminus.
272
+ #
273
+ def remote_source
274
+ Terminus.new(Cproton.pn_link_remote_source(@impl))
275
+ end
276
+
277
+ # Returns a representation of the remotely defined target terminus.
278
+ #
279
+ # @return [Terminus] The terminus.
280
+ #
281
+ def remote_target
282
+ Terminus.new(Cproton.pn_link_remote_target(@impl))
283
+ end
284
+
285
+ # Returns the parent session.
286
+ #
287
+ # @return [Session] The session.
288
+ #
289
+ def session
290
+ Session.wrap(Cproton.pn_link_session(@impl))
291
+ end
292
+
293
+ # Returns the parent connection.
294
+ #
295
+ # @return [Connection] The connection.
296
+ #
297
+ def connection
298
+ self.session.connection
299
+ end
300
+
301
+ # Returns the parent delivery.
302
+ #
303
+ # @return [Delivery] The delivery.
304
+ #
305
+ def delivery(tag)
306
+ Delivery.new(Cproton.pn_delivery(@impl, tag))
307
+ end
308
+
309
+ # Returns the current delivery.
310
+ #
311
+ # Each link maintains a sequence of deliveries in the order they were
312
+ # created, along with a reference to the *current* delivery. All send and
313
+ # receive operations on a link take place on the *current* delivery. If a
314
+ # link has no current delivery, the current delivery is automatically
315
+ # pointed to the *next* delivery created on the link.
316
+ #
317
+ # Once initialized, the current delivery remains the same until it is
318
+ # changed by advancing, or until it is settled.
319
+ #
320
+ # @see #next
321
+ # @see Delivery#settle
322
+ #
323
+ # @return [Delivery] The current delivery.
324
+ #
325
+ def current
326
+ Delivery.wrap(Cproton.pn_link_current(@impl))
327
+ end
328
+
329
+ # Sets the local sender settle mode.
330
+ #
331
+ # @param mode [Fixnum] The settle mode.
332
+ #
333
+ # @see #SND_UNSETTLED
334
+ # @see #SND_SETTLED
335
+ # @see #SND_MIXED
336
+ #
337
+ def snd_settle_mode=(mode)
338
+ Cproton.pn_link_set_snd_settle_mode(@impl, mode)
339
+ end
340
+
341
+ # Returns the local sender settle mode.
342
+ #
343
+ # @return [Fixnum] The local sender settle mode.
344
+ #
345
+ # @see #snd_settle_mode
346
+ #
347
+ def snd_settle_mode
348
+ Cproton.pn_link_snd_settle_mode(@impl)
349
+ end
350
+
351
+ # Sets the local receiver settle mode.
352
+ #
353
+ # @param mode [Fixnum] The settle mode.
354
+ #
355
+ # @see #RCV_FIRST
356
+ # @see #RCV_SECOND
357
+ #
358
+ def rcv_settle_mode=(mode)
359
+ Cproton.pn_link_set_rcv_settle_mode(@impl, mode)
360
+ end
361
+
362
+ # Returns the local receiver settle mode.
363
+ #
364
+ # @return [Fixnum] The local receiver settle mode.
365
+ #
366
+ def rcv_settle_mode
367
+ Cproton.pn_link_rcv_settle_mode(@impl)
368
+ end
369
+
370
+ # @private
371
+ def _local_condition
372
+ Cproton.pn_link_condition(@impl)
373
+ end
374
+
375
+ # @private
376
+ def _remote_condition
377
+ Cproton.pn_link_remote_condition(@impl)
378
+ end
379
+
380
+ def ==(other)
381
+ other.respond_to?(:impl) &&
382
+ (Cproton.pni_address_of(other.impl) == Cproton.pni_address_of(@impl))
383
+ end
384
+
385
+ end
386
+
387
+ end
@@ -0,0 +1,633 @@
1
+ #--
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #++
19
+
20
+ module Qpid::Proton
21
+
22
+ # A Message represents an addressable quantity of data.
23
+ #
24
+ # ==== Message Body
25
+ #
26
+ # The message body can be set using the #body= method. The message will
27
+ # then attempt to determine how exactly to encode the content.
28
+ #
29
+ # ==== Examples
30
+ #
31
+ # To create a message for sending:
32
+ #
33
+ # # send a simple text message
34
+ # msg = Qpid::Proton::Message.new
35
+ # msg.body = "STATE: update"
36
+ #
37
+ # # send a binary chunk of data
38
+ # data = File.binread("/home/qpid/binfile.tar.gz")
39
+ # msg = Qpid::Proton::Message.new
40
+ # msg.body = Qpid::Proton::BinaryString.new(data)
41
+ #
42
+ class Message
43
+
44
+ # @private
45
+ def proton_send(sender, tag = nil)
46
+ dlv = sender.delivery(tag || sender.delivery_tag)
47
+ encoded = self.encode
48
+ sender.stream(encoded)
49
+ sender.advance
50
+ dlv.settle if sender.snd_settle_mode == Link::SND_SETTLED
51
+ return dlv
52
+ end
53
+
54
+ # Decodes a message from supplied AMQP data and returns the number
55
+ # of bytes consumed.
56
+ #
57
+ # ==== Options
58
+ #
59
+ # * encoded - the encoded data
60
+ #
61
+ def decode(encoded)
62
+ check(Cproton.pn_message_decode(@impl, encoded, encoded.length))
63
+
64
+ post_decode
65
+ end
66
+
67
+ def post_decode # :nodoc:
68
+ # decode elements from the message
69
+ @properties = {}
70
+ props = Codec::Data.new(Cproton::pn_message_properties(@impl))
71
+ if props.next
72
+ @properties = props.type.get(props)
73
+ end
74
+ @instructions = nil
75
+ insts = Codec::Data.new(Cproton::pn_message_instructions(@impl))
76
+ if insts.next
77
+ @instructions = insts.type.get(insts)
78
+ end
79
+ @annotations = nil
80
+ annts = Codec::Data.new(Cproton::pn_message_annotations(@impl))
81
+ if annts.next
82
+ @annotations = annts.type.get(annts)
83
+ end
84
+ @body = nil
85
+ body = Codec::Data.new(Cproton::pn_message_body(@impl))
86
+ if body.next
87
+ @body = body.type.get(body)
88
+ end
89
+ end
90
+
91
+ # Encodes the message.
92
+ def encode
93
+ pre_encode
94
+ size = 16
95
+ loop do
96
+ error, data = Cproton::pn_message_encode(@impl, size)
97
+ if error == Qpid::Proton::Error::OVERFLOW
98
+ size *= 2
99
+ else
100
+ check(error)
101
+ return data
102
+ end
103
+ end
104
+ end
105
+
106
+ def pre_encode # :nodoc:
107
+ # encode elements from the message
108
+ props = Codec::Data.new(Cproton::pn_message_properties(@impl))
109
+ props.clear
110
+ Codec::Mapping.for_class(@properties.class).put(props, @properties) unless @properties.empty?
111
+ insts = Codec::Data.new(Cproton::pn_message_instructions(@impl))
112
+ insts.clear
113
+ if !@instructions.nil?
114
+ mapping = Codec::Mapping.for_class(@instructions.class)
115
+ mapping.put(insts, @instructions)
116
+ end
117
+ annts = Codec::Data.new(Cproton::pn_message_annotations(@impl))
118
+ annts.clear
119
+ if !@annotations.nil?
120
+ mapping = Codec::Mapping.for_class(@annotations.class)
121
+ mapping.put(annts, @annotations, :keys => :SYMBOL)
122
+ end
123
+ body = Codec::Data.new(Cproton::pn_message_body(@impl))
124
+ body.clear
125
+ if !@body.nil?
126
+ mapping = Codec::Mapping.for_class(@body.class)
127
+ mapping.put(body, @body)
128
+ end
129
+ end
130
+
131
+ # Creates a new +Message+ instance.
132
+ def initialize
133
+ @impl = Cproton.pn_message
134
+ ObjectSpace.define_finalizer(self, self.class.finalize!(@impl))
135
+ @properties = {}
136
+ @instructions = {}
137
+ @annotations = {}
138
+ @body = nil
139
+ end
140
+
141
+ def to_s
142
+ tmp = Cproton.pn_string("")
143
+ Cproton.pn_inspect(@impl, tmp)
144
+ result = Cproton.pn_string_get(tmp)
145
+ Cproton.pn_free(tmp)
146
+ return result
147
+ end
148
+
149
+ # Invoked by garbage collection to clean up resources used
150
+ # by the underlying message implementation.
151
+ def self.finalize!(impl) # :nodoc:
152
+ proc {
153
+ Cproton.pn_message_free(impl)
154
+ }
155
+ end
156
+
157
+ # Returns the underlying message implementation.
158
+ def impl # :nodoc:
159
+ @impl
160
+ end
161
+
162
+ # Clears the state of the +Message+. This allows a single instance of
163
+ # +Message+ to be reused.
164
+ #
165
+ def clear
166
+ Cproton.pn_message_clear(@impl)
167
+ @properties.clear unless @properties.nil?
168
+ @instructions.clear unless @instructions.nil?
169
+ @annotations.clear unless @annotations.nil?
170
+ @body = nil
171
+ end
172
+
173
+ # Returns the most recent error number.
174
+ #
175
+ def errno
176
+ Cproton.pn_message_errno(@impl)
177
+ end
178
+
179
+ # Returns the most recent error message.
180
+ #
181
+ def error
182
+ Cproton.pn_error_text(Cproton.pn_message_error(@impl))
183
+ end
184
+
185
+ # Returns whether there is currently an error reported.
186
+ #
187
+ def error?
188
+ !Cproton.pn_message_errno(@impl).zero?
189
+ end
190
+
191
+ # Sets the durable flag.
192
+ #
193
+ # See ::durable for more details on message durability.
194
+ #
195
+ # ==== Options
196
+ #
197
+ # * state - the durable state
198
+ #
199
+ def durable=(state)
200
+ raise TypeError.new("state cannot be nil") if state.nil?
201
+ Cproton.pn_message_set_durable(@impl, state)
202
+ end
203
+
204
+ # Returns the durable property.
205
+ #
206
+ # The durable property indicates that the emessage should be held durably
207
+ # by any intermediaries taking responsibility for the message.
208
+ #
209
+ # ==== Examples
210
+ #
211
+ # msg = Qpid::Proton::Message.new
212
+ # msg.durable = true
213
+ #
214
+ def durable
215
+ Cproton.pn_message_is_durable(@impl)
216
+ end
217
+
218
+ # Sets the priority.
219
+ #
220
+ # +NOTE:+ Priority values are limited to the range [0,255].
221
+ #
222
+ # ==== Options
223
+ #
224
+ # * priority - the priority value
225
+ #
226
+ def priority=(priority)
227
+ raise TypeError.new("invalid priority: #{priority}") if priority.nil? || !([Float, Fixnum].include?(priority.class))
228
+ raise RangeError.new("priority out of range: #{priority}") if ((priority > 255) || (priority < 0))
229
+ Cproton.pn_message_set_priority(@impl, priority.floor)
230
+ end
231
+
232
+ # Returns the priority.
233
+ #
234
+ def priority
235
+ Cproton.pn_message_get_priority(@impl)
236
+ end
237
+
238
+ # Sets the time-to-live for the message.
239
+ #
240
+ # ==== Options
241
+ #
242
+ # * time - the time in milliseconds
243
+ #
244
+ def ttl=(time)
245
+ raise TypeError.new("invalid ttl: #{time}") if time.nil? || !([Float, Fixnum].include?(time.class))
246
+ raise RangeError.new("time out of range: #{time}") if ((time < 0))
247
+ Cproton.pn_message_set_ttl(@impl, time.floor)
248
+ end
249
+
250
+ # Returns the time-to-live, in milliseconds.
251
+ #
252
+ def ttl
253
+ Cproton.pn_message_get_ttl(@impl)
254
+ end
255
+
256
+ # Sets whether this is the first time the message was acquired.
257
+ #
258
+ # See ::first_acquirer? for more details.
259
+ #
260
+ # ==== Options
261
+ #
262
+ # * state - true if claiming the message
263
+ #
264
+ def first_acquirer=(state)
265
+ raise TypeError.new("invalid state: #{state}") if state.nil? || !([TrueClass, FalseClass].include?(state.class))
266
+ Cproton.pn_message_set_first_acquirer(@impl, state)
267
+ end
268
+
269
+ # Sets the delivery count for the message.
270
+ #
271
+ # See ::delivery_count for more details.
272
+ #
273
+ # ==== Options
274
+ #
275
+ # * count - the delivery count
276
+ #
277
+ def delivery_count=(count)
278
+ raise ::ArgumentError.new("invalid count: #{count}") if count.nil? || !([Float, Fixnum].include?(count.class))
279
+ raise RangeError.new("count out of range: #{count}") if count < 0
280
+
281
+ Cproton.pn_message_set_delivery_count(@impl, count.floor)
282
+ end
283
+
284
+ # Returns the delivery count for the message.
285
+ #
286
+ # This is the number of delivery attempts for the given message.
287
+ #
288
+ def delivery_count
289
+ Cproton.pn_message_get_delivery_count(@impl)
290
+ end
291
+
292
+ # Returns whether this is the first acquirer.
293
+ #
294
+ #
295
+ def first_acquirer?
296
+ Cproton.pn_message_is_first_acquirer(@impl)
297
+ end
298
+
299
+ # Sets the message id.
300
+ #
301
+ # ==== Options
302
+ #
303
+ # * id = the id
304
+ #
305
+ def id=(id)
306
+ Cproton.pn_message_set_id(@impl, id)
307
+ end
308
+
309
+ # Returns the message id.
310
+ #
311
+ def id
312
+ Cproton.pn_message_get_id(@impl)
313
+ end
314
+
315
+ # Sets the user id.
316
+ #
317
+ # ==== Options
318
+ #
319
+ # * id - the user id
320
+ #
321
+ def user_id=(id)
322
+ Cproton.pn_message_set_user_id(@impl, id)
323
+ end
324
+
325
+ # Returns the user id.
326
+ #
327
+ def user_id
328
+ Cproton.pn_message_get_user_id(@impl)
329
+ end
330
+
331
+ # Sets the destination address.
332
+ #
333
+ # ==== Options
334
+ #
335
+ # * address - the address
336
+ #
337
+ def address=(address)
338
+ Cproton.pn_message_set_address(@impl, address)
339
+ end
340
+
341
+ # Returns the destination address.
342
+ #
343
+ def address
344
+ Cproton.pn_message_get_address(@impl)
345
+ end
346
+
347
+ # Sets the subject.
348
+ #
349
+ # ==== Options
350
+ #
351
+ # * subject - the subject
352
+ #
353
+ def subject=(subject)
354
+ Cproton.pn_message_set_subject(@impl, subject)
355
+ end
356
+
357
+ # Returns the subject
358
+ #
359
+ def subject
360
+ Cproton.pn_message_get_subject(@impl)
361
+ end
362
+
363
+ # Sets the reply-to address.
364
+ #
365
+ # ==== Options
366
+ #
367
+ # * address - the reply-to address
368
+ #
369
+ def reply_to=(address)
370
+ Cproton.pn_message_set_reply_to(@impl, address)
371
+ end
372
+
373
+ # Returns the reply-to address
374
+ #
375
+ def reply_to
376
+ Cproton.pn_message_get_reply_to(@impl)
377
+ end
378
+
379
+ # Sets the correlation id.
380
+ #
381
+ # ==== Options
382
+ #
383
+ # * id - the correlation id
384
+ #
385
+ def correlation_id=(id)
386
+ Cproton.pn_message_set_correlation_id(@impl, id)
387
+ end
388
+
389
+ # Returns the correlation id.
390
+ #
391
+ def correlation_id
392
+ Cproton.pn_message_get_correlation_id(@impl)
393
+ end
394
+
395
+ # Sets the content type.
396
+ #
397
+ # ==== Options
398
+ #
399
+ # * content_type - the content type
400
+ #
401
+ def content_type=(content_type)
402
+ Cproton.pn_message_set_content_type(@impl, content_type)
403
+ end
404
+
405
+ # Returns the content type
406
+ #
407
+ def content_type
408
+ Cproton.pn_message_get_content_type(@impl)
409
+ end
410
+
411
+ # Sets the message content.
412
+ #
413
+ # *WARNING:* This method has been deprecated. Please use #body= instead to
414
+ # set the content of a message.
415
+ #
416
+ # ==== Options
417
+ #
418
+ # * content - the content
419
+ #
420
+ def content=(content)
421
+ Cproton.pn_message_load(@impl, content)
422
+ end
423
+
424
+ # Returns the message content.
425
+ #
426
+ # *WARNING:* This method has been deprecated. Please use #body instead to
427
+ # retrieve the content of a message.
428
+ #
429
+ def content
430
+ size = 16
431
+ loop do
432
+ result = Cproton.pn_message_save(@impl, size)
433
+ error = result[0]
434
+ data = result[1]
435
+ if error == Qpid::Proton::Error::OVERFLOW
436
+ size = size * 2
437
+ else
438
+ check(error)
439
+ return data
440
+ end
441
+ end
442
+ end
443
+
444
+ # Sets the content encoding type.
445
+ #
446
+ # ==== Options
447
+ #
448
+ # * encoding - the content encoding
449
+ #
450
+ def content_encoding=(encoding)
451
+ Cproton.pn_message_set_content_encoding(@impl, encoding)
452
+ end
453
+
454
+ # Returns the content encoding type.
455
+ #
456
+ def content_encoding
457
+ Cproton.pn_message_get_content_encoding(@impl)
458
+ end
459
+
460
+ # Sets the expiration time.
461
+ #
462
+ # ==== Options
463
+ #
464
+ # * time - the expiry time
465
+ #
466
+ def expires=(time)
467
+ raise TypeError.new("invalid expiry time: #{time}") if time.nil?
468
+ raise ::ArgumentError.new("expiry time cannot be negative: #{time}") if time < 0
469
+ Cproton.pn_message_set_expiry_time(@impl, time)
470
+ end
471
+
472
+ # Returns the expiration time.
473
+ #
474
+ def expires
475
+ Cproton.pn_message_get_expiry_time(@impl)
476
+ end
477
+
478
+ # Sets the creation time.
479
+ #
480
+ # ==== Options
481
+ #
482
+ # * time - the creation time
483
+ #
484
+ def creation_time=(time)
485
+ raise TypeError.new("invalid time: #{time}") if time.nil?
486
+ raise ::ArgumentError.new("time cannot be negative") if time < 0
487
+ Cproton.pn_message_set_creation_time(@impl, time)
488
+ end
489
+
490
+ # Returns the creation time.
491
+ #
492
+ def creation_time
493
+ Cproton.pn_message_get_creation_time(@impl)
494
+ end
495
+
496
+ # Sets the group id.
497
+ #
498
+ # ==== Options
499
+ #
500
+ # * id - the group id
501
+ #
502
+ def group_id=(id)
503
+ Cproton.pn_message_set_group_id(@impl, id)
504
+ end
505
+
506
+ # Returns the group id.
507
+ #
508
+ def group_id
509
+ Cproton.pn_message_get_group_id(@impl)
510
+ end
511
+
512
+ # Sets the group sequence number.
513
+ #
514
+ # ==== Options
515
+ #
516
+ # * seq - the sequence number
517
+ #
518
+ def group_sequence=(seq)
519
+ raise TypeError.new("invalid seq: #{seq}") if seq.nil?
520
+ Cproton.pn_message_set_group_sequence(@impl, seq)
521
+ end
522
+
523
+ # Returns the group sequence number.
524
+ #
525
+ def group_sequence
526
+ Cproton.pn_message_get_group_sequence(@impl)
527
+ end
528
+
529
+ # Sets the reply-to group id.
530
+ #
531
+ # ==== Options
532
+ #
533
+ # * id - the id
534
+ #
535
+ def reply_to_group_id=(id)
536
+ Cproton.pn_message_set_reply_to_group_id(@impl, id)
537
+ end
538
+
539
+ # Returns the reply-to group id.
540
+ #
541
+ def reply_to_group_id
542
+ Cproton.pn_message_get_reply_to_group_id(@impl)
543
+ end
544
+
545
+ # Returns the list of property names for associated with this message.
546
+ #
547
+ # ==== Examples
548
+ #
549
+ # msg.properties.each do |name|
550
+ # end
551
+ #
552
+ def properties
553
+ @properties
554
+ end
555
+
556
+ # Replaces the entire set of properties with the specified hash.
557
+ #
558
+ def properties=(properties)
559
+ @properties = properties
560
+ end
561
+
562
+ # Assigns the value given to the named property.
563
+ #
564
+ # ==== Arguments
565
+ #
566
+ # * name - the property name
567
+ # * value - the property value
568
+ #
569
+ def []=(name, value)
570
+ @properties[name] = value
571
+ end
572
+
573
+ # Retrieves the value for the specified property name. If not found, then
574
+ # it returns nil.
575
+ #
576
+ def [](name)
577
+ @properties[name]
578
+ end
579
+
580
+ # Deletes the named property.
581
+ #
582
+ def delete_property(name)
583
+ @properties.delete(name)
584
+ end
585
+
586
+ # Returns the instructions for this message.
587
+ #
588
+ def instructions
589
+ @instructions
590
+ end
591
+
592
+ # Assigns instructions to this message.
593
+ #
594
+ def instructions=(instr)
595
+ @instructions = instr
596
+ end
597
+
598
+ # Returns the annotations for this message.
599
+ #
600
+ def annotations
601
+ @annotations
602
+ end
603
+
604
+ # Assigns annotations to this message.
605
+ #
606
+ def annotations=(annotations)
607
+ @annotations = annotations
608
+ end
609
+
610
+ # Returns the body property of the message.
611
+ #
612
+ def body
613
+ @body
614
+ end
615
+
616
+ # Assigns a new value to the body of the message.
617
+ #
618
+ def body=(body)
619
+ @body = body
620
+ end
621
+
622
+ private
623
+
624
+ def check(err) # :nodoc:
625
+ if err < 0
626
+ raise DataError, "[#{err}]: #{Cproton.pn_message_error(@data)}"
627
+ else
628
+ return err
629
+ end
630
+ end
631
+ end
632
+
633
+ end