qpid_messaging 0.20.2 → 0.22.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 (45) hide show
  1. data/ChangeLog +4 -0
  2. data/LICENSE +0 -4
  3. data/README.rdoc +15 -20
  4. data/TODO +10 -5
  5. data/ext/cqpid/cqpid.cpp +156 -40
  6. data/ext/cqpid/extconf.rb +10 -2
  7. data/lib/qpid_messaging.rb +56 -3
  8. data/lib/qpid_messaging/address.rb +51 -28
  9. data/lib/qpid_messaging/connection.rb +75 -46
  10. data/lib/qpid_messaging/duration.rb +49 -14
  11. data/lib/qpid_messaging/encoding.rb +5 -5
  12. data/lib/qpid_messaging/message.rb +61 -68
  13. data/lib/qpid_messaging/receiver.rb +62 -67
  14. data/lib/qpid_messaging/sender.rb +39 -56
  15. data/lib/qpid_messaging/session.rb +78 -81
  16. metadata +51 -61
  17. data/Rakefile +0 -137
  18. data/features/closing_a_connection.feature +0 -13
  19. data/features/closing_a_session.feature +0 -13
  20. data/features/connecting_to_a_broker.feature +0 -13
  21. data/features/creating_a_receiver.feature +0 -29
  22. data/features/creating_a_sender.feature +0 -25
  23. data/features/creating_a_session.feature +0 -12
  24. data/features/getting_the_connections_authenticated_username.feature +0 -8
  25. data/features/receiving_a_message.feature +0 -30
  26. data/features/sending_a_message.feature +0 -21
  27. data/features/session_returns_its_connection.feature +0 -12
  28. data/features/sessions_have_names.feature +0 -8
  29. data/features/step_definitions/address_steps.rb +0 -22
  30. data/features/step_definitions/connection_steps.rb +0 -93
  31. data/features/step_definitions/receiver_steps.rb +0 -69
  32. data/features/step_definitions/sender_steps.rb +0 -34
  33. data/features/step_definitions/session_steps.rb +0 -99
  34. data/features/support/env.rb +0 -22
  35. data/lib/qpid_messaging/errors.rb +0 -33
  36. data/lib/qpid_messaging/version.rb +0 -31
  37. data/spec/qpid_messaging/address_spec.rb +0 -87
  38. data/spec/qpid_messaging/connection_spec.rb +0 -191
  39. data/spec/qpid_messaging/duration_spec.rb +0 -56
  40. data/spec/qpid_messaging/encoding_spec.rb +0 -63
  41. data/spec/qpid_messaging/message_spec.rb +0 -305
  42. data/spec/qpid_messaging/receiver_spec.rb +0 -170
  43. data/spec/qpid_messaging/sender_spec.rb +0 -135
  44. data/spec/qpid_messaging/session_spec.rb +0 -353
  45. data/spec/spec_helper.rb +0 -20
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # Licensed to the Apache Software Foundation (ASF) under one
3
3
  # or more contributor license agreements. See the NOTICE file
4
4
  # distributed with this work for additional information
@@ -15,7 +15,7 @@
15
15
  # KIND, either express or implied. See the License for the
16
16
  # specific language governing permissions and limitations
17
17
  # under the License.
18
- #
18
+ #++
19
19
 
20
20
  module Qpid
21
21
 
@@ -24,13 +24,17 @@ module Qpid
24
24
  # Address represents an address to which messages can be sent or from
25
25
  # which they can be received.
26
26
  #
27
- # An Address can be described using the following pattern:
27
+ # == The +Address+ String
28
+ #
29
+ # An +Address+ can be described using the following pattern:
28
30
  #
29
31
  # <address> [ / <subject> ] ; [ { <key> : <value> , ... } ]
30
32
  #
31
33
  # where *address* is a simple name and *subject* is a subject or subject
32
34
  # pattern.
33
35
  #
36
+ # === Options
37
+ #
34
38
  # The options, enclosed in curly braces, are key:value pairs delimited by
35
39
  # a comma. The values can be nested maps also enclosed in curly braces.
36
40
  # Or they can be lists of values, where they are contained within square
@@ -40,44 +44,45 @@ module Qpid
40
44
  #
41
45
  # The following are the list of supported options:
42
46
  #
43
- # [:create]
47
+ # [create]
44
48
  # Indicates if the address should be created; values are *always*,
45
49
  # *never*, *sender* or *reciever*.
46
50
  #
