qpid_proton 0.18.1 → 0.19.0

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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cproton/cproton.c +863 -75
  3. data/lib/codec/data.rb +589 -815
  4. data/lib/codec/mapping.rb +142 -126
  5. data/lib/core/condition.rb +89 -0
  6. data/lib/core/connection.rb +188 -228
  7. data/lib/core/connection_driver.rb +202 -0
  8. data/lib/core/container.rb +366 -0
  9. data/lib/core/delivery.rb +76 -251
  10. data/lib/core/disposition.rb +21 -35
  11. data/lib/core/endpoint.rb +21 -53
  12. data/lib/core/event.rb +156 -0
  13. data/lib/core/exceptions.rb +109 -106
  14. data/lib/core/link.rb +24 -49
  15. data/lib/core/listener.rb +82 -0
  16. data/lib/core/message.rb +59 -155
  17. data/lib/core/messaging_handler.rb +190 -0
  18. data/lib/core/receiver.rb +38 -7
  19. data/lib/core/sasl.rb +43 -46
  20. data/lib/core/sender.rb +55 -32
  21. data/lib/core/session.rb +58 -58
  22. data/lib/core/ssl.rb +5 -13
  23. data/lib/core/ssl_details.rb +1 -2
  24. data/lib/core/ssl_domain.rb +5 -8
  25. data/lib/core/terminus.rb +62 -30
  26. data/lib/core/tracker.rb +45 -0
  27. data/lib/core/transfer.rb +121 -0
  28. data/lib/core/transport.rb +62 -97
  29. data/lib/core/uri.rb +73 -0
  30. data/lib/core/url.rb +11 -7
  31. data/lib/handler/adapter.rb +78 -0
  32. data/lib/handler/messaging_adapter.rb +127 -0
  33. data/lib/handler/messaging_handler.rb +128 -178
  34. data/lib/handler/reactor_messaging_adapter.rb +158 -0
  35. data/lib/messenger/messenger.rb +9 -8
  36. data/lib/messenger/subscription.rb +1 -2
  37. data/lib/messenger/tracker.rb +1 -2
  38. data/lib/messenger/tracker_status.rb +1 -2
  39. data/lib/qpid_proton.rb +36 -66
  40. data/lib/reactor/container.rb +40 -234
  41. data/lib/types/array.rb +73 -130
  42. data/lib/types/described.rb +2 -44
  43. data/lib/types/hash.rb +19 -56
  44. data/lib/types/strings.rb +1 -2
  45. data/lib/types/type.rb +68 -0
  46. data/lib/util/{handler.rb → deprecation.rb} +22 -15
  47. data/lib/util/error_handler.rb +4 -25
  48. data/lib/util/timeout.rb +1 -2
  49. data/lib/util/version.rb +1 -2
  50. data/lib/util/wrapper.rb +58 -38
  51. metadata +16 -33
  52. data/lib/core/base_handler.rb +0 -31
  53. data/lib/core/selectable.rb +0 -130
  54. data/lib/event/collector.rb +0 -148
  55. data/lib/event/event.rb +0 -318
  56. data/lib/event/event_base.rb +0 -91
  57. data/lib/event/event_type.rb +0 -71
  58. data/lib/handler/acking.rb +0 -70
  59. data/lib/handler/c_adaptor.rb +0 -47
  60. data/lib/handler/c_flow_controller.rb +0 -33
  61. data/lib/handler/endpoint_state_handler.rb +0 -217
  62. data/lib/handler/incoming_message_handler.rb +0 -74
  63. data/lib/handler/outgoing_message_handler.rb +0 -100
  64. data/lib/handler/wrapped_handler.rb +0 -76
  65. data/lib/reactor/acceptor.rb +0 -41
  66. data/lib/reactor/backoff.rb +0 -41
  67. data/lib/reactor/connector.rb +0 -115
  68. data/lib/reactor/global_overrides.rb +0 -44
  69. data/lib/reactor/link_option.rb +0 -90
  70. data/lib/reactor/reactor.rb +0 -196
  71. data/lib/reactor/session_per_connection.rb +0 -45
  72. data/lib/reactor/ssl_config.rb +0 -41
  73. data/lib/reactor/task.rb +0 -39
  74. data/lib/reactor/urls.rb +0 -45
  75. data/lib/util/class_wrapper.rb +0 -54
  76. data/lib/util/condition.rb +0 -47
  77. data/lib/util/constants.rb +0 -85
  78. data/lib/util/engine.rb +0 -82
  79. data/lib/util/reactor.rb +0 -32
  80. data/lib/util/swig_helper.rb +0 -114
  81. data/lib/util/uuid.rb +0 -32
