qpid_proton 0.0.1 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +9 -0
- data/LICENSE +203 -0
- data/TODO +14 -0
- data/ext/cproton/cproton.c +9872 -1995
- data/lib/qpid_proton.rb +8 -2
- data/lib/qpid_proton/exception_handling.rb +69 -0
- data/lib/qpid_proton/exceptions.rb +69 -0
- data/lib/qpid_proton/message.rb +434 -0
- data/lib/qpid_proton/message_format.rb +75 -0
- data/lib/qpid_proton/messenger.rb +399 -0
- data/lib/qpid_proton/{version.rb → subscription.rb} +14 -2
- data/lib/qpid_proton/tracker.rb +46 -0
- data/lib/qpid_proton/tracker_status.rb +72 -0
- metadata +18 -9
@@ -0,0 +1,75 @@
|
|
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
|
21
|
+
|
22
|
+
module Proton
|
23
|
+
|
24
|
+
class MessageFormat
|
25
|
+
|
26
|
+
def initialize value, name # :nodoc:
|
27
|
+
@value = value
|
28
|
+
@name = name
|
29
|
+
end
|
30
|
+
|
31
|
+
def value # :nodoc:
|
32
|
+
@value
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s # :nodoc:
|
36
|
+
@name.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.formats # :nodoc:
|
40
|
+
@formats
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.by_name(name) # :nodoc:
|
44
|
+
@by_name[name.to_sym]
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.by_value(value) # :nodoc:
|
48
|
+
@by_value[value]
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def self.add_item(key, value) # :nodoc:
|
54
|
+
@by_name ||= {}
|
55
|
+
@by_name[key] = MessageFormat.new value, key
|
56
|
+
@by_value ||= {}
|
57
|
+
@by_value[value] = @by_name[key]
|
58
|
+
@formats ||= []
|
59
|
+
@formats << @by_value[value]
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.const_missing(key) # :nodoc:
|
63
|
+
@by_name[key]
|
64
|
+
end
|
65
|
+
|
66
|
+
self.add_item :DATA, Cproton::PN_DATA
|
67
|
+
self.add_item :TEXT, Cproton::PN_TEXT
|
68
|
+
self.add_item :AMQP, Cproton::PN_AMQP
|
69
|
+
self.add_item :JSON, Cproton::PN_JSON
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,399 @@
|
|
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
|
21
|
+
|
22
|
+
module Proton
|
23
|
+
|
24
|
+
# A +Messenger+ provides a high-level means for sending and
|
25
|
+
# receiving AMQP messages.
|
26
|
+
#
|
27
|
+
# ==== Examples
|
28
|
+
#
|
29
|
+
class Messenger
|
30
|
+
|
31
|
+
# Automatically accept every message as it is returned by #get
|
32
|
+
#
|
33
|
+
ACCEPT_MODE_AUTO = Cproton::PN_ACCEPT_MODE_AUTO
|
34
|
+
|
35
|
+
# Messages must be manually accepted or rejected using #accept
|
36
|
+
#
|
37
|
+
ACCEPT_MODE_MANUAL = Cproton::PN_ACCEPT_MODE_MANUAL
|
38
|
+
|
39
|
+
include Qpid::Proton::ExceptionHandling
|
40
|
+
|
41
|
+
# Creates a new +Messenger+.
|
42
|
+
#
|
43
|
+
# The +name+ parameter is optional. If one is not provided then
|
44
|
+
# a unique name is generated.
|
45
|
+
#
|
46
|
+
# ==== Options
|
47
|
+
#
|
48
|
+
# * name - the name (def. nil)
|
49
|
+
#
|
50
|
+
def initialize(name = nil)
|
51
|
+
@impl = Cproton.pn_messenger(name)
|
52
|
+
ObjectSpace.define_finalizer(self, self.class.finalize!(@impl))
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.finalize!(impl) # :nodoc:
|
56
|
+
proc {
|
57
|
+
Cproton.pn_messenger_stop(impl)
|
58
|
+
Cproton.pn_messenger_free(impl)
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the name.
|
63
|
+
#
|
64
|
+
def name
|
65
|
+
Cproton.pn_messenger_name(@impl)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Sets the timeout period, in milliseconds.
|
69
|
+
#
|
70
|
+
# A negative timeout period implies an infinite timeout.
|
71
|
+
#
|
72
|
+
# ==== Options
|
73
|
+
#
|
74
|
+
# * timeout - the timeout period
|
75
|
+
#
|
76
|
+
def timeout=(timeout)
|
77
|
+
raise TypeError.new("invalid timeout: #{timeout}") if timeout.nil?
|
78
|
+
Cproton.pn_messenger_set_timeout(@impl, timeout)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns the timeout period
|
82
|
+
#
|
83
|
+
def timeout
|
84
|
+
Cproton.pn_messenger_get_timeout(@impl)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Reports whether an error occurred.
|
88
|
+
#
|
89
|
+
def error?
|
90
|
+
!Cproton.pn_messenger_errno(@impl).zero?
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the most recent error number.
|
94
|
+
#
|
95
|
+
def errno
|
96
|
+
Cproton.pn_messenger_errno(@impl)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns the most recent error message.
|
100
|
+
#
|
101
|
+
def error
|
102
|
+
Cproton.pn_messenger_error(@impl)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Starts the +Messenger+, allowing it to begin sending and
|
106
|
+
# receiving messages.
|
107
|
+
#
|
108
|
+
def start
|
109
|
+
check_for_error(Cproton.pn_messenger_start(@impl))
|
110
|
+
end
|
111
|
+
|
112
|
+
# Stops the +Messenger+, preventing it from sending or receiving
|
113
|
+
# any more messages.
|
114
|
+
#
|
115
|
+
def stop
|
116
|
+
check_for_error(Cproton.pn_messenger_stop(@impl))
|
117
|
+
end
|
118
|
+
|
119
|
+
# Subscribes the +Messenger+ to a remote address.
|
120
|
+
#
|
121
|
+
def subscribe(address)
|
122
|
+
raise TypeError.new("invalid address: #{address}") if address.nil?
|
123
|
+
subscription = Cproton.pn_messenger_subscribe(@impl, address)
|
124
|
+
raise Qpid::Proton::ProtonError.new("Subscribe failed") if subscription.nil?
|
125
|
+
Qpid::Proton::Subscription.new(subscription)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Path to a certificate file for the +Messenger+.
|
129
|
+
#
|
130
|
+
# This certificate is used when the +Messenger+ accepts or establishes
|
131
|
+
# SSL/TLS connections.
|
132
|
+
#
|
133
|
+
# ==== Options
|
134
|
+
#
|
135
|
+
# * certificate - the certificate
|
136
|
+
#
|
137
|
+
def certificate=(certificate)
|
138
|
+
Cproton.pn_messenger_set_certificate(@impl, certificate)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns the path to a certificate file.
|
142
|
+
#
|
143
|
+
def certificate
|
144
|
+
Cproton.pn_messenger_get_certificate(@impl)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Path to a private key file for the +Messenger+.
|
148
|
+
#
|
149
|
+
# The property must be specified for the +Messenger+ to accept incoming
|
150
|
+
# SSL/TLS connections and to establish client authenticated outgoing
|
151
|
+
# SSL/TLS connections.
|
152
|
+
#
|
153
|
+
# ==== Options
|
154
|
+
#
|
155
|
+
# * key - the key file
|
156
|
+
#
|
157
|
+
def private_key=(key)
|
158
|
+
Cproton.pn_messenger_set_private_key(@impl, key)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Returns the path to a private key file.
|
162
|
+
#
|
163
|
+
def private_key
|
164
|
+
Cproton.pn_messenger_get_private_key(@impl)
|
165
|
+
end
|
166
|
+
|
167
|
+
# A path to a database of trusted certificates for use in verifying the
|
168
|
+
# peer on an SSL/TLS connection. If this property is +nil+, then the
|
169
|
+
# peer will not be verified.
|
170
|
+
#
|
171
|
+
# ==== Options
|
172
|
+
#
|
173
|
+
# * certificates - the certificates path
|
174
|
+
#
|
175
|
+
def trusted_certificates=(certificates)
|
176
|
+
Cproton.pn_messenger_set_trusted_certificates(@impl,certificates)
|
177
|
+
end
|
178
|
+
|
179
|
+
# The path to the databse of trusted certificates.
|
180
|
+
#
|
181
|
+
def trusted_certificates
|
182
|
+
Cproton.pn_messenger_get_trusted_certificates(@impl)
|
183
|
+
end
|
184
|
+
|
185
|
+
# Puts a single message into the outgoing queue.
|
186
|
+
#
|
187
|
+
# To ensure messages are sent, you should then call ::send.
|
188
|
+
#
|
189
|
+
# ==== Options
|
190
|
+
#
|
191
|
+
# * message - the message
|
192
|
+
#
|
193
|
+
def put(message)
|
194
|
+
raise TypeError.new("invalid message: #{message}") if message.nil?
|
195
|
+
raise ArgumentError.new("invalid message type: #{message.class}") unless message.kind_of?(Message)
|
196
|
+
check_for_error(Cproton.pn_messenger_put(@impl, message.impl))
|
197
|
+
end
|
198
|
+
|
199
|
+
# Sends all outgoing messages, blocking until the outgoing queue
|
200
|
+
# is empty.
|
201
|
+
#
|
202
|
+
def send
|
203
|
+
check_for_error(Cproton.pn_messenger_send(@impl))
|
204
|
+
end
|
205
|
+
|
206
|
+
# Gets a single message incoming message from the local queue.
|
207
|
+
#
|
208
|
+
# If no message is provided in the argument, then one is created. In
|
209
|
+
# either case, the one returned will be the fetched message.
|
210
|
+
#
|
211
|
+
# ==== Options
|
212
|
+
#
|
213
|
+
# * msg - the (optional) +Message+ instance to be used
|
214
|
+
#
|
215
|
+
def get(msg = nil)
|
216
|
+
msg = Qpid::Proton::Message.new if msg.nil?
|
217
|
+
check_for_error(Cproton.pn_messenger_get(@impl, msg.impl))
|
218
|
+
return msg
|
219
|
+
end
|
220
|
+
|
221
|
+
# Receives up to the specified number of messages, blocking until at least
|
222
|
+
# one message is received.
|
223
|
+
#
|
224
|
+
# Options ====
|
225
|
+
#
|
226
|
+
# * max - the maximum number of messages to receive
|
227
|
+
#
|
228
|
+
def receive(max)
|
229
|
+
raise TypeError.new("invalid max: #{max}") if max.nil? || max.to_i.zero?
|
230
|
+
raise RangeError.new("negative max: #{max}") if max < 0
|
231
|
+
check_for_error(Cproton.pn_messenger_recv(@impl, max))
|
232
|
+
end
|
233
|
+
|
234
|
+
# Returns the number messages in the outgoing queue that have not been
|
235
|
+
# transmitted.
|
236
|
+
#
|
237
|
+
def outgoing
|
238
|
+
Cproton.pn_messenger_outgoing(@impl)
|
239
|
+
end
|
240
|
+
|
241
|
+
# Returns the number of messages in the incoming queue that have not
|
242
|
+
# been retrieved.
|
243
|
+
#
|
244
|
+
def incoming
|
245
|
+
Cproton.pn_messenger_incoming(@impl)
|
246
|
+
end
|
247
|
+
|
248
|
+
# Returns a +Tracker+ for the message most recently sent via the put
|
249
|
+
# method.
|
250
|
+
#
|
251
|
+
def outgoing_tracker
|
252
|
+
impl = Cproton.pn_messenger_outgoing_tracker(@impl)
|
253
|
+
return nil if impl == -1
|
254
|
+
Qpid::Proton::Tracker.new(impl)
|
255
|
+
end
|
256
|
+
|
257
|
+
# Returns a +Tracker+ for the most recently received message.
|
258
|
+
#
|
259
|
+
def incoming_tracker
|
260
|
+
impl = Cproton.pn_messenger_incoming_tracker(@impl)
|
261
|
+
return nil if impl == -1
|
262
|
+
Qpid::Proton::Tracker.new(impl)
|
263
|
+
end
|
264
|
+
|
265
|
+
# Set the accept mode for the Messenger. See #ACCEPT_MODE_AUTO and
|
266
|
+
# #ACCEPT_MODE_MANUAL for more details
|
267
|
+
#
|
268
|
+
# ==== Options
|
269
|
+
#
|
270
|
+
# * mode - the acceptance mode
|
271
|
+
#
|
272
|
+
# ==== Examples
|
273
|
+
#
|
274
|
+
# @messenger.accept_mode = Qpid::Proton::Messenger::ACCEPT_MODE_AUTO
|
275
|
+
#
|
276
|
+
def accept_mode=(mode)
|
277
|
+
raise TypeError.new("Invalid mode: #{mode}") unless valid_mode?(mode)
|
278
|
+
Cproton.pn_messenger_set_accept_mode(@impl, mode)
|
279
|
+
end
|
280
|
+
|
281
|
+
# Returns the current acceptance mode for the Messenger.
|
282
|
+
#
|
283
|
+
def accept_mode
|
284
|
+
Cproton.pn_messenger_get_accept_mode(@impl)
|
285
|
+
end
|
286
|
+
|
287
|
+
# Accepts the incoming message identified by the tracker.
|
288
|
+
#
|
289
|
+
# ==== Options
|
290
|
+
#
|
291
|
+
# * tracker - the tracker
|
292
|
+
# * flag - the flag
|
293
|
+
#
|
294
|
+
def accept(tracker, flag)
|
295
|
+
raise TypeError.new("invalid tracker: #{tracker}") unless valid_tracker?(tracker)
|
296
|
+
raise TypeError.new("invalid flag: #{flag}") unless Qpid::Proton::Tracker.valid_flag?(flag)
|
297
|
+
check_for_error(Cproton.pn_messenger_accept(@impl, tracker.impl, flag))
|
298
|
+
end
|
299
|
+
|
300
|
+
# Rejects the incoming message identified by the tracker.
|
301
|
+
#
|
302
|
+
# ==== Options
|
303
|
+
#
|
304
|
+
# * tracker - the tracker
|
305
|
+
# * flag - the flag
|
306
|
+
#
|
307
|
+
def reject(tracker, flag)
|
308
|
+
raise TypeError.new("invalid tracker: #{tracker}") unless valid_tracker?(tracker)
|
309
|
+
check_for_error(Cproton.pn_messenger_reject(@impl, tracker.impl, flag))
|
310
|
+
end
|
311
|
+
|
312
|
+
# Gets the last known remote state of the delivery associated with
|
313
|
+
# the given tracker. See TrackerStatus for details on the values
|
314
|
+
# returned.
|
315
|
+
#
|
316
|
+
# ==== Options
|
317
|
+
#
|
318
|
+
# * tracker - the tracker
|
319
|
+
#
|
320
|
+
def status(tracker)
|
321
|
+
raise TypeError.new("invalid tracker: #{tracker}") unless valid_tracker?(tracker)
|
322
|
+
Qpid::Proton::TrackerStatus.by_value(Cproton.pn_messenger_status(@impl, tracker.impl))
|
323
|
+
end
|
324
|
+
|
325
|
+
# Settles messages for a tracker.
|
326
|
+
#
|
327
|
+
# ==== Options
|
328
|
+
#
|
329
|
+
# * tracker - the tracker
|
330
|
+
# * flag - the flag
|
331
|
+
#
|
332
|
+
# ==== Examples
|
333
|
+
#
|
334
|
+
def settle(tracker, flag)
|
335
|
+
raise TypeError.new("invalid tracker: #{tracker}") unless valid_tracker?(tracker)
|
336
|
+
raise TypeError.new("invalid flag: #{flag}") unless Qpid::Proton::Tracker.valid_flag?(flag)
|
337
|
+
Cproton.pn_messenger_settle(@impl, tracker.impl, flag)
|
338
|
+
end
|
339
|
+
|
340
|
+
# Sets the incoming window.
|
341
|
+
#
|
342
|
+
# If the incoming window is set to a positive value, then after each
|
343
|
+
# call to #accept or #reject, the object will track the status of that
|
344
|
+
# many deliveries.
|
345
|
+
#
|
346
|
+
# ==== Options
|
347
|
+
#
|
348
|
+
# * window - the window size
|
349
|
+
#
|
350
|
+
def incoming_window=(window)
|
351
|
+
raise TypeError.new("invalid window: #{window}") unless valid_window?(window)
|
352
|
+
check_for_error(Cproton.pn_messenger_set_incoming_window(@impl, window))
|
353
|
+
end
|
354
|
+
|
355
|
+
# Returns the incoming window.
|
356
|
+
#
|
357
|
+
def incoming_window
|
358
|
+
Cproton.pn_messenger_get_incoming_window(@impl)
|
359
|
+
end
|
360
|
+
|
361
|
+
#Sets the outgoing window.
|
362
|
+
#
|
363
|
+
# If the outgoing window is set to a positive value, then after each call
|
364
|
+
# to #send, the object will track the status of that many deliveries.
|
365
|
+
#
|
366
|
+
# ==== Options
|
367
|
+
#
|
368
|
+
# * window - the window size
|
369
|
+
#
|
370
|
+
def outgoing_window=(window)
|
371
|
+
raise TypeError.new("invalid window: #{window}") unless valid_window?(window)
|
372
|
+
check_for_error(Cproton.pn_messenger_set_outgoing_window(@impl, window))
|
373
|
+
end
|
374
|
+
|
375
|
+
# Returns the outgoing window.
|
376
|
+
#
|
377
|
+
def outgoing_window
|
378
|
+
Cproton.pn_messenger_get_outgoing_window(@impl)
|
379
|
+
end
|
380
|
+
|
381
|
+
private
|
382
|
+
|
383
|
+
def valid_tracker?(tracker)
|
384
|
+
!tracker.nil? && tracker.is_a?(Qpid::Proton::Tracker)
|
385
|
+
end
|
386
|
+
|
387
|
+
def valid_mode?(mode)
|
388
|
+
[ACCEPT_MODE_AUTO, ACCEPT_MODE_MANUAL].include?(mode)
|
389
|
+
end
|
390
|
+
|
391
|
+
def valid_window?(window)
|
392
|
+
!window.nil? && [Float, Fixnum].include?(window.class)
|
393
|
+
end
|
394
|
+
|
395
|
+
end
|
396
|
+
|
397
|
+
end
|
398
|
+
|
399
|
+
end
|