47
- # [:assert]
51
+ # [assert]
48
52
  # Indicates whether or not to assert any specified node properties;
49
53
  # values are *always*, *never*, *sender* or *receiver*.
50
54
  #
51
- # [:delete]
55
+ # [delete]
52
56
  # Indicates whether or not to delete the addressed node when a sender
53
57
  # or receiver is cancelled; values are *always*, *never*, *sender* or
54
58
  # *receiver*.
55
59
  #
56
- # [:node]
60
+ # [node]
57
61
  # A nested map describing properties for the addressed node. Properties
58
62
  # are *type* (*topic* or *queue*), *durable* (a boolean), *x-declare*
59
- # (a nested map of amqp 0.10-specific options) and *x-bindings*. (nested
60
- # list which specifies a queue, exchange or a binding key and arguments.
63
+ # (a nested map of amqp 0.10-specific options) and *x-bindings* (nested
64
+ # list which specifies a queue, exchange or a binding key and arguments).
61
65
  #
62
- # [:link]
66
+ # [link]
63
67
  # A nested map through which properties of the link can be specified;
64
68
  # properties are *durable*, *reliability*, *x-declare*, *x-subscribe*
65
69
  # and *x-bindings*.
66
70
  #
67
- # [:mode]
71
+ # [mode]
68
72
  # (*For receivers only*) indicates whether the receiver should consume
69
73
  # or browse messages; values are *consume* (the default) and *browse*.
70
- #
71
74
  class Address
72
75
 
73
- # Creates a new +Address+ object from an address string.
76
+ # Creates a new +Address+ from an address string.
74
77
  #
75
- # ==== Options
78
+ # ==== Attributes
76
79
  #
77
- # * address - the address string
80
+ # * +address+ - the address string
78
81
  #
79
82
  # ==== Examples
80
83
  #
84
+ # # create a new address for a queue named "my-queue" that will
85
+ # # be created if it doesn't already exist
81
86
  # addr = Qpid::Messaging::Address.new "my-queue;{create:always}"
82
87
  #
83
88
  def initialize(address, address_impl = nil)
@@ -92,7 +97,10 @@ module Qpid
92
97
  #
93
98
  # ==== Examples
94
99
  #
95
- # puts "The address name is #{addr.name}."
100
+ # # display the name of the address
101
+ # addr = Qpid::Messaging::Address.new "foo;{create:always}"
102
+ # # outputs the word 'foo'
103
+ # puts addr.name
96
104
  #
97
105
  def name; @address_impl.getName; end
98
106
 
@@ -100,6 +108,9 @@ module Qpid
100
108
  #
101
109
  # ==== Examples
102
110
  #
111
+ # # create a new address with the name "my-queue"
112
+ # addr = Qpid::Messaging::Address.new "my-queue/my-subject;{create:always}"
113
+ # # changes the name to "my-new-queue"
103
114
  # addr.name = "my-new-queue"
104
115
  #
105
116
  def name=(name); @address_impl.setName name; end
@@ -108,7 +119,8 @@ module Qpid
108
119
  #
109
120
  # ==== Examples
110
121
  #
111
- # puts "The subject is #{addr.subject}."
122
+ # # creates a new address with the subject "bar"
123
+ # addr = Qpid::Messaging::Address.new "my-queue/bar;{create:always}"
112
124
  #
113
125
  def subject; @address_impl.getSubject; end
114
126
 
@@ -116,30 +128,40 @@ module Qpid
116
128
  #
117
129
  # ==== Examples
118
130
  #
119
- # addr.subject = "testing"
131
+ # # creates an address with the subject "example"
132
+ # addr = Qpid::Messaging::Address.new "my-queue/example;{create:always}"
133
+ # # changes the subject to "test"
134
+ # addr.subject = "test"
120
135
  #
121
136
  def subject=(subject); @address_impl.setSubject(subject); end
122
137
 
123
138
  # Returns the type for the +Address+.
124
- #
125
- # ==== Examples
126
- #
127
- # puts "The address is a #{address.address_type}."
128
- #
129
- #---
139
+ #--
130
140
  # We cannot use "type" since that clashes with the Ruby object.type
131
141
  # identifier.
142
+ #++
132
143
  def address_type; @address_impl.getType; end
133
144
 
134
145
  # Sets the type for the +Address+.
135
146
  #
136
147
  # The type of the address determines how +Sender+ and +Receiver+ objects