data/lib/core/link.rb CHANGED
@@ -1,4 +1,3 @@
1
- #--
2
1
  # Licensed to the Apache Software Foundation (ASF) under one
3
2
  # or more contributor license agreements. See the NOTICE file
4
3
  # distributed with this work for additional information
@@ -15,7 +14,7 @@
15
14
  # KIND, either express or implied. See the License for the
16
15
  # specific language governing permissions and limitations
17
16
  # under the License.
18
- #++
17
+
19
18
 
20
19
  module Qpid::Proton
21
20
 
@@ -26,6 +25,11 @@ module Qpid::Proton
26
25
  #
27
26
  class Link < Endpoint
28
27
 
28
+ # @private
29
+ PROTON_METHOD_PREFIX = "pn_link"
30
+ # @private
31
+ include Util::Wrapper
32
+
29
33
  # The sender will send all deliveries initially unsettled.
30
34
  SND_UNSETTLED = Cproton::PN_SND_UNSETTLED
31
35
  # The sender will send all deliveries settled to the receiver.
@@ -38,36 +42,21 @@ module Qpid::Proton
38
42
  # The receiver will only settle deliveries after the sender settles.
39
43
  RCV_SECOND = Cproton::PN_RCV_SECOND
40
44
 
41
- # @private
42
- include Util::SwigHelper
43
-
44
- # @private
45
- PROTON_METHOD_PREFIX = "pn_link"
46
-
47
45
  # @!attribute [r] state
48
46
  #
49
47
  # Returns the endpoint state flags.
50
48
  #
51
49
  proton_caller :state
52
50
 
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
51
+ # @deprecated Use {Sender#open} or {Receiver#open}
59
52
  proton_caller :open
60
53
 
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
54
+ # Close the local end of the link. The remote end may or may not be closed.
55
+ # @param error [Condition] Optional error condition to send with the close.
56
+ def close(error=nil)
57
+ Condition.assign(_local_condition, error)
58
+ Cproton.pn_link_close(@impl)
59
+ end
71
60
 
72
61
  # @!method detach
73
62
  #
@@ -176,7 +165,7 @@ module Qpid::Proton
176
165
  #
177
166
  # @return [Boolean] True if the link is a sender.
178
167
  #
179
- proton_reader :sender, :is_or_get => :is
168
+ proton_is :sender
180
169
 
181
170
  # @!attribute [r] receiver?
182
171
  #
@@ -184,10 +173,10 @@ module Qpid::Proton
184
173
  #
185
174
  # @return [Boolean] True if the link is a receiver.
186
175
  #
187
- proton_reader :receiver, :is_or_get => :is
176
+ proton_is :receiver
188
177
 
189
178
  # @private
190
- proton_reader :attachments
179
+ proton_get :attachments
191
180
 
192
181
  # Drains excess credit.
193
182
  #
@@ -207,20 +196,11 @@ module Qpid::Proton
207
196
  #
208
197
  proton_caller :drained
209
198
 
210
- # @private
211
- include Util::Wrapper
212
-
213
199
  # @private
214
200
  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
