qpid_messaging 0.16.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 (51) hide show
  1. data/LICENSE +234 -0
  2. data/README.rdoc +46 -0
  3. data/Rakefile +87 -0
  4. data/TODO +7 -0
  5. data/examples/client.rb +50 -0
  6. data/examples/drain.rb +111 -0
  7. data/examples/hello_world.rb +49 -0
  8. data/examples/map_receiver.rb +63 -0
  9. data/examples/map_sender.rb +52 -0
  10. data/examples/server.rb +51 -0
  11. data/examples/spout.rb +126 -0
  12. data/ext/cqpid/cqpid.cpp +9903 -0
  13. data/ext/cqpid/extconf.rb +73 -0
  14. data/features/closing_a_connection.feature +13 -0
  15. data/features/closing_a_session.feature +13 -0
  16. data/features/connecting_to_a_broker.feature +13 -0
  17. data/features/creating_a_receiver.feature +29 -0
  18. data/features/creating_a_sender.feature +25 -0
  19. data/features/creating_a_session.feature +12 -0
  20. data/features/getting_the_connections_authenticated_username.feature +8 -0
  21. data/features/receiving_a_message.feature +28 -0
  22. data/features/sending_a_message.feature +21 -0
  23. data/features/session_returns_its_connection.feature +12 -0
  24. data/features/sessions_have_names.feature +8 -0
  25. data/features/step_definitions/address_steps.rb +24 -0
  26. data/features/step_definitions/connection_steps.rb +93 -0
  27. data/features/step_definitions/receiver_steps.rb +61 -0
  28. data/features/step_definitions/sender_steps.rb +34 -0
  29. data/features/step_definitions/session_steps.rb +99 -0
  30. data/features/support/env.rb +22 -0
  31. data/lib/qpid_messaging.rb +30 -0
  32. data/lib/qpid_messaging/address.rb +187 -0
  33. data/lib/qpid_messaging/connection.rb +162 -0
  34. data/lib/qpid_messaging/duration.rb +95 -0
  35. data/lib/qpid_messaging/encoding.rb +61 -0
  36. data/lib/qpid_messaging/errors.rb +33 -0
  37. data/lib/qpid_messaging/message.rb +368 -0
  38. data/lib/qpid_messaging/receiver.rb +184 -0
  39. data/lib/qpid_messaging/sender.rb +152 -0
  40. data/lib/qpid_messaging/session.rb +269 -0
  41. data/lib/qpid_messaging/version.rb +33 -0
  42. data/spec/qpid/address_spec.rb +87 -0
  43. data/spec/qpid/connection_spec.rb +191 -0
  44. data/spec/qpid/duration_spec.rb +56 -0
  45. data/spec/qpid/encoding_spec.rb +63 -0
  46. data/spec/qpid/message_spec.rb +292 -0
  47. data/spec/qpid/receiver_spec.rb +170 -0
  48. data/spec/qpid/sender_spec.rb +135 -0
  49. data/spec/qpid/session_spec.rb +353 -0
  50. data/spec/spec_helper.rb +20 -0
  51. metadata +106 -0