137
- # are constructed for it. If no type is specified then it will be
138
- # determined by querying the broker.
148
+ # are constructed for it. It also affects how a reply-to address is
149
+ # encoded.
150
+ #
151
+ # If no type is specified then it will be determined by querying the
152
+ # broker. Explicitly setting the type prevents this.
153
+ #
154
+ # Values are either *queue* or *topic*.
155
+ #
156
+ # ==== Options
157
+ #
158
+ # * +type+ - the address type
139
159
  #
140
- # ===== Options
160
+ # ==== Examples
141
161
  #
142
- # * type - the address type
162
+ # # creates an queue address
163
+ # addr = Qpid::Messaging::Address.new "my-queue;{create:always}"
164
+ # addr.address_type = "queue"
143
165
  #
144
166
  def address_type=(type); @address_impl.setType(type); end
145
167
 
@@ -153,6 +175,7 @@ module Qpid
153
175
  # ==== Examples
154
176
  #
155
177
  # addr.options = :create => :always
178
+ # addr.options = :create => :always, :delete => :always
156
179
  #
157
180
  def options=(options = {}); @address_impl.setOptions(convert_options(options)); end
158
181
 
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # Licensed to the Apache Software Foundation (ASF) under one
3
3
  # or more contributor license agreements. See the NOTICE file
4
4
  # distributed with this work for additional information
@@ -15,56 +15,59 @@
15
15
  # KIND, either express or implied. See the License for the
16
16
  # specific language governing permissions and limitations
17
17
  # under the License.
18
- #
18
+ #++
19
19
 
20
20
  module Qpid
21
21
 
22
22
  module Messaging
23
23
 
24
- # Establishes a connection to a remote endpoint.
24
+ # A +Connection+ represents a network connection to a remote endpoint.
25
25
  class Connection
26
26
 
27
27
  attr_reader :options # :nodoc:
28
28
 
29
- # Creates a connection object, but does not actually connect to
30
- # the specified location.
29
+ # Creates a connection object. Raises a MessagingError if an invalid
30
+ # connection option is used.
31
31
  #
32
- # ==== Options
32
+ # == Options
33
33
  #
34
- # :url - the URL for the broker (def. +"localhost"+)
35
- # :options - connection options (def. +{}+)
34
+ # * +:url+ - the URL for the broker
35
+ # * +:options+ - connection options
36
36
  #
37
- # ==== Controlling Reconnect Behavior
37
+ # == Controlling Reconnect Behavior
38
38
  #
39
39
  # The following connection options can be used to configure
40
40
  # the reconnection behavior for this connection.
41
41
  #
42
- # * :username
43
- # * :password
44
- # * :heartbeat
45
- # * :tcp_nodelay
46
- # * :sasl_mechanism
47
- # * :sasl_service
48
- # * :sasl_min_ssf
49
- # * :sasl_max_ssf
50
- # * :transport
51
- # * :reconnect - +true+ or +false+; indicates wehtehr to attempt reconnections
52
- # * :reconnect_timeout - the number of seconds to attempt reconnecting
53
- # * :reconnect_limit - the number of retries before reporting failure
54
- # * :reconnect_interval_min - initial delay, in seconds, before attempting a reconnection
55
- # * :reconnect_interval_max - number of seconds to wait before additional reconnect attempts
56
- # * :reconnect_interval - shorthand for setting both min and max values
57
- # * :reconnect_urls - a list of alternate URLs to use for reconnection attempts
58
- #
59
- # ==== Examples
60
- #
42
+ # * +:username+ - the authentication username
43
+ # * +:password+ - the authentication password
44
+ # * +:heartbeat+
45
+ # * +:tcp_nodelay+
46
+ # * +:sasl_mechanism+
47
+ # * +:sasl_service+
48
+ # * +:sasl_min_ssf+
49
+ # * +:sasl_max_ssf+
50
+ # * +:transport+
51
+ # * +:reconnect+ - indicates whether to attempt reconnections
52
+ # * +:reconnect_timeout+ - the number of seconds to attempt reconnecting
53
+ # * +:reconnect_limit+ - the number of retries before reporting failure
54
+ # * +:reconnect_interval_min+ - initial delay, in seconds, before attempting a reconnection
55
+ # * +:reconnect_interval_max+ - number of seconds to wait before additional reconnect attempts
56
+ # * +:reconnect_interval+ - shorthand for setting both min and max values
57
+ # * +:reconnect_urls+ - a list of alternate URLs to use for reconnection attempts
58
+ #
59
+ # == Examples
60
+ #
61
+ # # creates a connection to the broker running local *localhost*
61
62
  # conn = Qpid::Messaging::Connnection.new