201
+ return unless impl
202
+ return fetch_instance(impl, :pn_link_attachments) ||
203
+ (Cproton.pn_link_is_sender(impl) ? Sender : Receiver).new(impl)
224
204
  end
225
205
 
226
206
  # @private
@@ -241,13 +221,9 @@ module Qpid::Proton
241
221
  Cproton.pn_link_error(@impl)
242
222
  end
243
223
 
244
- # Returns the next link that matches the given state mask.
245
- #
246
- # @param state_mask [Integer] The state mask.
247
- #
248
- # @return [Sender, Receiver] The next link.
249
- #
224
+ # @deprecated use {Session#each_link, Connection#each_link}
250
225
  def next(state_mask)
226
+ deprecated __method__, "Session#each_link, Connection#each_link"
251
227
  return Link.wrap(Cproton.pn_link_next(@impl, state_mask))
252
228
  end
253
229
 
@@ -298,11 +274,10 @@ module Qpid::Proton
298
274
  self.session.connection
299
275
  end
300
276
 
301
- # Returns the parent delivery.
302
- #
303
- # @return [Delivery] The delivery.
304
- #
277
+
278
+ # @deprecated use {Sender#send}
305
279
  def delivery(tag)
280
+ deprecated __method__, "Sender#send"
306
281
  Delivery.new(Cproton.pn_delivery(@impl, tag))
307
282
  end
308
283
 
@@ -0,0 +1,82 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+
19
+ module Qpid::Proton
20
+ # A listener for incoming connections.
21
+ #
22
+ # Create with {Container#listen} or {Container#listen_io}.
23
+ # To control the handler and connection options applied to incoming connections,
24
+ # pass a {ListenerHandler} on creation.
25
+ #
26
+ class Listener
27
+
28
+ # Class that handles listener events and provides options for accepted
29
+ # connections. This class simply returns a fixed set of options for every
30
+ # connection accepted, but you can subclass and override all of the on_
31
+ # methods to provide more interesting behaviour.
32
+ class Handler
33
+ # @param opts [Hash] Options to return from on_accept.
34
+ def initialize(opts=nil) @opts = opts || {}; end
35
+
36
+ # Called when the listener is ready to accept connections.
37
+ # @param listener [Listener] The listener
38
+ def on_open(listener) end
39
+
40
+ # Called if an error occurs.
41
+ # If there is an error while opening the listener, this method is
42
+ # called and {#on_open} is not
43
+ # @param listener [Listener]
44
+ # @param what [Condition] Information about the error.
45
+ def on_error(listener, what) end
46
+
47
+ # Called when a listener accepts a new connection.
48
+ # @param listener [Listener] The listener
49
+ # @return [Hash] Options to apply to the incoming connection, see {#connect}
50
+ def on_accept(listener) @opts; end
51
+
52
+ # Called when the listener closes.
53
+ # @param listener [Listener] The listener accepting the connection.
54
+ def on_close(listener) end
55
+ end
56
+
57
+ # @return [Container] The listener's container
58
+ attr_reader :container
59
+
60
+ # @return [Condition] The error condition if there is one
61
+ attr_reader :condition
62
+
63
+ # Close the listener
64
+ # @param error [Condition] Optional error condition.
65
+ def close(error=nil)
66
+ @closing = true
67
+ @condition ||= Condition.convert error
68
+ @io.close_read rescue nil # Cause listener to wake out of IO.select
69
+ nil
70
+ end
71
+
72
+ # Get the {IO} server socket used by the listener
73
+ def to_io() @io; end
74
+
75
+ private # Called by {Container}
76
+
77
+ def initialize(io, handler, container)
78
+ @io, @handler = io, handler
79
+ @container = container
80
+ end
81
+ end
82
+ end
data/lib/core/message.rb CHANGED
@@ -1,4 +1,3 @@
1
- #--
2
1
  # Licensed to the Apache Software Foundation (ASF) under one
3
2
  # or more contributor license agreements. See the NOTICE file
