qpid_proton 0.0.1 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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