63
+ # # creates a connection to *broker1.domain.com* on port *5672*
62
64
  # conn = Qpid::Messaging::Connection.new :url => "amqp:tcp:broker1.domain.com:5672"
65
+ # # creates a connection to localhost with the specified authentication credentials
63
66
  # conn = Qpid::Messaging::Connection.new :options => {:username => "login", :password => "password"}
64
67
  #
65
68
  def initialize(opts = {})
66
69
  @url = opts[:url] || "localhost"
67
- @options = convert_options(opts[:options] || {})
70
+ @options = Qpid::Messaging.stringify(opts[:options] || {})
68
71
  @connection_impl = opts[:impl] || Cqpid::Connection.new(@url, @options)
69
72
  end
70
73
 
@@ -74,8 +77,9 @@ module Qpid
74
77
 
75
78
  # Establishes the connection.
76
79
  #
77
- # ==== Examples
80
+ # == Examples
78
81
  #
82
+ # # open a connection if it's not already open
79
83
  # conn.open unless conn.open?
80
84
  #
81
85
  def open
@@ -84,25 +88,34 @@ module Qpid
84
88
 
85
89
  # Reports whether the connection is open.
86
90
  #
87
- # ==== Examples
91
+ # == Examples
88
92
  #
93
+ # # close the connection if it's not already closed
89
94
  # conn.close if conn.open?
90
95
  #
91
96
  def open?; true && !@connection_impl.nil? && @connection_impl.isOpen; end
92
97
 
93
98
  # Closes the connection.
99
+ #
100
+ # == Examples
101
+ #
102
+ # # close a connection
103
+ # conn.close
104
+ #
94
105
  def close; @connection_impl.close; end
95
106
 
96
107
  # Creates a new session.
97
108
  #
98
- # ==== Arguments
109
+ # == Arguments
99
110
  #
100
- # * :name - specifies the name for this session
101
- # * :transactional - if +true+ then a creates a transaction session (def. +false+)
111
+ # * +:name+ - specifies the name for this session
112
+ # * +:transactional+ - if +true+ then a creates a transaction session (def. +false+)
102
113
  #
103
- # ==== Examples
114
+ # == Examples
104
115
  #
116
+ # # create a session named 'session1'
105
117
  # session = conn.create_session :name => "session1"
118
+ # # create a transactional session
106
119
  # session = conn.create_session :transaction => true
107
120
  #
108
121
  def create_session(args = {})
@@ -119,26 +132,42 @@ module Qpid
119
132
  end
120
133
  end
121
134
 
122
- # Returns a session for the specified session name.
135
+ # Returns a Session with the given name. Raises an exception if no
136
+ # session with the given name exists.
137
+ #
138
+ # == Options
123
139
  #
124
- # ==== Examples
140
+ # * +name+ - the existing session's name
125
141
  #
142
+ # == Examples
143
+ #
144
+ # # retrieve a session named 'mysession' from the current connection
145
+ # name = "my-session"
146
+ # # if no such session exists then catchh the exception raised
126
147
  # begin
127
- # session = conn.session "mysession"
128
- # rescue SessionNameException => error
129
- # puts "No such session."
148
+ # session = conn.session name
149
+ # rescue MessagingException => error
150
+ # puts "No such session: #{name}."
130
151
  # end
131
152
  #
132
153
  def session name
133
- begin
134
- session_impl = @connection_impl.getSession name
135
- Qpid::Messaging::Session.new self, session_impl if session_impl
136
- rescue
137
- raise Qpid::Messaging::SessionNameException.new "No such session: #{name}"
138
- end
154
+ session_impl = @connection_impl.getSession name
155
+ Qpid::Messaging::Session.new self, session_impl if session_impl
139
156
  end
140
157
 
141
158
  # Returns the username used to authenticate with the connection.
159
+ #
160
+ # If the connection did not user authentication credentials, then the
161
+ # username returned is "anonymous".
162
+ #
163
+ # == Examples
164
+ #
165
+ # # create a new connection for user "qpiduser"
166
+ # conn = Qpid::Messaging::Connection.new :username => "qpiduser"
167
+ # conn.open
168
+ # # displays the authenticate username
169
+ # puts "Connected as #{conn.authenticated_username}" # should say 'qpiduser'
170
+ #
142
171
  def authenticated_username; @connection_impl.getAuthenticatedUsername if open?; end
