qpid_proton 0.9.0 → 0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/codec/data.rb +912 -0
- data/lib/codec/mapping.rb +169 -0
- data/lib/{qpid_proton/tracker.rb → core/base_handler.rb} +4 -15
- data/lib/core/connection.rb +328 -0
- data/lib/core/delivery.rb +271 -0
- data/lib/core/disposition.rb +158 -0
- data/lib/core/endpoint.rb +140 -0
- data/lib/{qpid_proton → core}/exceptions.rb +43 -2
- data/lib/core/link.rb +387 -0
- data/lib/core/message.rb +633 -0
- data/lib/core/receiver.rb +95 -0
- data/lib/core/sasl.rb +94 -0
- data/lib/core/selectable.rb +130 -0
- data/lib/core/sender.rb +76 -0
- data/lib/core/session.rb +163 -0
- data/lib/core/ssl.rb +164 -0
- data/lib/{qpid_proton/version.rb → core/ssl_details.rb} +7 -6
- data/lib/core/ssl_domain.rb +156 -0
- data/lib/core/terminus.rb +218 -0
- data/lib/core/transport.rb +411 -0
- data/lib/core/url.rb +77 -0
- data/lib/event/collector.rb +148 -0
- data/lib/event/event.rb +318 -0
- data/lib/event/event_base.rb +91 -0
- data/lib/event/event_type.rb +71 -0
- data/lib/handler/acking.rb +70 -0
- data/lib/handler/c_adaptor.rb +47 -0
- data/lib/handler/c_flow_controller.rb +33 -0
- data/lib/handler/endpoint_state_handler.rb +217 -0
- data/lib/handler/incoming_message_handler.rb +74 -0
- data/lib/handler/messaging_handler.rb +218 -0
- data/lib/handler/outgoing_message_handler.rb +98 -0
- data/lib/handler/wrapped_handler.rb +76 -0
- data/lib/messenger/messenger.rb +702 -0
- data/lib/messenger/subscription.rb +37 -0
- data/lib/messenger/tracker.rb +38 -0
- data/lib/messenger/tracker_status.rb +69 -0
- data/lib/qpid_proton.rb +106 -16
- data/lib/reactor/acceptor.rb +41 -0
- data/lib/reactor/backoff.rb +41 -0
- data/lib/reactor/connector.rb +98 -0
- data/lib/reactor/container.rb +272 -0
- data/lib/reactor/global_overrides.rb +44 -0
- data/lib/reactor/link_option.rb +90 -0
- data/lib/reactor/reactor.rb +198 -0
- data/lib/reactor/session_per_connection.rb +45 -0
- data/lib/reactor/ssl_config.rb +41 -0
- data/lib/reactor/task.rb +39 -0
- data/lib/{qpid_proton/subscription.rb → reactor/urls.rb} +12 -13
- data/lib/{qpid_proton → types}/array.rb +28 -29
- data/lib/types/described.rb +63 -0
- data/lib/{qpid_proton → types}/hash.rb +4 -3
- data/lib/types/strings.rb +62 -0
- data/lib/util/class_wrapper.rb +54 -0
- data/lib/util/condition.rb +45 -0
- data/lib/util/constants.rb +85 -0
- data/lib/util/engine.rb +82 -0
- data/lib/util/error_handler.rb +127 -0
- data/lib/util/handler.rb +41 -0
- data/lib/util/reactor.rb +32 -0
- data/lib/util/swig_helper.rb +114 -0
- data/lib/util/timeout.rb +50 -0
- data/lib/util/uuid.rb +32 -0
- data/lib/util/version.rb +30 -0
- data/lib/util/wrapper.rb +124 -0
- metadata +67 -21
- data/ext/cproton/cproton.c +0 -22196
- data/lib/qpid_proton/data.rb +0 -788
- data/lib/qpid_proton/described.rb +0 -66
- data/lib/qpid_proton/exception_handling.rb +0 -127
- data/lib/qpid_proton/filters.rb +0 -67
- data/lib/qpid_proton/mapping.rb +0 -170
- data/lib/qpid_proton/message.rb +0 -621
- data/lib/qpid_proton/messenger.rb +0 -702
- data/lib/qpid_proton/selectable.rb +0 -126
- data/lib/qpid_proton/strings.rb +0 -65
- 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
|
20
|
+
module Qpid
|
21
21
|
|
22
|
-
module Proton
|
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
|
data/lib/core/message.rb
ADDED
@@ -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
|