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