143
172
 
144
173
  private
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # Licensed to the Apache Software Foundation (ASF) under one
3
3
  # or more contributor license agreements. See the NOTICE file
4
4
  # distributed with this work for additional information
@@ -15,7 +15,7 @@
15
15
  # KIND, either express or implied. See the License for the
16
16
  # specific language governing permissions and limitations
17
17
  # under the License.
18
- #
18
+ #++
19
19
 
20
20
  module Qpid
21
21
 
@@ -23,19 +23,21 @@ module Qpid
23
23
 
24
24
  # A Duration represents a period of time in milliseconds
25
25
  #
26
- # It defines the following named values as symbols:
26
+ # == Named Durations
27
+ #
28
+ # The following named +Durations+ are available as symbols:
27
29
  #
28
- # [:FOREVER]
30
+ # [FOREVER]
29
31
  # The maximum integer value for the platform. Effectively this will wait
30
32
  # forever.
31
33
  #
32
- # [:IMMEDIATE]
34
+ # [IMMEDIATE]
33
35
  # An alias for 0 milliseconds.
34
36
  #
35
- # [:SECOND]
37
+ # [SECOND]
36
38
  # An alias for 1,000 milliseconds.
37
39
  #
38
- # [:MINUTE]
40
+ # [MINUTE]
39
41
  # And alias for 60,000 millisecons.
40
42
  #
41
43
  class Duration
@@ -44,12 +46,13 @@ module Qpid
44
46
  #
45
47
  # ==== Options
46
48
  #
47
- # * length - The duration in milliseconds.
49
+ # * +length+ - The duration in +milliseconds+.
48
50
  #
49
51
  # ==== Examples
50
52
  #
51
- # # Wait up to 10 seconds for an incoming message
52
- # receiver.get Qpid::Messaging::Duration.new 10000
53
+ # # creates a duration of 15 seconds
54
+ # # REMEMBER: Duration deals in milliseconds
55
+ # delay = Qpid::Messaging::Duration.new 15000
53
56
  #
54
57
  def initialize length
55
58
  @duration_impl = Cqpid::Duration.new length
@@ -59,18 +62,50 @@ module Qpid
59
62
  @duration_impl
60
63
  end
61
64
 
62
- # Returns the period of time in milliseconds
65
+ # Returns the period of time in +milliseconds+.
63
66
  #
64
67
  # ==== Examples
65
68
  #
66
- # duration = Qpid::Messaging::Duration.new :length => 5000
67
- # puts "Waiting #{duration.milliseconds} ms for a message."
68
- # msg = receiver.fetch duration
69
+ # # doubling growth in waiting for messages in a loop
70
+ # do loop
71
+ # set the base duration waiting length
72
+ # timeout = Qpid::Messaging::Duration::SECOND
73
+ # msg = nil
74
+ # # loop until we receive a message
75
+ # while msg.nil?
76
+ # puts "Waiting #{timeout.milliseconds}ms"
77
+ # msg = recv.get timeout
78
+ # # if nothing was received, double the duration
79
+ # if msg.nil?
80
+ # # double out timeout
81
+ # timeout = timeout * 2
82
+ # else
83
+ # # do something with the message
84
+ # puts "Received: #{msg.content}"
85
+ # end
86
+ # end
87
+ # end
69
88
  #
70
89
  def milliseconds
71
90
  @duration_impl.getMilliseconds
72
91
  end
73
92
 
93
+ # Multiplies the duration of the +Duration+ and returns a new instance.
94
+ #
95
+ # Raises exceptions on a negative factor. Returns
96
+ # Qpid::Messaging::Duration::IMMEDIATE when the factor is 0.
97
+ #
98
+ # ==== Examples
99
+ #
100
+ # # return a duration that is 2 minutes (120,000 ms)
101
+ # twominutes = Qpid::Messaging::Duration::MINUTE * 2
102
+ #
103
+ def *(factor)
104
+ raise TypeError.new "Factors must be non-zero positive values" if factor < 0
105
+ return Qpid::Messaging::Duration::IMMEDIATE if factor.zero?
106
+ Qpid::Messaging::Duration.new((self.milliseconds * factor).floor)
107
+ end
108
+
74
109
  def self.add_item(key, value) # :nodoc:
75
110
  @hash ||= {}
76
111
  @hash[key] = Duration.new value