amqp 0.7.1 → 0.7.2
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.
- data/.gitignore +6 -1
- data/.travis.yml +9 -0
- data/CHANGELOG +7 -0
- data/Gemfile +16 -5
- data/Rakefile +6 -0
- data/amqp.gemspec +2 -12
- data/bin/set_test_suite_realms_up.sh +2 -16
- data/examples/automatic_binding_for_default_direct_exchange.rb +5 -5
- data/examples/default_channel.rb +19 -0
- data/examples/immediately_bind_a_server_named_queue.rb +38 -0
- data/examples/issues/issue_75.rb +21 -0
- data/gemfiles/eventmachine-pre +24 -0
- data/lib/amqp/channel.rb +52 -7
- data/lib/amqp/client.rb +76 -9
- data/lib/amqp/connection.rb +6 -1
- data/lib/amqp/queue.rb +15 -4
- data/lib/amqp/version.rb +1 -1
- data/lib/mq.rb +1 -2
- data/spec/integration/authentication_spec.rb +18 -16
- data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +7 -5
- data/spec/integration/channel_close_spec.rb +1 -1
- data/spec/integration/exchange_declaration_spec.rb +54 -7
- data/spec/integration/queue_declaration_spec.rb +18 -15
- data/spec/integration/queue_exclusivity_spec.rb +14 -12
- data/spec/integration/reply_queue_communication_spec.rb +2 -2
- data/spec/integration/store_and_forward_spec.rb +3 -3
- data/spec/integration/topic_subscription_spec.rb +1 -2
- data/spec/integration/workload_distribution_spec.rb +1 -2
- data/spec/spec_helper.rb +7 -2
- data/spec/unit/amqp/basic_spec.rb +1 -1
- data/spec/unit/amqp/client_spec.rb +102 -0
- data/spec/unit/amqp/connection_spec.rb +4 -2
- metadata +73 -13
- data/bin/jenkins.sh +0 -25
data/lib/amqp/connection.rb
CHANGED
@@ -81,6 +81,9 @@ module AMQP
|
|
81
81
|
def self.start *args, &blk
|
82
82
|
EM.run {
|
83
83
|
@conn ||= connect *args
|
84
|
+
@conn.callback { AMQP.channel = AMQP::Channel.new(@conn) }
|
85
|
+
|
86
|
+
# callback passed to .start must come last
|
84
87
|
@conn.callback(&blk) if blk
|
85
88
|
@conn
|
86
89
|
}
|
@@ -91,11 +94,13 @@ module AMQP
|
|
91
94
|
end
|
92
95
|
|
93
96
|
def self.stop
|
94
|
-
if @conn
|
97
|
+
if @conn && !@closing
|
95
98
|
@closing = true
|
96
99
|
EM.next_tick do
|
100
|
+
AMQP.channel.close
|
97
101
|
@conn.close {
|
98
102
|
yield if block_given?
|
103
|
+
@channel = nil
|
99
104
|
@conn = nil
|
100
105
|
@closing = false
|
101
106
|
}
|
data/lib/amqp/queue.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module AMQP
|
4
4
|
class Queue
|
5
5
|
def self.add_default_options(name, opts, block)
|
6
|
-
{ :queue => name, :nowait => block.nil? }.merge(opts)
|
6
|
+
{ :queue => name, :nowait => (block.nil? && !name.empty?) }.merge(opts)
|
7
7
|
end
|
8
8
|
|
9
9
|
# Queues store and forward messages. Queues can be configured in the server
|
@@ -66,11 +66,19 @@ module AMQP
|
|
66
66
|
# method it will raise a channel or connection exception.
|
67
67
|
#
|
68
68
|
def initialize(mq, name, opts = {}, &block)
|
69
|
-
|
70
|
-
|
69
|
+
raise ArgumentError, "queue name must not be nil. Use '' (empty string) for server-named queues." if name.nil?
|
70
|
+
|
71
|
+
@mq = mq
|
72
|
+
@opts = self.class.add_default_options(name, opts, block)
|
71
73
|
@bindings ||= {}
|
72
|
-
@name = name unless name.empty?
|
73
74
|
@status = @opts[:nowait] ? :unknown : :unfinished
|
75
|
+
|
76
|
+
if name.empty?
|
77
|
+
@mq.queues_awaiting_declare_ok.push(self)
|
78
|
+
else
|
79
|
+
@name = name
|
80
|
+
end
|
81
|
+
|
74
82
|
@mq.callback {
|
75
83
|
@mq.send Protocol::Queue::Declare.new(@opts)
|
76
84
|
}
|
@@ -466,6 +474,9 @@ module AMQP
|
|
466
474
|
end
|
467
475
|
|
468
476
|
def reset
|
477
|
+
unsubscribe
|
478
|
+
cancelled
|
479
|
+
|
469
480
|
@deferred_status = nil
|
470
481
|
initialize @mq, @name, @opts
|
471
482
|
|
data/lib/amqp/version.rb
CHANGED
data/lib/mq.rb
CHANGED
@@ -20,8 +20,7 @@ MQ should have been called Channel all along). No other AMQP client library we k
|
|
20
20
|
of invents it's own terminology when it comes to AMQP entities, and amqp gem shouldn't,
|
21
21
|
too.
|
22
22
|
|
23
|
-
|
24
|
-
https://github.com/ruby-amqp/amqp/issues
|
23
|
+
Learn more at http://bit.ly/amqp-gem-080-migration.
|
25
24
|
|
26
25
|
Thank you for understanding. AMQP gem maintainers team.
|
27
26
|
|
@@ -7,20 +7,22 @@ describe "Authentication attempt" do
|
|
7
7
|
# Environment
|
8
8
|
#
|
9
9
|
|
10
|
-
include
|
11
|
-
|
12
|
-
|
10
|
+
include EventedSpec::EMSpec
|
11
|
+
default_timeout 1
|
13
12
|
em_before { AMQP.cleanup_state }
|
14
13
|
em_after { AMQP.cleanup_state }
|
15
14
|
|
16
|
-
describe "with default connection parameters" do
|
17
15
|
|
16
|
+
# Tests below use AMQP_OPTS for settings, if you really need to modify them,
|
17
|
+
# create amqp.yml file with new settings. (see spec/spec_helper)
|
18
|
+
|
19
|
+
# Also it assumes that guest/guest has access to /
|
20
|
+
describe "with default connection parameters" do
|
18
21
|
#
|
19
22
|
# Examples
|
20
23
|
#
|
21
24
|
|
22
|
-
|
23
|
-
# access to / (default vhost)
|
25
|
+
|
24
26
|
context "when guest/guest has access to /" do
|
25
27
|
after :all do
|
26
28
|
done
|
@@ -44,16 +46,16 @@ describe "Authentication attempt" do
|
|
44
46
|
# Examples
|
45
47
|
#
|
46
48
|
|
47
|
-
# assuming
|
48
|
-
#
|
49
|
-
context "when
|
49
|
+
# assuming AMQP_OPTS are correct
|
50
|
+
# and SchadenFreude with random password doesn't have any access
|
51
|
+
context "when #{AMQP_OPTS[:username]} has access to #{AMQP_OPTS[:vhost]}" do
|
50
52
|
after :all do
|
51
53
|
done
|
52
54
|
end
|
53
55
|
|
54
56
|
context "and provided credentials are correct" do
|
55
57
|
it "succeeds" do
|
56
|
-
connection = AMQP.connect :username =>
|
58
|
+
connection = AMQP.connect :username => AMQP_OPTS[:username], :password => AMQP_OPTS[:password], :vhost => AMQP_OPTS[:vhost]
|
57
59
|
|
58
60
|
done(0.3) {
|
59
61
|
connection.should be_connected
|
@@ -64,7 +66,7 @@ describe "Authentication attempt" do
|
|
64
66
|
|
65
67
|
context "and provided credentials ARE INCORRECT" do
|
66
68
|
it "fails" do
|
67
|
-
connection = AMQP.connect :user => "
|
69
|
+
connection = AMQP.connect :user => "SchadenFreude", :pass => Time.now.to_i.to_s, :vhost => AMQP_OPTS[:vhost]
|
68
70
|
|
69
71
|
done(0.5) {
|
70
72
|
connection.should_not be_connected
|
@@ -81,16 +83,16 @@ describe "Authentication attempt" do
|
|
81
83
|
# Examples
|
82
84
|
#
|
83
85
|
|
84
|
-
# assuming
|
85
|
-
#
|
86
|
-
context "when
|
86
|
+
# assuming AMQP_OPTS are correct
|
87
|
+
# and SchadenFreude with random password doesn't have any access
|
88
|
+
context "when #{AMQP_OPTS[:username]} has access to #{AMQP_OPTS[:vhost]}" do
|
87
89
|
after :all do
|
88
90
|
done
|
89
91
|
end
|
90
92
|
|
91
93
|
context "and provided credentials are correct" do
|
92
94
|
it "succeeds" do
|
93
|
-
connection = AMQP.connect "amqp
|
95
|
+
connection = AMQP.connect "amqp://#{AMQP_OPTS[:username]}:#{AMQP_OPTS[:password]}@localhost/#{URI::escape AMQP_OPTS[:vhost], /[^-_.!~*'()a-zA-Z\d]/n}"
|
94
96
|
|
95
97
|
done(0.3) {
|
96
98
|
connection.should be_connected
|
@@ -101,7 +103,7 @@ describe "Authentication attempt" do
|
|
101
103
|
|
102
104
|
context "and provided credentials ARE INCORRECT" do
|
103
105
|
it "succeeds" do
|
104
|
-
connection = AMQP.connect "amqp://
|
106
|
+
connection = AMQP.connect "amqp://schadenfreude:#{Time.now.to_i}@localhost"
|
105
107
|
|
106
108
|
done(0.5) {
|
107
109
|
connection.should_not be_connected
|
@@ -8,7 +8,7 @@ describe "Queue that was bound to default direct exchange thanks to Automatic Mo
|
|
8
8
|
# Environment
|
9
9
|
#
|
10
10
|
|
11
|
-
include
|
11
|
+
include EventedSpec::AMQPSpec
|
12
12
|
|
13
13
|
default_timeout 2
|
14
14
|
|
@@ -16,8 +16,8 @@ describe "Queue that was bound to default direct exchange thanks to Automatic Mo
|
|
16
16
|
@channel = AMQP::Channel.new
|
17
17
|
@channel.should be_open
|
18
18
|
|
19
|
-
@queue1 = @channel.queue("
|
20
|
-
@queue2 = @channel.queue("
|
19
|
+
@queue1 = @channel.queue("amqp-gem.automatic-binding.q1", :auto_delete => true)
|
20
|
+
@queue2 = @channel.queue("amqp-gem.automatic-binding.q2", :auto_delete => true)
|
21
21
|
|
22
22
|
# Rely on default direct exchange binding, see section 2.1.2.4 Automatic Mode in AMQP 0.9.1 spec.
|
23
23
|
@exchange = AMQP::Exchange.default(@channel)
|
@@ -48,14 +48,16 @@ describe "Queue that was bound to default direct exchange thanks to Automatic Mo
|
|
48
48
|
end
|
49
49
|
|
50
50
|
expected_number_of_messages.times do
|
51
|
-
@exchange.publish(dispatched_data, :routing_key => @queue1.name)
|
51
|
+
@exchange.publish(dispatched_data, :routing_key => @queue1.name)
|
52
52
|
end
|
53
53
|
|
54
54
|
4.times do
|
55
55
|
@exchange.publish("some white noise", :routing_key => "killa key")
|
56
56
|
end
|
57
57
|
|
58
|
-
|
58
|
+
delayed(0.2) { @queue2.delete }
|
59
|
+
|
60
|
+
done(0.35) {
|
59
61
|
number_of_received_messages.should == expected_number_of_messages
|
60
62
|
}
|
61
63
|
end # it
|
@@ -8,7 +8,7 @@ describe AMQP do
|
|
8
8
|
# Environment
|
9
9
|
#
|
10
10
|
|
11
|
-
include
|
11
|
+
include EventedSpec::AMQPSpec
|
12
12
|
|
13
13
|
default_timeout 10
|
14
14
|
|
@@ -26,6 +26,8 @@ describe AMQP do
|
|
26
26
|
it 'declares a new direct exchange with that name' do
|
27
27
|
@channel.direct('name').name.should == 'name'
|
28
28
|
|
29
|
+
@channel.direct('name').delete
|
30
|
+
|
29
31
|
done
|
30
32
|
end
|
31
33
|
|
@@ -35,6 +37,8 @@ describe AMQP do
|
|
35
37
|
exchange.should_not be_durable
|
36
38
|
exchange.should be_transient
|
37
39
|
|
40
|
+
exchange.delete
|
41
|
+
|
38
42
|
done
|
39
43
|
end
|
40
44
|
|
@@ -42,6 +46,7 @@ describe AMQP do
|
|
42
46
|
exchange = @channel.direct('name')
|
43
47
|
|
44
48
|
exchange.should_not be_auto_deleted
|
49
|
+
exchange.delete
|
45
50
|
|
46
51
|
done
|
47
52
|
end
|
@@ -59,9 +64,9 @@ describe AMQP do
|
|
59
64
|
context "when exchange name was specified as a blank string" do
|
60
65
|
it 'returns direct exchange with server-generated name' do
|
61
66
|
pending <<-EOF
|
62
|
-
|
63
|
-
|
64
|
-
|
67
|
+
This has to be fixed in RabbitMQ first
|
68
|
+
https://bugzilla.rabbitmq.com/show_bug.cgi?id=23509
|
69
|
+
EOF
|
65
70
|
@channel.direct("") do |exchange|
|
66
71
|
exchange.name.should_not be_empty
|
67
72
|
done
|
@@ -80,6 +85,9 @@ describe AMQP do
|
|
80
85
|
|
81
86
|
exchange.should == original_exchange
|
82
87
|
|
88
|
+
original_exchange.delete
|
89
|
+
exchange.delete
|
90
|
+
|
83
91
|
done
|
84
92
|
end # it
|
85
93
|
end
|
@@ -104,6 +112,8 @@ describe AMQP do
|
|
104
112
|
exchange.should be_durable
|
105
113
|
exchange.should_not be_transient
|
106
114
|
|
115
|
+
exchange.delete
|
116
|
+
|
107
117
|
done
|
108
118
|
end # it
|
109
119
|
end # context
|
@@ -115,6 +125,8 @@ describe AMQP do
|
|
115
125
|
exchange.should_not be_durable
|
116
126
|
exchange.should be_transient
|
117
127
|
|
128
|
+
exchange.delete
|
129
|
+
|
118
130
|
done
|
119
131
|
end # it
|
120
132
|
end # context
|
@@ -125,6 +137,7 @@ describe AMQP do
|
|
125
137
|
exchange = @channel.direct("a new auto-deleted direct exchange", :auto_delete => true)
|
126
138
|
|
127
139
|
exchange.should be_auto_deleted
|
140
|
+
exchange.delete
|
128
141
|
done
|
129
142
|
end # it
|
130
143
|
end # context
|
@@ -135,6 +148,7 @@ describe AMQP do
|
|
135
148
|
exchange = @channel.direct("a new non-auto-deleted direct exchange", :auto_delete => false)
|
136
149
|
|
137
150
|
exchange.should_not be_auto_deleted
|
151
|
+
exchange.delete
|
138
152
|
done
|
139
153
|
end # it
|
140
154
|
end # context
|
@@ -145,6 +159,7 @@ describe AMQP do
|
|
145
159
|
exchange = @channel.direct("a new non-auto-deleted direct exchange", :auto_delete => false)
|
146
160
|
|
147
161
|
exchange.should_not be_auto_deleted
|
162
|
+
exchange.delete
|
148
163
|
done
|
149
164
|
end # it
|
150
165
|
end # context
|
@@ -152,12 +167,14 @@ describe AMQP do
|
|
152
167
|
|
153
168
|
context "when exchange is re-declared with parameters different from original declaration" do
|
154
169
|
it "raises an exception" do
|
155
|
-
@channel.direct("previously.declared.durable.direct.exchange", :durable => true)
|
170
|
+
exchange = @channel.direct("previously.declared.durable.direct.exchange", :durable => true)
|
156
171
|
|
157
172
|
expect {
|
158
173
|
@channel.direct("previously.declared.durable.direct.exchange", :durable => false)
|
159
174
|
}.to raise_error(AMQP::IncompatibleOptionsError)
|
160
175
|
|
176
|
+
exchange.delete
|
177
|
+
|
161
178
|
done
|
162
179
|
end # it
|
163
180
|
end # context
|
@@ -174,6 +191,7 @@ describe AMQP do
|
|
174
191
|
exchange = @channel.fanout(name)
|
175
192
|
|
176
193
|
exchange.name.should == name
|
194
|
+
exchange.delete
|
177
195
|
|
178
196
|
done
|
179
197
|
end
|
@@ -199,6 +217,9 @@ describe AMQP do
|
|
199
217
|
|
200
218
|
exchange.should == original_exchange
|
201
219
|
|
220
|
+
original_exchange.delete
|
221
|
+
exchange.delete
|
222
|
+
|
202
223
|
done
|
203
224
|
end # it
|
204
225
|
end
|
@@ -293,6 +314,8 @@ describe AMQP do
|
|
293
314
|
exchange = @channel.topic(name)
|
294
315
|
exchange.name.should == name
|
295
316
|
|
317
|
+
exchange.delete
|
318
|
+
|
296
319
|
done
|
297
320
|
end
|
298
321
|
end # context
|
@@ -316,6 +339,8 @@ describe AMQP do
|
|
316
339
|
exchange = @channel.topic(name, :passive => true)
|
317
340
|
|
318
341
|
exchange.should == original_exchange
|
342
|
+
original_exchange.delete
|
343
|
+
exchange.delete
|
319
344
|
|
320
345
|
done
|
321
346
|
end # it
|
@@ -341,6 +366,8 @@ describe AMQP do
|
|
341
366
|
exchange.should be_durable
|
342
367
|
exchange.should_not be_transient
|
343
368
|
|
369
|
+
exchange.delete
|
370
|
+
|
344
371
|
done
|
345
372
|
end # it
|
346
373
|
end # context
|
@@ -352,6 +379,8 @@ describe AMQP do
|
|
352
379
|
exchange.should_not be_durable
|
353
380
|
exchange.should be_transient
|
354
381
|
|
382
|
+
exchange.delete
|
383
|
+
|
355
384
|
done
|
356
385
|
end # it
|
357
386
|
end # context
|
@@ -372,6 +401,7 @@ describe AMQP do
|
|
372
401
|
exchange = @channel.topic("a new non-auto-deleted topic exchange", :auto_delete => false)
|
373
402
|
|
374
403
|
exchange.should_not be_auto_deleted
|
404
|
+
exchange.delete
|
375
405
|
done
|
376
406
|
end # it
|
377
407
|
end # context
|
@@ -382,6 +412,7 @@ describe AMQP do
|
|
382
412
|
exchange = @channel.topic("a new non-auto-deleted topic exchange", :auto_delete => false)
|
383
413
|
|
384
414
|
exchange.should_not be_auto_deleted
|
415
|
+
exchange.delete
|
385
416
|
done
|
386
417
|
end # it
|
387
418
|
end # context
|
@@ -395,13 +426,15 @@ describe AMQP do
|
|
395
426
|
it "raises an exception" do
|
396
427
|
channel = AMQP::Channel.new
|
397
428
|
|
398
|
-
channel.topic("previously.declared.durable.topic.exchange", :durable => true)
|
429
|
+
exchange = channel.topic("previously.declared.durable.topic.exchange", :durable => true)
|
399
430
|
channel.should be_open
|
400
431
|
|
401
432
|
expect {
|
402
433
|
channel.topic("previously.declared.durable.topic.exchange", :durable => false)
|
403
434
|
}.to raise_error(AMQP::IncompatibleOptionsError)
|
404
435
|
|
436
|
+
exchange.delete
|
437
|
+
|
405
438
|
done
|
406
439
|
end # it
|
407
440
|
end # context
|
@@ -418,6 +451,7 @@ describe AMQP do
|
|
418
451
|
exchange = @channel.headers(name)
|
419
452
|
|
420
453
|
exchange.name.should == name
|
454
|
+
exchange.delete
|
421
455
|
|
422
456
|
done
|
423
457
|
end
|
@@ -446,6 +480,8 @@ describe AMQP do
|
|
446
480
|
exchange = @channel.headers(name, :passive => true)
|
447
481
|
|
448
482
|
exchange.should == original_exchange
|
483
|
+
original_exchange.delete
|
484
|
+
exchange.delete
|
449
485
|
|
450
486
|
done
|
451
487
|
end # it
|
@@ -471,6 +507,8 @@ describe AMQP do
|
|
471
507
|
exchange.should be_durable
|
472
508
|
exchange.should_not be_transient
|
473
509
|
|
510
|
+
exchange.delete
|
511
|
+
|
474
512
|
done
|
475
513
|
end # it
|
476
514
|
end # context
|
@@ -482,6 +520,8 @@ describe AMQP do
|
|
482
520
|
exchange.should_not be_durable
|
483
521
|
exchange.should be_transient
|
484
522
|
|
523
|
+
exchange.delete
|
524
|
+
|
485
525
|
done
|
486
526
|
end # it
|
487
527
|
end # context
|
@@ -492,6 +532,7 @@ describe AMQP do
|
|
492
532
|
exchange = @channel.headers("a new auto-deleted headers exchange", :auto_delete => true)
|
493
533
|
|
494
534
|
exchange.should be_auto_deleted
|
535
|
+
|
495
536
|
done
|
496
537
|
end # it
|
497
538
|
end # context
|
@@ -502,6 +543,8 @@ describe AMQP do
|
|
502
543
|
exchange = @channel.headers("a new non-auto-deleted headers exchange", :auto_delete => false)
|
503
544
|
|
504
545
|
exchange.should_not be_auto_deleted
|
546
|
+
exchange.delete
|
547
|
+
|
505
548
|
done
|
506
549
|
end # it
|
507
550
|
end # context
|
@@ -512,6 +555,8 @@ describe AMQP do
|
|
512
555
|
exchange = @channel.headers("a new non-auto-deleted headers exchange", :auto_delete => false)
|
513
556
|
|
514
557
|
exchange.should_not be_auto_deleted
|
558
|
+
exchange.delete
|
559
|
+
|
515
560
|
done
|
516
561
|
end # it
|
517
562
|
end # context
|
@@ -523,12 +568,14 @@ describe AMQP do
|
|
523
568
|
end
|
524
569
|
|
525
570
|
it "raises an exception" do
|
526
|
-
@channel.headers("previously.declared.durable.topic.exchange", :durable => true)
|
571
|
+
exchange = @channel.headers("previously.declared.durable.topic.exchange", :durable => true)
|
527
572
|
|
528
573
|
expect {
|
529
574
|
@channel.headers("previously.declared.durable.topic.exchange", :durable => false)
|
530
575
|
}.to raise_error(AMQP::IncompatibleOptionsError)
|
531
576
|
|
577
|
+
exchange.delete
|
578
|
+
|
532
579
|
done
|
533
580
|
end # it
|
534
581
|
end # context
|