qpid_proton 0.0.1 → 0.3
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.
- 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
|