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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codec/data.rb +912 -0
  3. data/lib/codec/mapping.rb +169 -0
  4. data/lib/{qpid_proton/tracker.rb → core/base_handler.rb} +4 -15
  5. data/lib/core/connection.rb +328 -0
  6. data/lib/core/delivery.rb +271 -0
  7. data/lib/core/disposition.rb +158 -0
  8. data/lib/core/endpoint.rb +140 -0
  9. data/lib/{qpid_proton → core}/exceptions.rb +43 -2
  10. data/lib/core/link.rb +387 -0
  11. data/lib/core/message.rb +633 -0
  12. data/lib/core/receiver.rb +95 -0
  13. data/lib/core/sasl.rb +94 -0
  14. data/lib/core/selectable.rb +130 -0
  15. data/lib/core/sender.rb +76 -0
  16. data/lib/core/session.rb +163 -0
  17. data/lib/core/ssl.rb +164 -0
  18. data/lib/{qpid_proton/version.rb → core/ssl_details.rb} +7 -6
  19. data/lib/core/ssl_domain.rb +156 -0
  20. data/lib/core/terminus.rb +218 -0
  21. data/lib/core/transport.rb +411 -0
  22. data/lib/core/url.rb +77 -0
  23. data/lib/event/collector.rb +148 -0
  24. data/lib/event/event.rb +318 -0
  25. data/lib/event/event_base.rb +91 -0
  26. data/lib/event/event_type.rb +71 -0
  27. data/lib/handler/acking.rb +70 -0
  28. data/lib/handler/c_adaptor.rb +47 -0
  29. data/lib/handler/c_flow_controller.rb +33 -0
  30. data/lib/handler/endpoint_state_handler.rb +217 -0
  31. data/lib/handler/incoming_message_handler.rb +74 -0
  32. data/lib/handler/messaging_handler.rb +218 -0
  33. data/lib/handler/outgoing_message_handler.rb +98 -0
  34. data/lib/handler/wrapped_handler.rb +76 -0
  35. data/lib/messenger/messenger.rb +702 -0
  36. data/lib/messenger/subscription.rb +37 -0
  37. data/lib/messenger/tracker.rb +38 -0
  38. data/lib/messenger/tracker_status.rb +69 -0
  39. data/lib/qpid_proton.rb +106 -16
  40. data/lib/reactor/acceptor.rb +41 -0
  41. data/lib/reactor/backoff.rb +41 -0
  42. data/lib/reactor/connector.rb +98 -0
  43. data/lib/reactor/container.rb +272 -0
  44. data/lib/reactor/global_overrides.rb +44 -0
  45. data/lib/reactor/link_option.rb +90 -0
  46. data/lib/reactor/reactor.rb +198 -0
  47. data/lib/reactor/session_per_connection.rb +45 -0
  48. data/lib/reactor/ssl_config.rb +41 -0
  49. data/lib/reactor/task.rb +39 -0
  50. data/lib/{qpid_proton/subscription.rb → reactor/urls.rb} +12 -13
  51. data/lib/{qpid_proton → types}/array.rb +28 -29
  52. data/lib/types/described.rb +63 -0
  53. data/lib/{qpid_proton → types}/hash.rb +4 -3
  54. data/lib/types/strings.rb +62 -0
  55. data/lib/util/class_wrapper.rb +54 -0
  56. data/lib/util/condition.rb +45 -0
  57. data/lib/util/constants.rb +85 -0
  58. data/lib/util/engine.rb +82 -0
  59. data/lib/util/error_handler.rb +127 -0
  60. data/lib/util/handler.rb +41 -0
  61. data/lib/util/reactor.rb +32 -0
  62. data/lib/util/swig_helper.rb +114 -0
  63. data/lib/util/timeout.rb +50 -0
  64. data/lib/util/uuid.rb +32 -0
  65. data/lib/util/version.rb +30 -0
  66. data/lib/util/wrapper.rb +124 -0
  67. metadata +67 -21
  68. data/ext/cproton/cproton.c +0 -22196
  69. data/lib/qpid_proton/data.rb +0 -788
  70. data/lib/qpid_proton/described.rb +0 -66
  71. data/lib/qpid_proton/exception_handling.rb +0 -127
  72. data/lib/qpid_proton/filters.rb +0 -67
  73. data/lib/qpid_proton/mapping.rb +0 -170
  74. data/lib/qpid_proton/message.rb +0 -621
  75. data/lib/qpid_proton/messenger.rb +0 -702
  76. data/lib/qpid_proton/selectable.rb +0 -126
  77. data/lib/qpid_proton/strings.rb +0 -65
  78. data/lib/qpid_proton/tracker_status.rb +0 -73
