qpid_proton 0.9.0 → 0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -0,0 +1,702 @@
|
|
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::Messenger
|
21
|
+
|
22
|
+
# The +Messenger+ class defines a high level interface for
|
23
|
+
# sending and receiving Messages. Every Messenger contains
|
24
|
+
# a single logical queue of incoming messages and a single
|
25
|
+
# logical queue of outgoing messages. These messages in these
|
26
|
+
# queues may be destined for, or originate from, a variety of
|
27
|
+
# addresses.
|
28
|
+
#
|
29
|
+
# The messenger interface is single-threaded. All methods
|
30
|
+
# except one ( #interrupt ) are intended to be used from within
|
31
|
+
# the messenger thread.
|
32
|
+
#
|
33
|
+
# === Sending & Receiving Messages
|
34
|
+
#
|
35
|
+
# The Messenger class works in conjuction with the Message class. The
|
36
|
+
# Message class is a mutable holder of message content.
|
37
|
+
#
|
38
|
+
# The put method copies its Message to the outgoing queue, and may
|
39
|
+
# send queued messages if it can do so without blocking. The send
|
40
|
+
# method blocks until it has sent the requested number of messages,
|
41
|
+
# or until a timeout interrupts the attempt.
|
42
|
+
#
|
43
|
+
# Similarly, the recv method receives messages into the incoming
|
44
|
+
# queue, and may block as it attempts to receive the requested number
|
45
|
+
# of messages, or until timeout is reached. It may receive fewer
|
46
|
+
# than the requested number. The get method pops the
|
47
|
+
# eldest Message off the incoming queue and copies it into the Message
|
48
|
+
# object that you supply. It will not block.
|
49
|
+
#
|
50
|
+
# The blocking attribute allows you to turn off blocking behavior entirely,
|
51
|
+
# in which case send and recv will do whatever they can without
|
52
|
+
# blocking, and then return. You can then look at the number
|
53
|
+
# of incoming and outgoing messages to see how much outstanding work
|
54
|
+
# still remains.
|
55
|
+
#
|
56
|
+
class Messenger
|
57
|
+
|
58
|
+
include Qpid::Proton::Util::ErrorHandler
|
59
|
+
|
60
|
+
can_raise_error [:send, :receive, :password=, :start, :stop,
|
61
|
+
:perform_put, :perform_get, :interrupt,
|
62
|
+
:route, :rewrite, :accept, :reject,
|
63
|
+
:incoming_window=, :outgoing_window=]
|
64
|
+
|
65
|
+
# Creates a new +Messenger+.
|
66
|
+
#
|
67
|
+
# The +name+ parameter is optional. If one is not provided then
|
68
|
+
# a unique name is generated.
|
69
|
+
#
|
70
|
+
# ==== Options
|
71
|
+
#
|
72
|
+
# * name - the name (def. nil)
|
73
|
+
#
|
74
|
+
def initialize(name = nil)
|
75
|
+
@impl = Cproton.pn_messenger(name)
|
76
|
+
@selectables = {}
|
77
|
+
ObjectSpace.define_finalizer(self, self.class.finalize!(@impl))
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.finalize!(impl) # :nodoc:
|
81
|
+
proc {
|
82
|
+
Cproton.pn_messenger_free(impl)
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns the name.
|
87
|
+
#
|
88
|
+
def name
|
89
|
+
Cproton.pn_messenger_name(@impl)
|
90
|
+
end
|
91
|
+
|
92
|
+
# This property contains the password for the Messenger.private_key
|
93
|
+
# file, or +nil+ if the file is not encrypted.
|
94
|
+
#
|
95
|
+
# ==== Arguments
|
96
|
+
#
|
97
|
+
# * password - the password
|
98
|
+
#
|
99
|
+
def password=(password)
|
100
|
+
Cproton.pn_messenger_set_password(@impl, password)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns the password property for the Messenger.private_key file.
|
104
|
+
#
|
105
|
+
def password
|
106
|
+
Cproton.pn_messenger_get_password(@impl)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Sets the timeout period, in milliseconds.
|
110
|
+
#
|
111
|
+
# A negative timeout period implies an infinite timeout.
|
112
|
+
#
|
113
|
+
# ==== Options
|
114
|
+
#
|
115
|
+
# * timeout - the timeout period
|
116
|
+
#
|
117
|
+
def timeout=(timeout)
|
118
|
+
raise TypeError.new("invalid timeout: #{timeout}") if timeout.nil?
|
119
|
+
Cproton.pn_messenger_set_timeout(@impl, timeout)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns the timeout period
|
123
|
+
#
|
124
|
+
def timeout
|
125
|
+
Cproton.pn_messenger_get_timeout(@impl)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Returns true if blocking mode is enabled.
|
129
|
+
#
|
130
|
+
# Enable or disable blocking behavior during message sending
|
131
|
+
# and receiving. This affects every blocking call, with the
|
132
|
+
# exception of work(). Currently, the affected calls are
|
133
|
+
# send, recv, and stop.
|
134
|
+
def blocking?
|
135
|
+
Cproton.pn_messenger_is_blocking(@impl)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Sets the blocking mode.
|
139
|
+
def blocking=(blocking)
|
140
|
+
Cproton.pn_messenger_set_blocking(@impl, blocking)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Returns true if passive mode is enabled.
|
144
|
+
#
|
145
|
+
def passive?
|
146
|
+
Cproton.pn_messenger_is_passive(@impl)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Turns passive mode on or off.
|
150
|
+
#
|
151
|
+
# When set to passive mode, Messenger will not attempt to perform I/O
|
152
|
+
# operations internally. In this mode it is necesssary to use the
|
153
|
+
# Selectable type to drive any I/O needed to perform requestioned
|
154
|
+
# actions.
|
155
|
+
#
|
156
|
+
# In this mode Messenger will never block.
|
157
|
+
#
|
158
|
+
def passive=(mode)
|
159
|
+
Cproton.pn_messenger_set_passive(@impl, mode)
|
160
|
+
end
|
161
|
+
|
162
|
+
def deadline
|
163
|
+
tstamp = Cproton.pn_messenger_deadline(@impl)
|
164
|
+
return tstamp / 1000.0 unless tstamp.nil?
|
165
|
+
end
|
166
|
+
|
167
|
+
# Reports whether an error occurred.
|
168
|
+
#
|
169
|
+
def error?
|
170
|
+
!Cproton.pn_messenger_errno(@impl).zero?
|
171
|
+
end
|
172
|
+
|
173
|
+
# Returns the most recent error number.
|
174
|
+
#
|
175
|
+
def errno
|
176
|
+
Cproton.pn_messenger_errno(@impl)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Returns the most recent error message.
|
180
|
+
#
|
181
|
+
def error
|
182
|
+
Cproton.pn_error_text(Cproton.pn_messenger_error(@impl))
|
183
|
+
end
|
184
|
+
|
185
|
+
# Clears the current error state.
|
186
|
+
#
|
187
|
+
def clear_error
|
188
|
+
error = Cproton.pn_messenger_error(@impl)
|
189
|
+
unless error.nil?
|
190
|
+
Cproton.pn_error_clear(error)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# Currently a no-op placeholder.
|
195
|
+
# For future compatibility, do not send or recv messages
|
196
|
+
# before starting the +Messenger+.
|
197
|
+
#
|
198
|
+
def start
|
199
|
+
Cproton.pn_messenger_start(@impl)
|
200
|
+
end
|
201
|
+
|
202
|
+
# Stops the +Messenger+, preventing it from sending or receiving
|
203
|
+
# any more messages.
|
204
|
+
#
|
205
|
+
def stop
|
206
|
+
Cproton.pn_messenger_stop(@impl)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Returns true if a Messenger is in the stopped state.
|
210
|
+
# This function does not block.
|
211
|
+
#
|
212
|
+
def stopped?
|
213
|
+
Cproton.pn_messenger_stopped(@impl)
|
214
|
+
end
|
215
|
+
|
216
|
+
# Subscribes the Messenger to messages originating from the
|
217
|
+
# specified source. The source is an address as specified in the
|
218
|
+
# Messenger introduction with the following addition. If the
|
219
|
+
# domain portion of the address begins with the '~' character, the
|
220
|
+
# Messenger will interpret the domain as host/port, bind to it,
|
221
|
+
# and listen for incoming messages. For example "~0.0.0.0",
|
222
|
+
# "amqp://~0.0.0.0" will all bind to any local interface and
|
223
|
+
# listen for incoming messages. An address of "amqps://~0.0.0.0"
|
224
|
+
# will only permit incoming SSL connections.
|
225
|
+
#
|
226
|
+
# ==== Options
|
227
|
+
#
|
228
|
+
# * address - the source address to be subscribe
|
229
|
+
# * timeout - an optional time-to-live value, in seconds, for the
|
230
|
+
# subscription
|
231
|
+
#
|
232
|
+
def subscribe(address, timeout=0)
|
233
|
+
raise TypeError.new("invalid address: #{address}") if address.nil?
|
234
|
+
subscription = Cproton.pn_messenger_subscribe_ttl(@impl, address, timeout)
|
235
|
+
raise Qpid::Proton::ProtonError.new("Subscribe failed") if subscription.nil?
|
236
|
+
Subscription.new(subscription)
|
237
|
+
end
|
238
|
+
|
239
|
+
# Path to a certificate file for the +Messenger+.
|
240
|
+
#
|
241
|
+
# This certificate is used when the +Messenger+ accepts or establishes
|
242
|
+
# SSL/TLS connections. This property must be specified for the
|
243
|
+
# Messenger to accept incoming SSL/TLS connections and to establish
|
244
|
+
# client authenticated outgoing SSL/TLS connection. Non client authenticated
|
245
|
+
# outgoing SSL/TLS connections do not require this property.
|
246
|
+
#
|
247
|
+
# ==== Options
|
248
|
+
#
|
249
|
+
# * certificate - the certificate
|
250
|
+
#
|
251
|
+
def certificate=(certificate)
|
252
|
+
Cproton.pn_messenger_set_certificate(@impl, certificate)
|
253
|
+
end
|
254
|
+
|
255
|
+
# Returns the path to a certificate file.
|
256
|
+
#
|
257
|
+
def certificate
|
258
|
+
Cproton.pn_messenger_get_certificate(@impl)
|
259
|
+
end
|
260
|
+
|
261
|
+
# Path to a private key file for the +Messenger+.
|
262
|
+
#
|
263
|
+
# The property must be specified for the +Messenger+ to accept incoming
|
264
|
+
# SSL/TLS connections and to establish client authenticated outgoing
|
265
|
+
# SSL/TLS connections. Non client authenticated SSL/TLS connections
|
266
|
+
# do not require this property.
|
267
|
+
#
|
268
|
+
# ==== Options
|
269
|
+
#
|
270
|
+
# * key - the key file
|
271
|
+
#
|
272
|
+
def private_key=(key)
|
273
|
+
Cproton.pn_messenger_set_private_key(@impl, key)
|
274
|
+
end
|
275
|
+
|
276
|
+
# Returns the path to a private key file.
|
277
|
+
#
|
278
|
+
def private_key
|
279
|
+
Cproton.pn_messenger_get_private_key(@impl)
|
280
|
+
end
|
281
|
+
|
282
|
+
# A path to a database of trusted certificates for use in verifying the
|
283
|
+
# peer on an SSL/TLS connection. If this property is +nil+, then the
|
284
|
+
# peer will not be verified.
|
285
|
+
#
|
286
|
+
# ==== Options
|
287
|
+
#
|
288
|
+
# * certificates - the certificates path
|
289
|
+
#
|
290
|
+
def trusted_certificates=(certificates)
|
291
|
+
Cproton.pn_messenger_set_trusted_certificates(@impl,certificates)
|
292
|
+
end
|
293
|
+
|
294
|
+
# The path to the databse of trusted certificates.
|
295
|
+
#
|
296
|
+
def trusted_certificates
|
297
|
+
Cproton.pn_messenger_get_trusted_certificates(@impl)
|
298
|
+
end
|
299
|
+
|
300
|
+
# Places the content contained in the message onto the outgoing
|
301
|
+
# queue of the Messenger.
|
302
|
+
#
|
303
|
+
# This method will never block, however it will send any unblocked
|
304
|
+
# Messages in the outgoing queue immediately and leave any blocked
|
305
|
+
# Messages remaining in the outgoing queue.
|
306
|
+
# The send call may then be used to block until the outgoing queue
|
307
|
+
# is empty. The outgoing attribute may be used to check the depth
|
308
|
+
# of the outgoing queue.
|
309
|
+
#
|
310
|
+
# ==== Options
|
311
|
+
#
|
312
|
+
# * message - the message
|
313
|
+
#
|
314
|
+
def put(message)
|
315
|
+
if message.nil?
|
316
|
+
raise TypeError.new("invalid message: #{message}")
|
317
|
+
end
|
318
|
+
unless message.kind_of?(Qpid::Proton::Message)
|
319
|
+
raise ::ArgumentError.new("invalid message type: #{message.class}")
|
320
|
+
end
|
321
|
+
# encode the message first
|
322
|
+
message.pre_encode
|
323
|
+
perform_put(message)
|
324
|
+
return outgoing_tracker
|
325
|
+
end
|
326
|
+
|
327
|
+
private
|
328
|
+
|
329
|
+
def perform_put(message) # :nodoc:
|
330
|
+
Cproton.pn_messenger_put(@impl, message.impl)
|
331
|
+
end
|
332
|
+
|
333
|
+
public
|
334
|
+
|
335
|
+
|
336
|
+
# This call will block until the indicated number of messages
|
337
|
+
# have been sent, or until the operation times out.
|
338
|
+
# If n is -1 this call will block until all outgoing messages
|
339
|
+
# have been sent. If n is 0 then this call will send whatever
|
340
|
+
# it can without blocking.
|
341
|
+
#
|
342
|
+
def send(n = -1)
|
343
|
+
Cproton.pn_messenger_send(@impl, n)
|
344
|
+
end
|
345
|
+
|
346
|
+
# Moves the message from the head of the incoming message queue into
|
347
|
+
# the supplied message object. Any content in the supplied message
|
348
|
+
# will be overwritten.
|
349
|
+
# A tracker for the incoming Message is returned. The tracker can
|
350
|
+
# later be used to communicate your acceptance or rejection of the
|
351
|
+
# Message.
|
352
|
+
#
|
353
|
+
# If no message is provided in the argument, then one is created. In
|
354
|
+
# either case, the one returned will be the fetched message.
|
355
|
+
#
|
356
|
+
# ==== Options
|
357
|
+
#
|
358
|
+
# * msg - the (optional) +Message+ instance to be used
|
359
|
+
#
|
360
|
+
def get(msg = nil)
|
361
|
+
msg_impl = nil
|
362
|
+
if msg.nil? then
|
363
|
+
msg_impl = nil
|
364
|
+
else
|
365
|
+
msg_impl = msg.impl
|
366
|
+
end
|
367
|
+
perform_get(msg_impl)
|
368
|
+
msg.post_decode unless msg.nil?
|
369
|
+
return incoming_tracker
|
370
|
+
end
|
371
|
+
|
372
|
+
private
|
373
|
+
|
374
|
+
def perform_get(msg) # :nodoc:
|
375
|
+
Cproton.pn_messenger_get(@impl, msg)
|
376
|
+
end
|
377
|
+
|
378
|
+
public
|
379
|
+
|
380
|
+
# Receives up to limit messages into the incoming queue. If no value
|
381
|
+
# for limit is supplied, this call will receive as many messages as it
|
382
|
+
# can buffer internally. If the Messenger is in blocking mode, this
|
383
|
+
# call will block until at least one Message is available in the
|
384
|
+
# incoming queue.
|
385
|
+
#
|
386
|
+
# Options ====
|
387
|
+
#
|
388
|
+
# * limit - the maximum number of messages to receive
|
389
|
+
#
|
390
|
+
def receive(limit = -1)
|
391
|
+
Cproton.pn_messenger_recv(@impl, limit)
|
392
|
+
end
|
393
|
+
|
394
|
+
# Returns true if the messenger is currently receiving data.
|
395
|
+
def receiving?
|
396
|
+
Cproton.pn_messenger_receiving(@impl)
|
397
|
+
end
|
398
|
+
|
399
|
+
# Attempts interrupting of the messenger thread.
|
400
|
+
#
|
401
|
+
# The Messenger interface is single-threaded, and this is the only
|
402
|
+
# function intended to be called from outside of is thread.
|
403
|
+
#
|
404
|
+
# Call this from a non-Messenger thread to interrupt it while it
|
405
|
+
# is blocking. This will cause a ::InterruptError to be raised.
|
406
|
+
#
|
407
|
+
# If there is no currently blocking call, then the next blocking
|
408
|
+
# call will be affected, even if it is within the same thread that
|
409
|
+
# originated the interrupt.
|
410
|
+
#
|
411
|
+
def interrupt
|
412
|
+
Cproton.pn_messenger_interrupt(@impl)
|
413
|
+
end
|
414
|
+
|
415
|
+
# Sends or receives any outstanding messages queued for a Messenger.
|
416
|
+
#
|
417
|
+
# This will block for the indicated timeout. This method may also do I/O
|
418
|
+
# other than sending and receiving messages. For example, closing
|
419
|
+
# connections after stop() has been called.
|
420
|
+
#
|
421
|
+
def work(timeout=-1)
|
422
|
+
err = Cproton.pn_messenger_work(@impl, timeout)
|
423
|
+
if (err == Cproton::PN_TIMEOUT) then
|
424
|
+
return false
|
425
|
+
else
|
426
|
+
check_for_error(err)
|
427
|
+
return true
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
# Returns the number messages in the outgoing queue that have not been
|
432
|
+
# transmitted.
|
433
|
+
#
|
434
|
+
def outgoing
|
435
|
+
Cproton.pn_messenger_outgoing(@impl)
|
436
|
+
end
|
437
|
+
|
438
|
+
# Returns the number of messages in the incoming queue that have not
|
439
|
+
# been retrieved.
|
440
|
+
#
|
441
|
+
def incoming
|
442
|
+
Cproton.pn_messenger_incoming(@impl)
|
443
|
+
end
|
444
|
+
|
445
|
+
# Adds a routing rule to the Messenger's internal routing table.
|
446
|
+
#
|
447
|
+
# The route procedure may be used to influence how a Messenger will
|
448
|
+
# internally treat a given address or class of addresses. Every call
|
449
|
+
# to the route procedure will result in Messenger appending a routing
|
450
|
+
# rule to its internal routing table.
|
451
|
+
#
|
452
|
+
# Whenever a Message is presented to a Messenger for delivery, it
|
453
|
+
# will match the address of this message against the set of routing
|
454
|
+
# rules in order. The first rule to match will be triggered, and
|
455
|
+
# instead of routing based on the address presented in the message,
|
456
|
+
# the Messenger will route based on the address supplied in the rule.
|
457
|
+
#
|
458
|
+
# The pattern matching syntax supports two types of matches, a '%'
|
459
|
+
# will match any character except a '/', and a '*' will match any
|
460
|
+
# character including a '/'.
|
461
|
+
#
|
462
|
+
# A routing address is specified as a normal AMQP address, however it
|
463
|
+
# may additionally use substitution variables from the pattern match
|
464
|
+
# that triggered the rule.
|
465
|
+
#
|
466
|
+
# ==== Arguments
|
467
|
+
#
|
468
|
+
# * pattern - the address pattern
|
469
|
+
# * address - the target address
|
470
|
+
#
|
471
|
+
# ==== Examples
|
472
|
+
#
|
473
|
+
# # route messages sent to foo to the destionaty amqp://foo.com
|
474
|
+
# messenger.route("foo", "amqp://foo.com")
|
475
|
+
#
|
476
|
+
# # any message to foobar will be routed to amqp://foo.com/bar
|
477
|
+
# messenger.route("foobar", "amqp://foo.com/bar")
|
478
|
+
#
|
479
|
+
# # any message to bar/<path> will be routed to the same path within
|
480
|
+
# # the amqp://bar.com domain
|
481
|
+
# messenger.route("bar/*", "amqp://bar.com/$1")
|
482
|
+
#
|
483
|
+
# # route all Message objects over TLS
|
484
|
+
# messenger.route("amqp:*", "amqps:$1")
|
485
|
+
#
|
486
|
+
# # supply credentials for foo
|
487
|
+
# messenger.route("amqp://foo.com/*", "amqp://user:password@foo.com/$1")
|
488
|
+
#
|
489
|
+
# # supply credentials for all domains
|
490
|
+
# messenger.route("amqp://*", "amqp://user:password@$1")
|
491
|
+
#
|
492
|
+
# # route all addresses through a single proxy while preserving the
|
493
|
+
# # original destination
|
494
|
+
# messenger.route("amqp://%$/*", "amqp://user:password@proxy/$1/$2")
|
495
|
+
#
|
496
|
+
# # route any address through a single broker
|
497
|
+
# messenger.route("*", "amqp://user:password@broker/$1")
|
498
|
+
#
|
499
|
+
def route(pattern, address)
|
500
|
+
Cproton.pn_messenger_route(@impl, pattern, address)
|
501
|
+
end
|
502
|
+
|
503
|
+
# Similar to #route, except that the destination of
|
504
|
+
# the Message is determined before the message address is rewritten.
|
505
|
+
#
|
506
|
+
# The outgoing address is only rewritten after routing has been
|
507
|
+
# finalized. If a message has an outgoing address of
|
508
|
+
# "amqp://0.0.0.0:5678", and a rewriting rule that changes its
|
509
|
+
# outgoing address to "foo", it will still arrive at the peer that
|
510
|
+
# is listening on "amqp://0.0.0.0:5678", but when it arrives there,
|
511
|
+
# the receiver will see its outgoing address as "foo".
|
512
|
+
#
|
513
|
+
# The default rewrite rule removes username and password from addresses
|
514
|
+
# before they are transmitted.
|
515
|
+
#
|
516
|
+
# ==== Arguments
|
517
|
+
#
|
518
|
+
# * pattern - the outgoing address
|
519
|
+
# * address - the target address
|
520
|
+
#
|
521
|
+
def rewrite(pattern, address)
|
522
|
+
Cproton.pn_messenger_rewrite(@impl, pattern, address)
|
523
|
+
end
|
524
|
+
|
525
|
+
def selectable
|
526
|
+
impl = Cproton.pn_messenger_selectable(@impl)
|
527
|
+
|
528
|
+
# if we don't have any selectables, then return
|
529
|
+
return nil if impl.nil?
|
530
|
+
|
531
|
+
fd = Cproton.pn_selectable_get_fd(impl)
|
532
|
+
|
533
|
+
selectable = @selectables[fd]
|
534
|
+
if selectable.nil?
|
535
|
+
selectable = Selectable.new(self, impl)
|
536
|
+
@selectables[fd] = selectable
|
537
|
+
end
|
538
|
+
return selectable
|
539
|
+
end
|
540
|
+
|
541
|
+
# Returns a +Tracker+ for the message most recently sent via the put
|
542
|
+
# method.
|
543
|
+
#
|
544
|
+
def outgoing_tracker
|
545
|
+
impl = Cproton.pn_messenger_outgoing_tracker(@impl)
|
546
|
+
return nil if impl == -1
|
547
|
+
Tracker.new(impl)
|
548
|
+
end
|
549
|
+
|
550
|
+
# Returns a +Tracker+ for the most recently received message.
|
551
|
+
#
|
552
|
+
def incoming_tracker
|
553
|
+
impl = Cproton.pn_messenger_incoming_tracker(@impl)
|
554
|
+
return nil if impl == -1
|
555
|
+
Tracker.new(impl)
|
556
|
+
end
|
557
|
+
|
558
|
+
# Signal the sender that you have acted on the Message
|
559
|
+
# pointed to by the tracker. If no tracker is supplied,
|
560
|
+
# then all messages that have been returned by the get
|
561
|
+
# method are accepted, except those that have already been
|
562
|
+
# auto-settled by passing beyond your incoming window size.
|
563
|
+
#
|
564
|
+
# ==== Options
|
565
|
+
#
|
566
|
+
# * tracker - the tracker
|
567
|
+
#
|
568
|
+
def accept(tracker = nil)
|
569
|
+
raise TypeError.new("invalid tracker: #{tracker}") unless tracker.nil? or valid_tracker?(tracker)
|
570
|
+
if tracker.nil? then
|
571
|
+
tracker = self.incoming_tracker
|
572
|
+
flag = Cproton::PN_CUMULATIVE
|
573
|
+
else
|
574
|
+
flag = 0
|
575
|
+
end
|
576
|
+
Cproton.pn_messenger_accept(@impl, tracker.impl, flag)
|
577
|
+
end
|
578
|
+
|
579
|
+
# Rejects the incoming message identified by the tracker.
|
580
|
+
# If no tracker is supplied, all messages that have been returned
|
581
|
+
# by the get method are rejected, except those that have already
|
582
|
+
# been auto-settled by passing beyond your outgoing window size.
|
583
|
+
#
|
584
|
+
# ==== Options
|
585
|
+
#
|
586
|
+
# * tracker - the tracker
|
587
|
+
#
|
588
|
+
def reject(tracker)
|
589
|
+
raise TypeError.new("invalid tracker: #{tracker}") unless tracker.nil? or valid_tracker?(tracker)
|
590
|
+
if tracker.nil? then
|
591
|
+
tracker = self.incoming_tracker
|
592
|
+
flag = Cproton::PN_CUMULATIVE
|
593
|
+
else
|
594
|
+
flag = 0
|
595
|
+
end
|
596
|
+
Cproton.pn_messenger_reject(@impl, tracker.impl, flag)
|
597
|
+
end
|
598
|
+
|
599
|
+
# Gets the last known remote state of the delivery associated with
|
600
|
+
# the given tracker, as long as the Message is still within your
|
601
|
+
# outgoing window. (Also works on incoming messages that are still
|
602
|
+
# within your incoming queue. See TrackerStatus for details on the
|
603
|
+
# values returned.
|
604
|
+
#
|
605
|
+
# ==== Options
|
606
|
+
#
|
607
|
+
# * tracker - the tracker
|
608
|
+
#
|
609
|
+
def status(tracker)
|
610
|
+
raise TypeError.new("invalid tracker: #{tracker}") unless valid_tracker?(tracker)
|
611
|
+
TrackerStatus.by_value(Cproton.pn_messenger_status(@impl, tracker.impl))
|
612
|
+
end
|
613
|
+
|
614
|
+
# Frees a Messenger from tracking the status associated
|
615
|
+
# with a given tracker. If you don't supply a tracker, all
|
616
|
+
# outgoing messages up to the most recent will be settled.
|
617
|
+
#
|
618
|
+
# ==== Options
|
619
|
+
#
|
620
|
+
# * tracker - the tracker
|
621
|
+
#
|
622
|
+
# ==== Examples
|
623
|
+
#
|
624
|
+
def settle(tracker)
|
625
|
+
raise TypeError.new("invalid tracker: #{tracker}") unless valid_tracker?(tracker)
|
626
|
+
if tracker.nil? then
|
627
|
+
tracker = self.incoming_tracker
|
628
|
+
flag = Cproton::PN_CUMULATIVE
|
629
|
+
else
|
630
|
+
flag = 0
|
631
|
+
end
|
632
|
+
Cproton.pn_messenger_settle(@impl, tracker.impl, flag)
|
633
|
+
end
|
634
|
+
|
635
|
+
# Sets the incoming window.
|
636
|
+
#
|
637
|
+
# The Messenger will track the remote status of this many incoming
|
638
|
+
# deliveries after they have been accepted or rejected.
|
639
|
+
#
|
640
|
+
# Messages enter this window only when you take them into your application
|
641
|
+
# using get(). If your incoming window size is n, and you get n+1 messages
|
642
|
+
# without explicitly accepting or rejecting the oldest message, then the
|
643
|
+
# message that passes beyond the edge of the incoming window will be
|
644
|
+
# assigned the default disposition of its link.
|
645
|
+
#
|
646
|
+
# ==== Options
|
647
|
+
#
|
648
|
+
# * window - the window size
|
649
|
+
#
|
650
|
+
def incoming_window=(window)
|
651
|
+
raise TypeError.new("invalid window: #{window}") unless valid_window?(window)
|
652
|
+
Cproton.pn_messenger_set_incoming_window(@impl, window)
|
653
|
+
end
|
654
|
+
|
655
|
+
# Returns the incoming window.
|
656
|
+
#
|
657
|
+
def incoming_window
|
658
|
+
Cproton.pn_messenger_get_incoming_window(@impl)
|
659
|
+
end
|
660
|
+
|
661
|
+
# Sets the outgoing window.
|
662
|
+
#
|
663
|
+
# The Messenger will track the remote status of this many outgoing
|
664
|
+
# deliveries after calling send.
|
665
|
+
# A Message enters this window when you call the put() method with the
|
666
|
+
# message. If your outgoing window size is n, and you call put n+1
|
667
|
+
# times, status information will no longer be available for the
|
668
|
+
# first message.
|
669
|
+
#
|
670
|
+
# ==== Options
|
671
|
+
#
|
672
|
+
# * window - the window size
|
673
|
+
#
|
674
|
+
def outgoing_window=(window)
|
675
|
+
raise TypeError.new("invalid window: #{window}") unless valid_window?(window)
|
676
|
+
Cproton.pn_messenger_set_outgoing_window(@impl, window)
|
677
|
+
end
|
678
|
+
|
679
|
+
# Returns the outgoing window.
|
680
|
+
#
|
681
|
+
def outgoing_window
|
682
|
+
Cproton.pn_messenger_get_outgoing_window(@impl)
|
683
|
+
end
|
684
|
+
|
685
|
+
# Unregisters a selectable object.
|
686
|
+
def unregister_selectable(fileno) # :nodoc:
|
687
|
+
@selectables.delete(fileno)
|
688
|
+
end
|
689
|
+
|
690
|
+
private
|
691
|
+
|
692
|
+
def valid_tracker?(tracker)
|
693
|
+
!tracker.nil? && tracker.is_a?(Tracker)
|
694
|
+
end
|
695
|
+
|
696
|
+
def valid_window?(window)
|
697
|
+
!window.nil? && [Float, Fixnum].include?(window.class)
|
698
|
+
end
|
699
|
+
|
700
|
+
end
|
701
|
+
|
702
|
+
end
|