4
3
  # distributed with this work for additional information
@@ -15,77 +14,45 @@
15
14
  # KIND, either express or implied. See the License for the
16
15
  # specific language governing permissions and limitations
17
16
  # under the License.
18
- #++
17
+
19
18
 
20
19
  module Qpid::Proton
21
20
 
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
21
+ # Messsage data and headers that can sent or received on a {Link}
30
22
  #
31
- # To create a message for sending:
23
+ # {#body} is the main message content.
24
+ # {#properties} is a {Hash} of extra properties that can be attached to the message.
32
25
  #
33
- # # send a simple text message
34
- # msg = Qpid::Proton::Message.new
35
- # msg.body = "STATE: update"
26
+ # @example Create a message containing a Unicode string
27
+ # msg = Qpid::Proton::Message.new "this is a string"
36
28
  #
37
- # # send a binary chunk of data
38
- # data = File.binread("/home/qpid/binfile.tar.gz")
29
+ # @example Create a message containing binary data
39
30
  # msg = Qpid::Proton::Message.new
40
- # msg.body = Qpid::Proton::BinaryString.new(data)
31
+ # msg.body = Qpid::Proton::BinaryString.new(File.binread("/home/qpid/binfile.tar.gz"))
41
32
  #
42
33
  class Message
34
+ include Util::Deprecation
43
35
 
44
36
  # @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
37
+ PROTON_METHOD_PREFIX = "pn_message"
38
+ # @private
39
+ include Util::Wrapper
53
40
 
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
- #
41
+ # Decodes a message from AMQP binary data.
42
+ # @param encoded [String] the encoded bytes
43
+ # @return[Integer] the number of bytes consumed
61
44
  def decode(encoded)
62
45
  check(Cproton.pn_message_decode(@impl, encoded, encoded.length))
63
-
64
46
  post_decode
65
47
  end
66
48
 
67
- def post_decode # :nodoc:
49
+ # @private
50
+ def post_decode
68
51
  # 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
52
+ @properties = Codec::Data.to_object(Cproton::pn_message_properties(@impl)) || {}
53
+ @instructions = Codec:: Data.to_object(Cproton::pn_message_instructions(@impl)) || {}
54
+ @annotations = Codec::Data.to_object(Cproton::pn_message_annotations(@impl)) || {}
55
+ @body = Codec::Data.to_object(Cproton::pn_message_body(@impl))
89
56
  end
90
57
 
91
58
  # Encodes the message.
@@ -103,47 +70,38 @@ module Qpid::Proton
103
70
  end
104
71
  end
105
72
 
106
- def pre_encode # :nodoc:
73
+ # @private
74
+ def pre_encode
107
75
  # 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)
76
+ Codec::Data.from_object(Cproton::pn_message_properties(@impl),
77
+ !@properties.empty? && Types.symbol_keys!(@properties))
78
+ Codec::Data.from_object(Cproton::pn_message_instructions(@impl),
79
+ !@instructions.empty? && Types.symbol_keys!(@instructions))
80
+ if @annotations # Make sure keys are symbols
81
+ @annotations.keys.each do |k|
82
+ @annotations[k.to_sym] = @annotations.delete(k) unless k.is_a? Symbol
83
+ end
128
84
  end
85
+ Codec::Data.from_object(Cproton::pn_message_annotations(@impl), !@annotations.empty? && @annotations)
86
+ Codec::Data.from_object(Cproton::pn_message_body(@impl), @body)
129
87
  end
130
88
 
131
89
  # Creates a new +Message+ instance.
132
- def initialize(body = nil)
90
+ # @param body the body of the message, equivalent to calling m.body=(body)
91
+ # @param opts [Hash] additional options, equivalent to +Message#key=value+ for each +key=>value+
92
+ def initialize(body = nil, opts={})
133
93
  @impl = Cproton.pn_message
134
94
  ObjectSpace.define_finalizer(self, self.class.finalize!(@impl))