@@ -0,0 +1,33 @@
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 #:nodoc:
21
+
22
+ NAME = "qpid_messaging"
23
+
24
+ module Version
25
+
26
+ NUMBERS = [MAJOR = 0,
27
+ MINOR = 16,
28
+ RELEASE = 0]
29
+ end
30
+
31
+ VERSION = Version::NUMBERS.join('.')
32
+
33
+ end
@@ -0,0 +1,87 @@
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
+ require 'spec_helper'
21
+
22
+ module Qpid
23
+
24
+ module Messaging
25
+
26
+ describe Address do
27
+
28
+ before(:each) do
29
+ @address = Qpid::Messaging::Address.new "my-name", "my-subject", :create => :always
30
+ end
31
+
32
+ it "stores the name, subject and options when created" do
33
+ name = @address.name
34
+ subject = @address.subject
35
+ create = @address.options["create"]
36
+
37
+ name.should == "my-name"
38
+ subject.should == "my-subject"
39
+ create.should == "always"
40
+ end
41
+
42
+ it "can update the name" do
43
+ @address.name = "new-name"
44
+
45
+ name = @address.name
46
+
47
+ name.should == "new-name"
48
+ end
49
+
50
+ it "can update the subject" do
51
+ @address.subject = "new-subject"
52
+
53
+ subject = @address.subject
54
+
55
+ subject.should == "new-subject"
56
+ end
57
+
58
+ it "can update the type" do
59
+ @address.address_type = "routed"
60
+
61
+ type = @address.address_type
62
+
63
+ type.should == "routed"
64
+ end
65
+
66
+ it "can update the options" do
67
+ @address.options[:create] = :never
68
+
69
+ create = @address.options["create"]
70
+
71
+ create.should == "always"
72
+ end
73
+
74
+ it "can return a string representation" do
75
+ address = Qpid::Messaging::Address.new "foo", "bar", :create => :always, :link => :durable
76
+ result = address.to_s
77
+
78
+ result.should =~ /foo\/bar/
79
+ result.should =~ /create:always/
80
+ result.should =~ /link:durable/
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,191 @@
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
+ require 'spec_helper'
21
+
22
+ module Qpid
23
+
24
+ module Messaging
25
+
26
+ describe Connection do
27
+
28
+ before(:each) do
29
+ @session_impl = double('Cqpid::Session')
30
+ @connection_impl = double('Cqpid::Connection')
31
+
32
+ @connection = Qpid::Messaging::Connection.new :impl => @connection_impl
33
+ end
34
+
35
+ it "accepts options on construction" do
36
+ expect {
37
+ connection = Qpid::Messaging::Connection.new :options => {:username => "foo"}
38
+
39
+ connection.options.should include("username")
40
+ }.should_not raise_error
41
+ end
42
+
43
+ it "returns the underlying implementation" do
44
+ impl = @connection.connection_impl
45
+
46
+ impl.should == @connection_impl
47
+ end
48
+
49
+ it "opens the connection" do
50
+ @connection_impl.should_receive(:open)
51
+
52
+ @connection.open
53
+ end
54
+
55
+ it "closes the connection" do
56
+ @connection_impl.should_receive(:close)
57
+
58
+ @connection.close
59
+ end
60
+
61
+ it "retrieves a session by name" do
62
+ @connection_impl.should_receive(:getSession).
63
+ with("farkle").
64
+ and_return(@session_impl)
65
+
66
+ session = @connection.session "farkle"
67
+
68
+ session.session_impl.should == @session_impl
69
+ end
70
+
71
+ it "raises an error when a session name is invalid" do
72
+ @connection_impl.should_receive(:getSession).
73
+ with("farkle").
74
+ and_raise(RuntimeError)
75
+
76
+ expect {
77
+ @connection.session "farkle"
78
+ }.to raise_error(SessionNameException)
79
+ end
80
+
81
+ ####################################################################
82
+ # test conditions for when a connection is not connected to a broker
83
+ ####################################################################
84
+ describe "when closed" do
85
+
86
+ before(:each) do
87
+ @connection_impl.should_receive(:isOpen).
88
+ and_return(false)
89
+ end
90
+
91
+ it "returns false when not connected to a broker" do
92
+ open = @connection.open?
93
+
94
+ open.should == false
95
+ end
96
+
97
+ it "should raise an error when creating a session on a closed connection" do
98
+ expect {
99
+ @connection.create_session
100
+ }.to raise_error(RuntimeError)
101
+ end
102
+
103
+ it "raises an error when creating a transactional session on a closed connection" do
104
+ expect {
105
+ @connection.create_session :transactional => true
106
+ }.to raise_error(RuntimeError)
107
+ end
108
+
109
+ it "raises an error when creating a named session on a closed connection" do
110
+ expect {
111
+ @connection.create_session :name => "test", :transactional => true
112
+ }.to raise_error(RuntimeError)
113
+ end
114
+
115
+ it "returns a null username when not connected" do
116
+ username = @connection.authenticated_username
117
+
118
+ username.should be_nil
119
+ end
120
+
121
+ end
122
+
123
+ #########################################################
124
+ # test conditions for when a connection must be connected
125
+ #########################################################
126
+ describe "when connected" do
127
+
128
+ before(:each) do
129
+ @connection_impl.should_receive(:isOpen).
130
+ and_return(true)
131
+ end
132
+
133
+ it "returns true when connected to a broker" do
134
+ open = @connection.open?
135
+
136
+ open.should == true
137
+ end
138
+
139
+ it "creates a session" do
140
+ @connection_impl.should_receive(:createSession).
141
+ and_return(@session_impl)
142
+
143
+ session = @connection.create_session
144
+
145
+ session.session_impl.should == @session_impl
146
+ end
147
+
148
+ it "creates a named session with a name when provided" do
149
+ @connection_impl.should_receive(:createSession).with("farkle").
150
+ and_return(@session_impl)
151
+
152
+ session = @connection.create_session :name => "farkle"
153
+
154
+ session.session_impl.should == @session_impl
155
+ end
156
+
157
+ it "creates a transactional session when specified" do
158
+ @connection_impl.should_receive(:createTransactionalSession).
159
+ and_return(@session_impl)
160
+
161
+ session = @connection.create_session :transactional => true
162
+
163
+ session.session_impl.should == @session_impl
164
+ end
165
+
166
+ it "creates a named transactional session when specified" do
167
+ @connection_impl.should_receive(:createTransactionalSession).
168
+ with("farkle").
169
+ and_return(@session_impl)
170
+
171
+ session = @connection.create_session :transactional => true, :name => "farkle"
172
+
173
+ session.session_impl.should == @session_impl
174
+ end
175
+
176
+ it "returns the authenticated username when connected" do
177
+ @connection_impl.should_receive(:getAuthenticatedUsername).
178
+ and_return("mcpierce")
179
+
180
+ username = @connection.authenticated_username
181
+
182
+ username.should == "mcpierce"
183
+ end
184
+
185
+ end
186
+
187
+ end
188
+
189
+ end
190
+
191
+ end
@@ -0,0 +1,56 @@
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
+ require 'spec_helper'
21
+
22
+ module Qpid
23
+
24
+ module Messaging
25
+
26
+ describe Duration do
27
+
28
+ before(:each) do
29
+ @duration = Qpid::Messaging::Duration::SECOND
30
+ end
31
+
32
+ it "returns the underlying implementation" do
33
+ impl = @duration.duration_impl
34
+
35
+ impl.should_not be_nil
36
+ end
37
+
38
+ it "can create a duration with a millisecond value" do
39
+ duration = Qpid::Messaging::Duration.new 500
40
+
41
+ milliseconds = duration.milliseconds
42
+
43
+ milliseconds.should == 500
44
+ end
45
+
46
+ it "returns the time in milliseconds" do
47
+ milliseconds = @duration.milliseconds
48
+
49
+ milliseconds.should == 1000
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,63 @@
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
+ require 'spec_helper'
21
+
22
+ module Qpid
23
+
24
+ module Messaging
25
+
26
+ describe "encoding" do
27
+ end
28
+
29
+ describe "decoding" do
30
+
31
+ before(:each) do
32
+ @message = Qpid::Messaging::Message.new
33
+ end
34
+
35
+ it "can decode a message's text content" do
36
+ @message.content = "This is an unencoded message."
37
+
38
+ content = Qpid::Messaging.decode @message
39
+
40
+ content.should == "This is an unencoded message."
41
+ end
42
+
43
+ it "can decode a message's list content" do
44
+ @message.content = ["this", "that"]
45
+
46
+ content = Qpid::Messaging.decode @message
47
+
48
+ content.should == ["this", "that"]
49
+ end
50
+
51
+ it "can decode a message's map content" do
52
+ @message.content = {"this" => "that"}
53
+
54
+ content = Qpid::Messaging.decode @message
55
+
56
+ content.should == {"this" => "that"}
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,292 @@
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
+ require 'spec_helper'
21
+
22
+ module Qpid
23
+
24
+ module Messaging
25
+
26
+ describe Message do
27
+
28
+ before(:each) do
29
+ @message = Qpid::Messaging::Message.new :content => "My content"
30
+ end
31
+
32
+ it "returns its implementation" do
33
+ impl = @message.message_impl
34
+
35
+ impl.class.should == Cqpid::Message
36
+ end
37
+
38
+ it "can set the reply to address" do
39
+ address = Qpid::Messaging::Address.new "my-queue", ""
40
+
41
+ @message.reply_to = address
42
+
43
+ reply_to = @message.reply_to
44
+
45
+ reply_to.name.should == address.name
46
+ end
47
+
48
+ it "should store the content when created" do
49
+ content = @message.content
50
+
51
+ content.should == "My content"
52
+ end
53
+
54
+ it "should properly encode a map when created" do
55
+ message = Qpid::Messaging::Message.new :content => {"foo" => "bar"}
56
+
57
+ content = message.content
58
+ content_type = message.content_type
59
+
60
+ content_type.should == "amqp/map"
61
+ content.class == Hash
62
+ content["foo"].should == "bar"
63
+ end
64
+
65
+ it "should properly encode a list when created" do
66
+ message = Qpid::Messaging::Message.new :content => ["foo", "bar"]
67
+
68
+ content = message.content
69
+ content_type = message.content_type
70
+
71
+ content_type.should == "amqp/list"
72
+ content.class == Array
73
+ content.should include("foo")
74
+ content.should include("bar")
75
+ end
76
+
77
+ it "should store the subject" do
78
+ @message.subject = "new-subject"
79
+
80
+ subject = @message.subject
81
+
82
+ subject.should == "new-subject"
83
+ end
84
+
85
+ it "should update the content type" do
86
+ @message.content_type = "amqp/audio"
87
+
88
+ content_type = @message.content_type
89
+
90
+ content_type.should == "amqp/audio"
91
+ end
92
+
93
+ it "should store the message id" do
94
+ @message.message_id = "foo"
95
+
96
+ id = @message.message_id
97
+
98
+ id.should == "foo"
99
+ end
100
+
101
+ it "should store the user id" do
102
+ @message.user_id = "foo"
103
+
104
+ id = @message.user_id
105
+
106
+ id.should == "foo"
107
+ end
108
+
109
+ it "should store the correlation id" do
110
+ @message.correlation_id = "message1"
111
+
112
+ id = @message.correlation_id
113
+
114
+ id.should == "message1"
115
+ end
116
+
117
+ it "should store the priority" do
118
+ @message.priority = 7
119
+
120
+ priority = @message.priority
121
+
122
+ priority.should == 7
123
+ end
124
+
125
+ it "should accept a Duration as the time to live" do
126
+ @message.ttl = Qpid::Messaging::Duration::SECOND
127
+
128
+ ttl = @message.ttl
129
+
130
+ ttl.milliseconds.should == Qpid::Messaging::Duration::SECOND.milliseconds
131
+ end
132
+
133
+ it "should accept an integer value as the time to live" do
134
+ @message.ttl = 15000
135
+
136
+ ttl = @message.ttl
137
+
138
+ ttl.milliseconds.should == 15000
139
+ end
140
+
141
+ it "should update the durable flag" do
142
+ @message.durable = true
143
+
144
+ durable = @message.durable
145
+
146
+ durable.should == true
147
+ end
148
+
149
+ it "should update the redelivered flag" do
150
+ @message.redelivered = true
151
+
152
+ redelivered = @message.redelivered
153
+
154
+ redelivered.should == true
155
+ end
156
+
157
+ it "should store a property" do
158
+ property = @message[:test_property]
159
+
160
+ property.should == nil
161
+
162
+ @message[:test_property] = "test_value1"
163
+
164
+ property = @message[:test_property]
165
+
166
+ property.should == "test_value1"
167
+ end
168
+
169
+ it "should convert a symbol property value to a string" do
170
+ @message[:test_property] = :test_value2
171
+
172
+ property = @message[:test_property]
173
+
174
+ property.should == "test_value2"
175
+ end
176
+
177
+ it "should convert a symbol property name to a string" do
178
+ @message[:test_property] = "test_value3"
179
+
180
+ property = @message["test_property"]
181
+
182
+ property.should == "test_value3"
183
+ end
184
+
185
+ it "should store text content" do
186
+ @message.content = "This is the content."
187
+
188
+ content = @message.content
189
+
190
+ content.should == "This is the content."
191
+ end
192
+
193
+ it "should store list content" do
194
+ list = ["foo", "bar"]
195
+
196
+ @message.content = list
197
+
198
+ content = @message.content
199
+ content_type = @message.content_type
200
+
201
+ content.should == list
202
+ content_type.should == "amqp/list"
203
+ end
204
+
205
+ it "should convert symbol list elements to strings" do
206
+ @message.content = [:farkle]
207
+
208
+ content = @message.content.first
209
+
210
+ content.should == "farkle"
211
+ end
212
+
213
+ it "should store map content" do
214
+ map = {"foo" => "bar"}
215
+
216
+ @message.content = map
217
+
218
+ content = @message.content
219
+ content_type = @message.content_type
220
+
221
+ content.should == map
222
+ content_type.should == "amqp/map"
223
+ end
224
+
225
+ it "should convert symbol map elements to strings" do
226
+ @message.content = {:first_name => :qpid}
227
+
228
+ content = @message.content["first_name"]
229
+
230
+ content.should == "qpid"
231
+ end
232
+
233
+ describe "with content from the underlying implementation" do
234
+
235
+ before(:each) do
236
+ @message_impl = double("Cqpid::Message")
237
+ @message = Qpid::Messaging::Message.new :impl => @message_impl
238
+ end
239
+
240
+ it "should return simple text content" do
241
+ @message_impl.should_receive(:getContent).
242
+ and_return("my content")
243
+ @message_impl.should_receive(:getContentType).
244
+ and_return("")
245
+
246
+ content = @message.content
247
+
248
+ content.should == "my content"
249
+ end
250
+
251
+ it "should decode a list" do
252
+ list = ["first", "second"]
253
+
254
+ @message_impl.should_receive(:getContent).
255
+ and_return(list)
256
+ @message_impl.should_receive(:getContentType).
257
+ twice.
258
+ and_return("amqp/list")
259
+ Qpid::Messaging.stub!(:decode).
260
+ with(@message, "amqp/list").
261
+ and_return(list)
262
+
263
+ content = @message.content
264
+
265
+ content.should == list
266
+ end
267
+
268
+ it "should decode a map" do
269
+ map = {"first" => "second"}
270
+
271
+ @message_impl.should_receive(:getContent).
272
+ and_return(map)
273
+ @message_impl.should_receive(:getContentType).
274
+ twice.
275
+ and_return("amqp/map")
276
+ Qpid::Messaging.stub!(:decode).
277
+ with(@message, "amqp/map").
278
+ and_return(map)
279
+
280
+ content = @message.content
281
+
282
+ content.should == map
283
+ end
284
+
285
+
286
+ end
287
+
288
+ end
289
+
290
+ end
291
+
292
+ end