qpid_proton 0.9.0 → 0.10

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