135
95
  @properties = {}
136
96
  @instructions = {}
137
97
  @annotations = {}
138
98
  self.body = body unless 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
99
+ if !opts.nil? then
100
+ opts.each do |k, v|
101
+ setter = (k.to_s+"=").to_sym()
102
+ self.send setter, v
103
+ end
104
+ end
147
105
  end
148
106
 
149
107
  # Invoked by garbage collection to clean up resources used
@@ -409,11 +367,13 @@ module Qpid::Proton
409
367
 
410
368
  # @deprecated use {#body=}
411
369
  def content=(content)
370
+ deprecated __method__, "body="
412
371
  Cproton.pn_message_load(@impl, content)
413
372
  end
414
373
 
415
374
  # @deprecated use {#body}
416
375
  def content
376
+ deprecated __method__, "body"
417
377
  size = 16
418
378
  loop do
419
379
  result = Cproton.pn_message_save(@impl, size)
@@ -529,88 +489,32 @@ module Qpid::Proton
529
489
  Cproton.pn_message_get_reply_to_group_id(@impl)
530
490
  end
531
491
 
532
- # Returns the list of property names for associated with this message.
533
- #
534
- # ==== Examples
535
- #
536
- # msg.properties.each do |name|
537
- # end
538
- #
539
- def properties
540
- @properties
541
- end
542
-
543
- # Replaces the entire set of properties with the specified hash.
544
- #
545
- def properties=(properties)
546
- @properties = properties
547
- end
492
+ # @return [Hash] Application properties for the message
493
+ attr_accessor :properties
548
494
 
549
- # Assigns the value given to the named property.
550
- #
551
- # ==== Arguments
552
- #
553
- # * name - the property name
554
- # * value - the property value
555
- #
556
- def []=(name, value)
557
- @properties[name] = value
558
- end
495
+ # Equivalent to +{#properties}[name] = value+
496
+ def []=(name, value) @properties[name] = value; end
559
497
 
560
- # Retrieves the value for the specified property name. If not found, then
561
- # it returns nil.
562
- #
563
- def [](name)
564
- @properties[name]
565
- end
498
+ # Equivalent to +{#properties}[name]+
499
+ def [](name) @properties[name]; end
566
500
 
567
- # Deletes the named property.
568
- #
569
- def delete_property(name)
570
- @properties.delete(name)
571
- end
501
+ # Equivalent to +{#properties}.delete(name)+
502
+ def delete_property(name) @properties.delete(name); end
572
503
 
573
- # Returns the instructions for this message.
574
- #
575
- def instructions
576
- @instructions
577
- end
578
-
579
- # Assigns instructions to this message.
580
- #
581
- def instructions=(instr)
582
- @instructions = instr
583
- end
584
-
585
- # Returns the annotations for this message.
586
- #
587
- def annotations
588
- @annotations
589
- end
504
+ # @return [Hash] Delivery instructions for this message.
505
+ attr_accessor :instructions
590
506
 
591
- # Assigns annotations to this message.
592
- #
593
- def annotations=(annotations)
594
- @annotations = annotations
595
- end
507
+ # @return [Hash] Delivery annotations for this message.
508
+ attr_accessor :annotations
596
509
 
597
- # Returns the body property of the message.
598
- #
599
- def body
600
- @body
601
- end
602
-
603
- # Assigns a new value to the body of the message.
604
- #
605
- def body=(body)
606
- @body = body
607
- end
510
+ # @return [Object] body of the message.
511
+ attr_accessor :body
608
512
 
609
513
  private
610
514
 
611
515
  def check(err) # :nodoc:
612
516
  if err < 0
613
- raise DataError, "[#{err}]: #{Cproton.pn_message_error(@data)}"
517
+ raise TypeError, "[#{err}]: #{Cproton.pn_message_error(@data)}"
614
518
  else
615
519
  return err
616
520
  end