@@ -0,0 +1,169 @@
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::Codec
21
+
22
+ # Maps between Proton types and their Ruby native language counterparts.
23
+ #
24
+ # @private
25
+ class Mapping
26
+
27
+ attr_reader :code
28
+ attr_reader :put_method
29
+ attr_reader :get_method
30
+
31
+ # Creates a new mapping.
32
+ #
33
+ # ==== Arguments
34
+ #
35
+ # * code - the AMQP code for this type
36
+ # * name - the AMQP name for this type
37
+ # * klasses - the Ruby classes for this type
38
+ # * getter - overrides the get method for the type
39
+ def initialize(code, name, klasses = nil, getter = nil)
40
+
41
+ @debug = (name == "bool")
42
+
43
+ @code = code
44
+ @name = name
45
+
46
+ @@by_preferred ||= {}
47
+ @@by_code ||= {}
48
+ @@by_code["#{code}"] = self
49
+ @@by_name ||= {}
50
+ @@by_name[name] = self
51
+ @@by_class ||= {}
52
+
53
+ unless klasses.nil?
54
+ klasses.each do |klass|
55
+ raise "entry exists for #{klass}" if @@by_class.keys.include? klass
56
+ @@by_class[klass] = self unless klass.nil?
57
+ end
58
+ end
59
+
60
+ @put_method = (name + "=").intern
61
+
62
+ if getter.nil?
63
+ @get_method = name.intern
64
+ else
65
+ @get_method = getter.intern
66
+ end
67
+ end
68
+
69
+ def to_s; @name; end
70
+
71
+ def put(data, value)
72
+ data.__send__(@put_method, value)
73
+ end
74
+
75
+ def get(data)
76
+ data.__send__(@get_method)
77
+ end
78
+
79
+ def self.for_class(klass) # :nodoc:
80
+ @@by_class[klass]
81
+ end
82
+
83
+ def self.for_code(code)
84
+ @@by_code["#{code}"]
85
+ end
86
+
87
+ end
88
+
89
+ NULL = Mapping.new(Cproton::PN_NULL, "null", [NilClass], "nil?")
90
+ BOOL = Mapping.new(Cproton::PN_BOOL, "bool", [TrueClass, FalseClass], "bool")
91
+ UBYTE = Mapping.new(Cproton::PN_UBYTE, "ubyte")
92
+ BYTE = Mapping.new(Cproton::PN_BYTE, "byte")
93
+ USHORT = Mapping.new(Cproton::PN_USHORT, "ushort")
94
+ SHORT = Mapping.new(Cproton::PN_SHORT, "short")
95
+ UINT = Mapping.new(Cproton::PN_UINT, "uint")
96
+ INT = Mapping.new(Cproton::PN_INT, "int")
97
+ CHAR = Mapping.new(Cproton::PN_CHAR, "char")
98
+ ULONG = Mapping.new(Cproton::PN_ULONG, "ulong")
99
+ LONG = Mapping.new(Cproton::PN_LONG, "long", [Fixnum, Bignum])
100
+ TIMESTAMP = Mapping.new(Cproton::PN_TIMESTAMP, "timestamp", [Date, Time])
101
+ FLOAT = Mapping.new(Cproton::PN_FLOAT, "float")
102
+ DOUBLE = Mapping.new(Cproton::PN_DOUBLE, "double", [Float])
103
+ DECIMAL32 = Mapping.new(Cproton::PN_DECIMAL32, "decimal32")
104
+ DECIMAL64 = Mapping.new(Cproton::PN_DECIMAL64, "decimal64")
105
+ DECIMAL128 = Mapping.new(Cproton::PN_DECIMAL128, "decimal128")
106
+ UUID = Mapping.new(Cproton::PN_UUID, "uuid")
107
+ BINARY = Mapping.new(Cproton::PN_BINARY, "binary")
108
+ STRING = Mapping.new(Cproton::PN_STRING, "string", [String, Symbol,
109
+ Qpid::Proton::Types::UTFString,
110
+ Qpid::Proton::Types::BinaryString])
111
+
112
+ # @private
113
+ class << STRING
114
+ def put(data, value)
115
+ # if we have a symbol then convert it to a string
116
+ value = value.to_s if value.is_a?(Symbol)
117
+
118
+ isutf = false
119
+
120
+ if value.is_a?(Qpid::Proton::Types::UTFString)
121
+ isutf = true
122
+ else
123
+ # For Ruby 1.8 we will just treat all strings as binary.
124
+ # For Ruby 1.9+ we can check the encoding first to see what it is
125
+ if RUBY_VERSION >= "1.9"
126
+ # If the string is ASCII-8BIT then treat is as binary. Otherwise,
127
+ # try to convert it to UTF-8 and, if successful, send as that.
128
+ if value.encoding != Encoding::ASCII_8BIT &&
129
+ value.encode(Encoding::UTF_8).valid_encoding?
130
+ isutf = true
131
+ end
132
+ end
133
+ end
134
+
135
+ data.string = value if isutf
136
+ data.binary = value if !isutf
137
+
138
+ end
139
+ end
140
+
141
+ SYMBOL = Mapping.new(Cproton::PN_SYMBOL, "symbol")
142
+ DESCRIBED = Mapping.new(Cproton::PN_DESCRIBED, "described", [Qpid::Proton::Types::Described], "get_described")
143
+ ARRAY = Mapping.new(Cproton::PN_ARRAY, "array", nil, "get_array")
144
+ LIST = Mapping.new(Cproton::PN_LIST, "list", [::Array], "get_array")
145
+ MAP = Mapping.new(Cproton::PN_MAP, "map", [::Hash], "get_map")
146
+
147
+ # @private
148
+ class << MAP
149
+ def put(data, map, options = {})
150
+ data.put_map
151
+ data.enter
152
+ map.each_pair do |key, value|
153
+ if options[:keys] == :SYMBOL
154
+ SYMBOL.put(data, key)
155
+ else
156
+ Mapping.for_class(key.class).put(data, key)
157
+ end
158
+
159
+ if value.nil?
160
+ data.null
161
+ else
162
+ Mapping.for_class(value.class).put(data, value)
163
+ end
164
+ end
165
+ data.exit
166
+ end
167
+ end
168
+
169
+ end
@@ -17,24 +17,13 @@
17
17
  # under the License.
18
18
  #++
19
19
 
20
- module Qpid # :nodoc:
20
+ module Qpid::Proton
21
21
 
22
- module Proton # :nodoc:
22
+ class BaseHandler
23
23
 
24
- # A +Tracker+ is used to track the disposition of a +Message+.
24
+ # Override to process unhandled events.
25
25
  #
26
- class Tracker
27
-
28
- CUMULATIVE = Cproton::PN_CUMULATIVE
29
-
30
- def initialize(impl) # :nodoc:
31
- @impl = impl
32
- end
33
-
34
- def impl # :nodoc:
35
- @impl
36
- end
37
-
26
+ def on_unhandled(method, *args)
38
27
  end
39
28
 
40
29
  end
@@ -0,0 +1,328 @@
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
21
+
22
+ # A Connection option has at most one Qpid::Proton::Transport instance.
23
+ #
24
+ class Connection < Endpoint
25
+
26
+ # @private
27
+ include Util::SwigHelper
28
+
29
+ # @private
30
+ PROTON_METHOD_PREFIX = "pn_connection"
31
+
32
+ # @!attribute hostname
33
+ #
34
+ # @return [String] The AMQP hostname for the connection.
35
+ #
36
+ proton_accessor :hostname
37
+
38
+ # @private
39
+ proton_reader :attachments
40
+
41
+ attr_accessor :overrides
42
+ attr_accessor :session_policy
43
+
44
+ # @private
45
+ include Util::Wrapper
46
+
47
+ # @private
48
+ def self.wrap(impl)
49
+ return nil if impl.nil?
50
+
51
+ self.fetch_instance(impl, :pn_connection_attachments) || Connection.new(impl)
52
+ end
53
+
54
+ # Constructs a new instance of Connection.
55
+ #
56
+ # You do *not* need to provide the underlying C struct, as this is
57
+ # automatically generated as needed. The argument is a convenience
58
+ # for returning existing Connection objects.
59
+ #
60
+ # @param impl [pn_connection_t] The pn_connection_t struct.
61
+ #
62
+ def initialize(impl = Cproton.pn_connection)
63
+ super()
64
+ @impl = impl
65
+ @offered_capabilities = nil
66
+ @desired_capabilities = nil
67
+ @properties = nil
68
+ @overrides = nil
69
+ @collector = nil
70
+ @session_policy = nil
71
+ self.class.store_instance(self, :pn_connection_attachments)
72
+ end
73
+
74
+ def overrides?
75
+ !@overrides.nil?
76
+ end
77
+
78
+ def session_policy?
79
+ !@session_policy.nil?
80
+ end
81
+
82
+ # This method is used when working within the context of an event.
83
+ #
84
+ # @return [Connection] The connection itself.
85
+ #
86
+ def connection
87
+ self
88
+ end
89
+
90
+ # The Transport to which this connection is bound.
91
+ #
92
+ # @return [Transport] The transport, or nil if the Connection is unbound.
93
+ #
94
+ def transport
95
+ Transport.wrap(Cproton.pn_connection_transport(@impl))
96
+ end
97
+
98
+ # Associates the connection with an event collector.
99
+ #
100
+ # By doing this, key changes in the endpoint's state are reported to
101
+ # the connector via Event objects that can be inspected and processed.
102
+ #
103
+ # Note that, by registering a collector, the user is requesting that an
104
+ # indefinite number of events be queued up on its behalf. This means
105
+ # that, unless the application eventual processes these events, the
106
+ # storage requirements for keeping them will grow without bound. So be
107
+ # careful and do not register a collector with a connection unless the
108
+ # application will process the events.
109
+ #
110
+ # @param collector [Event::Collector] The event collector.
111
+ #
112
+ def collect(collector)
113
+ if collector.nil?
114
+ Cproton.pn_connection_collect(@impl, nil)
115
+ else
116
+ Cproton.pn_connection_collect(@impl, collector.impl)
117
+ end
118
+ @collector = collector
119
+ end
120
+
121
+ # Get the AMQP container name advertised by the remote connection
122
+ # endpoint.
123
+ #
124
+ # This will return nil until the REMOTE_ACTIVE state is reached.
125
+ #
126
+ # Any non-nil container returned by this operation will be valid
127
+ # until the connection is unbound from a transport, or freed,
128
+ # whichever happens sooner.
129
+ #
130
+ # @return [String] The remote connection's AMQP container name.
131
+ #
132
+ # @see #container
133
+ #
134
+ def remote_container
135
+ Cproton.pn_connection_remote_container(@impl)
136
+ end
137
+
138
+ def container=(name)
139
+ Cproton.pn_connection_set_container(@impl, name)
140
+ end
141
+
142
+ def container
143
+ Cproton.pn_connection_get_container(@impl)
144
+ end
145
+
146
+ # Get the AMQP hostname set by the remote connection endpoint.
147
+ #
148
+ # This will return nil until the #REMOTE_ACTIVE state is
149
+ # reached.
150
+ #
151
+ # @return [String] The remote connection's AMQP hostname.
152
+ #
153
+ # @see #hostname
154
+ #
155
+ def remote_hostname
156
+ Cproton.pn_connection_remote_hostname(@impl)
157
+ end
158
+
159
+ # Get the AMQP offered capabilities suppolied by the remote connection
160
+ # endpoint.
161
+ #
162
+ # This object returned is valid until the connection is freed. The Data
163
+ # object will be empty until the remote connection is opened, as
164
+ # indicated by the #REMOTE_ACTIVE flag.
165
+ #
166
+ # @return [Data] The offered capabilities.
167
+ #
168
+ def remote_offered_capabilities
169
+ data_to_object(Cproton.pn_connection_remote_offered_capabilities(@impl))
170
+ end
171
+
172
+ # Get the AMQP desired capabilities supplied by the remote connection
173
+ # endpoint.
174
+ #
175
+ # The object returned is valid until the connection is freed. The Data
176
+ # object will be empty until the remote connection is opened, as
177
+ # indicated by the #REMOTE_ACTIVE flag.
178
+ #
179
+ # @return [Data] The desired capabilities.
180
+ #
181
+ def remote_desired_capabilities
182
+ data_to_object(Cproton.pn_connection_remote_desired_capabilities(@impl))
183
+ end
184
+
185
+ # Get the AMQP connection properties supplie by the remote connection
186
+ # endpoint.
187
+ #
188
+ # The object returned is valid until the connection is freed. The Data
189
+ # object will be empty until the remote connection is opened, as
190
+ # indicated by the #REMOTE_ACTIVE flag.
191
+ #
192
+ # @return [Data] The remote properties.
193
+ #
194
+ def remote_properties
195
+ data_to_object(Cproton.pn_connection_remote_properites(@impl))
196
+ end
197
+
198
+ # Opens the connection.
199
+ #
200
+ def open
201
+ object_to_data(@offered_capabilities,
202
+ Cproton.pn_connection_offered_capabilities(@impl))
203
+ object_to_data(@desired_capabilities,
204
+ Cproton.pn_connection_desired_capabilities(@impl))
205
+ object_to_data(@properties,
206
+ Cproton.pn_connection_properties(@impl))
207
+ Cproton.pn_connection_open(@impl)
208
+ end
209
+
210
+ # Closes the connection.
211
+ #
212
+ # Once this operation has completed, the #LOCAL_CLOSED state flag will be
213
+ # set.
214
+ #
215
+ def close
216
+ self._update_condition
217
+ Cproton.pn_connection_close(@impl)
218
+ end
219
+
220
+ # Gets the endpoint current state flags
221
+ #
222
+ # @see Endpoint#LOCAL_UNINIT
223
+ # @see Endpoint#LOCAL_ACTIVE
224
+ # @see Endpoint#LOCAL_CLOSED
225
+ # @see Endpoint#LOCAL_MASK
226
+ #
227
+ # @return [Fixnum] The state flags.
228
+ #
229
+ def state
230
+ Cproton.pn_connection_state(@impl)
231
+ end
232
+
233
+ # Returns the session for this connection.
234
+ #
235
+ # @return [Session] The session.
236
+ #
237
+ def session
238
+ @session ||= Session.wrap(Cproton.pn_session(@impl))
239
+ end
240
+
241
+ # Returns the first session from the connection that matches the specified
242
+ # state mask.
243
+ #
244
+ # Examines the state of each session owned by the connection, and returns
245
+ # the first session that matches the given state mask. If the state mask
246
+ # contains *both* local and remote flags, then an exact match against
247
+ # those flags is performed. If the state mask contains only local *or*
248
+ # remote flags, then a match occurs if a*any* of the local or remote flags
249
+ # are set, respectively.
250
+ #
251
+ # @param mask [Fixnum] The state mask to be matched.
252
+ #
253
+ # @return [Session] The first matching session, or nil if none matched.
254
+ #
255
+ # @see Endpoint#LOCAL_UNINIT
256
+ # @see Endpoint#LOCAL_ACTIVE
257
+ # @see Endpoint#LOCAL_CLOSED
258
+ # @see Endpoint#REMOTE_UNINIT
259
+ # @see Endpoint#REMOTE_ACTIVE
260
+ # @see Endpoint#REMOTE_CLOSED
261
+ #
262
+ def session_head(mask)
263
+ Session.wrap(Cproton.pn_session_header(@impl, mask))
264
+ end
265
+
266
+ # Returns the first link that matches the given state mask.
267
+ #
268
+ # Examines the state of each link owned by the connection and returns the
269
+ # first that matches the given state mask. If the state mask contains
270
+ # *both* local and remote flags, then an exact match against those flags
271
+ # is performed. If the state mask contains *only* local or remote flags,
272
+ # then a match occurs if *any* of the local ore remote flags are set,
273
+ # respectively.
274
+ #
275
+ # @param mask [Fixnum] The state mask to be matched.
276
+ #
277
+ # @return [Link] The first matching link, or nil if none matched.
278
+ #
279
+ # @see Endpoint#LOCAL_UNINIT
280
+ # @see Endpoint#LOCAL_ACTIVE
281
+ # @see Endpoint#LOCAL_CLOSED
282
+ # @see Endpoint#REMOTE_UNINIT
283
+ # @see Endpoint#REMOTE_ACTIVE
284
+ # @see Endpoint#REMOTE_CLOSED
285
+ #
286
+ def link_head(mask)
287
+ Link.wrap(Cproton.pn_link_head(@impl, mask))
288
+ end
289
+
290
+ # Extracts the first delivery on the connection that has pending
291
+ # operations.
292
+ #
293
+ # A readable delivery indicates message data is waiting to be read. A
294
+ # A writable delivery indcates that message data may be sent. An updated
295
+ # delivery indicates that the delivery's disposition has changed.
296
+ #
297
+ # A delivery will never be *both* readable and writable, but it may be
298
+ # both readable or writable and updated.
299
+ #
300
+ # @return [Delivery] The delivery, or nil if none are available.
301
+ #
302
+ # @see Delivery#next
303
+ #
304
+ def work_head
305
+ Delivery.wrap(Cproton.pn_work_head(@impl))
306
+ end
307
+
308
+ # Returns the code for a connection error.
309
+ #
310
+ # @return [Fixnum] The error code.
311
+ #
312
+ def error
313
+ Cproton.pn_error_code(Cproton.pn_connection_error(@impl))
314
+ end
315
+
316
+ # @private
317
+ def _local_condition
318
+ Cproton.pn_connection_condition(@impl)
319
+ end
320
+
321
+ # @private
322
+ def _remote_condition
323
+ Cproton.pn_connection_remote_condition(@impl)
324
+ end
325
+
326
+ end
327
+
328
+ end