dmexe_rabbitmq_http_api_client 0.3.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ module RabbitMQ
2
+ module HTTP
3
+ class Client
4
+ VERSION = "0.3.0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rabbitmq/http/client/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "dmexe_rabbitmq_http_api_client"
8
+ gem.version = RabbitMQ::HTTP::Client::VERSION
9
+ gem.authors = ["Michael Klishin"]
10
+ gem.email = ["michael@defprotocol.org"]
11
+ gem.description = %q{RabbitMQ HTTP API client for Ruby}
12
+ gem.summary = %q{RabbitMQ HTTP API client for Ruby}
13
+ gem.homepage = "http://github.com/ruby-amqp/rabbitmq_http_api_client"
14
+ gem.licenses = ["MIT", "Mozilla Public License"]
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_dependency "hashie", ">= 1.2.0"
22
+ gem.add_dependency "multi_json", ">= 1.4.0"
23
+ gem.add_dependency "faraday", "~> 0.8.4"
24
+ gem.add_dependency "faraday_middleware", "~> 0.9.0"
25
+ gem.add_dependency "effin_utf8", "~> 1.0.0"
26
+ end
@@ -0,0 +1,681 @@
1
+ require "spec_helper"
2
+
3
+ describe RabbitMQ::HTTP::Client do
4
+ let(:endpoint) { "http://127.0.0.1:15672" }
5
+
6
+ subject do
7
+ described_class.connect(endpoint, :username => "guest", :password => "guest")
8
+ end
9
+
10
+ before :all do
11
+ @connection = Bunny.new
12
+ @connection.start
13
+ end
14
+
15
+ after :all do
16
+ @connection.close
17
+ end
18
+
19
+
20
+ #
21
+ # Overview
22
+ #
23
+
24
+ describe "GET /api/overview" do
25
+ it "returns an overview" do
26
+ r = subject.overview
27
+
28
+ r.exchange_types.map { |h| h.name }.
29
+ sort.should == ["direct", "fanout", "headers", "topic"]
30
+
31
+ r.rabbitmq_version.should_not be_nil
32
+ r.erlang_version.should_not be_nil
33
+ end
34
+ end
35
+
36
+ #
37
+ # Nodes
38
+ #
39
+
40
+ describe "GET /api/nodes" do
41
+ it "lists cluster nodes with detailed status information for each one of them" do
42
+ nodes = subject.list_nodes
43
+ n = nodes.first
44
+
45
+ rabbit = n.applications.detect { |app| app.name == "rabbit" }
46
+ rabbit.description.should == "RabbitMQ"
47
+
48
+ n.name.should == "rabbit@localhost"
49
+ n.partitions.should == []
50
+ n.fd_used.should_not be_nil
51
+ n.fd_total.should_not be_nil
52
+ n.sockets_used.should_not be_nil
53
+ n.sockets_total.should_not be_nil
54
+ n.mem_used.should_not be_nil
55
+ n.mem_limit.should_not be_nil
56
+ n.disk_free_limit.should_not be_nil
57
+ n.disk_free.should_not be_nil
58
+ n.proc_used.should_not be_nil
59
+ n.proc_total.should_not be_nil
60
+ n.run_queue.should_not be_nil
61
+ end
62
+ end
63
+
64
+ describe "GET /api/node/:name" do
65
+ it "returns status information for a single cluster node" do
66
+ n = subject.node_info("rabbit@localhost")
67
+
68
+ rabbit = n.applications.detect { |app| app.name == "rabbit" }
69
+ rabbit.description.should == "RabbitMQ"
70
+
71
+ n.name.should == "rabbit@localhost"
72
+ n.partitions.should == []
73
+ n.fd_used.should_not be_nil
74
+ n.fd_total.should_not be_nil
75
+ n.sockets_used.should_not be_nil
76
+ n.sockets_total.should_not be_nil
77
+ n.mem_used.should_not be_nil
78
+ n.mem_limit.should_not be_nil
79
+ n.disk_free_limit.should_not be_nil
80
+ n.disk_free.should_not be_nil
81
+ n.proc_used.should_not be_nil
82
+ n.proc_total.should_not be_nil
83
+ n.run_queue.should_not be_nil
84
+ n.running.should be_true
85
+ end
86
+ end
87
+
88
+ #
89
+ # Extensions
90
+ #
91
+
92
+ describe "GET /api/extensions" do
93
+ it "returns a list of enabled management plugin extensions" do
94
+ xs = subject.list_extensions
95
+ f = xs.first
96
+
97
+ f.javascript.should == "dispatcher.js"
98
+ end
99
+ end
100
+
101
+ #
102
+ # Definitions
103
+ #
104
+
105
+ describe "GET /api/definitions" do
106
+ it "returns a list of all resources/definitions (vhosts, users, permissions, queues, exchanges, bindings, etc)" do
107
+ xs = subject.list_definitions
108
+
109
+ xs.bindings.should be_instance_of(Array)
110
+ xs.queues.should be_instance_of(Array)
111
+ xs.exchanges.should be_instance_of(Array)
112
+ xs.users.should be_instance_of(Array)
113
+ xs.vhosts.should be_instance_of(Array)
114
+ end
115
+ end
116
+
117
+ describe "POST /api/definitions" do
118
+ it "uploads definitions to RabbitMQ"
119
+ end
120
+
121
+ #
122
+ # Connections
123
+ #
124
+
125
+ describe "GET /api/connections" do
126
+ before :all do
127
+ @connection = Bunny.new
128
+ @connection.start
129
+ end
130
+
131
+ it "returns a list of all active connections" do
132
+ xs = subject.list_connections
133
+ f = xs.first
134
+
135
+ f.name.should =~ /127.0.0.1/
136
+ f.client_properties.product.should == "Bunny"
137
+ end
138
+ end
139
+
140
+ describe "GET /api/connections/:name" do
141
+ it "returns information about the connection" do
142
+ xs = subject.list_connections
143
+ c = subject.connection_info(xs.first.name)
144
+
145
+ c.name.should =~ /127.0.0.1/
146
+ c.client_properties.product.should == "Bunny"
147
+ end
148
+ end
149
+
150
+ describe "DELETE /api/connections/:name" do
151
+ it "closes the connection" do
152
+ pending "Needs investigation, DELETE does not seem to close the connection"
153
+ xs = subject.list_connections
154
+ c = subject.close_connection(xs.first.name)
155
+
156
+ c.name.should =~ /127.0.0.1/
157
+ c.client_properties.product.should == "Bunny"
158
+
159
+ @connection.should_not be_open
160
+ end
161
+ end
162
+
163
+
164
+ #
165
+ # Channels
166
+ #
167
+
168
+ describe "GET /api/channels" do
169
+ before :all do
170
+ @channel = @connection.create_channel
171
+ end
172
+
173
+ it "returns a list of all active channels" do
174
+ xs = subject.list_channels
175
+ f = xs.first
176
+
177
+ f.number.should be >= 1
178
+ f.prefetch_count.should be >= 0
179
+ end
180
+ end
181
+
182
+ describe "GET /api/channels/:name" do
183
+ before :all do
184
+ @channel = @connection.create_channel
185
+ end
186
+
187
+ it "returns information about the channel" do
188
+ xs = subject.list_channels
189
+ c = subject.channel_info(xs.first.name)
190
+
191
+ c.number.should be >= 1
192
+ c.prefetch_count.should be >= 0
193
+ end
194
+ end
195
+
196
+ #
197
+ # Exchanges
198
+ #
199
+
200
+ describe "GET /api/exchanges" do
201
+ it "returns a list of all exchanges in the cluster" do
202
+ xs = subject.list_exchanges
203
+ f = xs.first
204
+
205
+ f.type.should_not be_nil
206
+ f.name.should_not be_nil
207
+ f.vhost.should_not be_nil
208
+ f.durable.should_not be_nil
209
+ f.auto_delete.should_not be_nil
210
+ end
211
+ end
212
+
213
+ describe "GET /api/exchanges/:vhost" do
214
+ it "returns a list of all exchanges in a vhost" do
215
+ xs = subject.list_exchanges("/")
216
+ f = xs.first
217
+
218
+ f.vhost.should == "/"
219
+ end
220
+ end
221
+
222
+ describe "GET /api/exchanges/:vhost/:name" do
223
+ it "returns information about the exchange" do
224
+ e = subject.exchange_info("/", "amq.fanout")
225
+
226
+ e.type.should == "fanout"
227
+ e.name.should == "amq.fanout"
228
+ e.durable.should be_true
229
+ e.vhost.should == "/"
230
+ e.internal.should be_false
231
+ e.auto_delete.should be_false
232
+ end
233
+ end
234
+
235
+ describe "GET /api/exchanges/:vhost/:name/bindings/source" do
236
+ before :all do
237
+ @channel = @connection.create_channel
238
+ end
239
+
240
+ it "returns a list of all bindings in which the given exchange is the source" do
241
+ e = @channel.fanout("http.api.tests.fanout", :durable => true)
242
+ q = @channel.queue("http.api.tests.queue1", :durable => true)
243
+ q.bind(e)
244
+
245
+ xs = subject.list_bindings_by_source("/", "http.api.tests.fanout")
246
+ f = xs.first
247
+
248
+ f.destination.should == q.name
249
+ f.destination_type.should == "queue"
250
+ f.routing_key.should == ""
251
+ f.source.should == e.name
252
+ f.vhost.should == "/"
253
+
254
+ e.delete
255
+ q.delete
256
+ end
257
+ end
258
+
259
+
260
+ describe "GET /api/exchanges/:vhost/:name/bindings/destination" do
261
+ before :all do
262
+ @channel = @connection.create_channel
263
+ end
264
+
265
+ it "returns a list of all bindings in which the given exchange is the source" do
266
+ e1 = @channel.fanout("http.api.tests.fanout1", :durable => true)
267
+ e2 = @channel.fanout("http.api.tests.fanout2", :durable => true)
268
+ e1.bind(e2)
269
+
270
+ xs = subject.list_bindings_by_destination("/", "http.api.tests.fanout1")
271
+ f = xs.first
272
+
273
+ f.destination.should == e1.name
274
+ f.destination_type.should == "exchange"
275
+ f.routing_key.should == ""
276
+ f.source.should == e2.name
277
+ f.vhost.should == "/"
278
+
279
+ e1.delete
280
+ e2.delete
281
+ end
282
+ end
283
+
284
+
285
+
286
+ describe "POST /api/exchanges/:vhost/:name/publish" do
287
+ it "publishes a messages to the exchange"
288
+ end
289
+
290
+
291
+ #
292
+ # Queues
293
+ #
294
+
295
+ describe "GET /api/queues" do
296
+ before :all do
297
+ @channel = @connection.create_channel
298
+ end
299
+
300
+ it "returns a list of all queues" do
301
+ q = @channel.queue("", :exclusive => true)
302
+
303
+ xs = subject.list_queues
304
+ xs.detect { |x| x.name == q.name }.should_not be_empty
305
+ end
306
+ end
307
+
308
+ describe "GET /api/queues/:vhost" do
309
+ before :all do
310
+ @channel = @connection.create_channel
311
+ end
312
+
313
+ it "returns a list of all queues" do
314
+ q = @channel.queue("", :exclusive => true)
315
+
316
+ xs = subject.list_queues("/")
317
+ xs.detect { |x| x.name == q.name }.should_not be_empty
318
+ end
319
+ end
320
+
321
+ describe "GET /api/queues/:vhost/:name" do
322
+ before :all do
323
+ @channel = @connection.create_channel
324
+ end
325
+
326
+ it "returns information about a queue" do
327
+ q = @channel.queue("", :exclusive => true, :durable => false)
328
+ i = subject.queue_info("/", q.name)
329
+
330
+ i.durable.should be_false
331
+ i.durable.should == q.durable?
332
+
333
+ i.name.should == q.name
334
+ i.auto_delete.should == q.auto_delete?
335
+ i.active_consumers.should == 0
336
+ i.backing_queue_status.avg_ack_egress_rate.should == 0.0
337
+ end
338
+ end
339
+
340
+ describe "PUT /api/queues/:vhost/:name" do
341
+ before :all do
342
+ @channel = @connection.create_channel
343
+ end
344
+
345
+ let(:queue_name) { "httpdeclared" }
346
+
347
+ it "declares a queue" do
348
+ subject.declare_queue("/", queue_name, :durable => false, :auto_delete => true)
349
+
350
+ q = @channel.queue(queue_name, :durable => false, :auto_delete => true)
351
+ q.delete
352
+ end
353
+ end
354
+
355
+ describe "DELETE /api/queues/:vhost/:name" do
356
+ before :all do
357
+ @channel = @connection.create_channel
358
+ end
359
+
360
+ let(:queue_name) { "httpdeclared" }
361
+
362
+ it "deletes a queue" do
363
+ q = @channel.queue(queue_name, :durable => false)
364
+ subject.delete_queue("/", queue_name)
365
+ end
366
+ end
367
+
368
+ describe "GET /api/queues/:vhost/:name/bindings" do
369
+ before :all do
370
+ @channel = @connection.create_channel
371
+ end
372
+
373
+ it "returns a list of bindings for a queue" do
374
+ q = @channel.queue("")
375
+ q.bind("amq.fanout")
376
+
377
+ xs = subject.list_queue_bindings("/", q.name)
378
+ x = xs.first
379
+
380
+ x.destination.should == q.name
381
+ x.destination_type.should == "queue"
382
+ end
383
+ end
384
+
385
+ describe "DELETE /api/queues/:vhost/:name/contents" do
386
+ before :all do
387
+ @channel = @connection.create_channel
388
+ end
389
+
390
+ it "purges a queue" do
391
+ q = @channel.queue("")
392
+ x = @channel.fanout("amq.fanout", :durable => true, :auto_delete => false)
393
+ q.bind(x)
394
+
395
+ 10.times do
396
+ x.publish("", :routing_key => q.name)
397
+ end
398
+ sleep 0.7
399
+
400
+ q.message_count.should == 10
401
+ subject.purge_queue("/", q.name)
402
+ sleep 0.5
403
+ q.message_count.should == 0
404
+ q.delete
405
+ end
406
+ end
407
+
408
+ # yes, POST, because it potentially modifies the state (ordering) of the queue
409
+ describe "POST /api/queues/:vhost/:name/get" do
410
+ before :all do
411
+ @channel = @connection.create_channel
412
+ end
413
+
414
+ it "fetches a message from a queue, a la basic.get" do
415
+ q = @channel.queue("")
416
+ x = @channel.fanout("amq.fanout", :durable => true, :auto_delete => false)
417
+ q.bind(x)
418
+
419
+ 10.times do |i|
420
+ x.publish("msg #{i}", :routing_key => q.name, :content_type => "application/xyz")
421
+ end
422
+ sleep 0.7
423
+
424
+ q.message_count.should == 10
425
+ xs = subject.get_messages("/", q.name, :count => 10, :requeue => false, :encoding => "auto")
426
+ m = xs.first
427
+
428
+ m.properties.content_type.should == "application/xyz"
429
+ m.payload.should == "msg 0"
430
+ m.payload_encoding.should == "string"
431
+
432
+ q.delete
433
+ end
434
+ end
435
+
436
+ describe "GET /api/bindings" do
437
+ it "returns a list of all bindings" do
438
+ xs = subject.list_bindings
439
+ b = xs.first
440
+
441
+ b.destination.should_not be_nil
442
+ b.destination_type.should_not be_nil
443
+ b.source.should_not be_nil
444
+ b.routing_key.should_not be_nil
445
+ b.vhost.should_not be_nil
446
+ end
447
+ end
448
+
449
+ describe "GET /api/bindings/:vhost" do
450
+ it "returns a list of all bindings in a vhost" do
451
+ xs = subject.list_bindings("/")
452
+ b = xs.first
453
+
454
+ b.destination.should_not be_nil
455
+ b.destination_type.should_not be_nil
456
+ b.source.should_not be_nil
457
+ b.routing_key.should_not be_nil
458
+ b.vhost.should_not be_nil
459
+ end
460
+ end
461
+
462
+ describe "GET /api/bindings/:vhost/e/:exchange/q/:queue" do
463
+ before :all do
464
+ @channel = @connection.create_channel
465
+ end
466
+
467
+ it "returns a list of all bindings between an exchange and a queue" do
468
+ q = @channel.queue("")
469
+ x = @channel.fanout("http.client.fanout")
470
+ q.bind(x)
471
+
472
+ xs = subject.list_bindings_between_queue_and_exchange("/", q.name, x.name)
473
+ b = xs.first
474
+ b.destination.should == q.name
475
+ b.destination_type.should == "queue"
476
+ b.source.should == x.name
477
+ b.routing_key.should_not be_nil
478
+ b.vhost.should == "/"
479
+
480
+ q.delete
481
+ x.delete
482
+ end
483
+ end
484
+
485
+ describe "POST /api/bindings/:vhost/e/:exchange/q/:queue" do
486
+ it "creates a binding between an exchange and a queue"
487
+ end
488
+
489
+ describe "GET /api/bindings/:vhost/e/:exchange/q/:queue/props" do
490
+ it "returns an individual binding between an exchange and a queue"
491
+ end
492
+
493
+ describe "DELETE /api/bindings/:vhost/e/:exchange/q/:queue/props" do
494
+ it "deletes an individual binding between an exchange and a queue"
495
+ end
496
+
497
+ describe "GET /api/vhosts" do
498
+ it "returns a list of vhosts" do
499
+ xs = subject.list_vhosts
500
+ v = xs.first
501
+
502
+ v.name.should_not be_nil
503
+ v.tracing.should be_false
504
+ end
505
+ end
506
+
507
+ describe "GET /api/vhosts/:name" do
508
+ it "returns infomation about a vhost" do
509
+ v = subject.vhost_info("/")
510
+
511
+ v.name.should_not be_nil
512
+ v.tracing.should be_false
513
+ end
514
+ end
515
+
516
+ describe "PUT /api/vhosts/:name" do
517
+ let(:vhost) { "http-created" }
518
+
519
+ it "creates a vhost" do
520
+ subject.create_vhost(vhost)
521
+ subject.create_vhost(vhost)
522
+
523
+ v = subject.vhost_info(vhost)
524
+ v.name.should == vhost
525
+ end
526
+ end
527
+
528
+ describe "DELETE /api/vhosts/:name" do
529
+ let(:vhost) { "http-created2" }
530
+
531
+ it "deletes a vhost" do
532
+ subject.create_vhost(vhost)
533
+ subject.delete_vhost(vhost)
534
+ end
535
+ end
536
+
537
+ describe "GET /api/vhosts/:name/permissions" do
538
+ it "returns a list of permissions in a vhost" do
539
+ xs = subject.list_permissions("/")
540
+ p = xs.detect { |x| x.user == "guest" }
541
+
542
+ p.read.should == ".*"
543
+ end
544
+ end
545
+
546
+ describe "GET /api/users" do
547
+ it "returns a list of all users" do
548
+ xs = subject.list_users
549
+ u = xs.first
550
+
551
+ u.name.should_not be_nil
552
+ u.password_hash.should_not be_nil
553
+ u.tags.should_not be_nil
554
+ end
555
+ end
556
+
557
+ describe "GET /api/users/:name" do
558
+ it "returns information about a user" do
559
+ u = subject.user_info("guest")
560
+ u.name.should == "guest"
561
+ u.tags.should == "administrator"
562
+ end
563
+ end
564
+
565
+ describe "PUT /api/users/:name" do
566
+ it "updates information about a user" do
567
+ subject.update_user("alt", :tags => "http", :password => "alt")
568
+
569
+ u = subject.user_info("alt")
570
+ u.tags.should == "http"
571
+ end
572
+ end
573
+
574
+ describe "DELETE /api/users/:name" do
575
+ it "deletes a user" do
576
+ subject.update_user("alt2", :tags => "http", :password => "alt")
577
+ subject.delete_user("alt2")
578
+ end
579
+ end
580
+
581
+ describe "GET /api/users/:name/permissions" do
582
+ it "returns a list of permissions for a user" do
583
+ xs = subject.user_permissions("guest")
584
+ p = xs.first
585
+
586
+ p.read.should == ".*"
587
+ end
588
+ end
589
+
590
+ describe "GET /api/whoami" do
591
+ it "returns information about the current user" do
592
+ u = subject.whoami
593
+ u.name.should == "guest"
594
+ end
595
+ end
596
+
597
+ describe "GET /api/permissions" do
598
+ it "lists all permissions" do
599
+ xs = subject.list_permissions
600
+ xs.first.read.should_not be_nil
601
+ end
602
+ end
603
+
604
+ describe "GET /api/permissions/:vhost/:user" do
605
+ it "returns a list of permissions of a user in a vhost" do
606
+ p = subject.list_permissions_of("/", "guest")
607
+
608
+ p.read.should == ".*"
609
+ p.write.should == ".*"
610
+ p.configure.should == ".*"
611
+ end
612
+ end
613
+
614
+ describe "PUT /api/permissions/:vhost/:user" do
615
+ it "updates permissions of a user in a vhost" do
616
+ subject.update_permissions_of("/", "guest", :write => ".*", :read => ".*", :configure => ".*")
617
+
618
+ p = subject.list_permissions_of("/", "guest")
619
+
620
+ p.read.should == ".*"
621
+ p.write.should == ".*"
622
+ p.configure.should == ".*"
623
+ end
624
+ end
625
+
626
+ describe "DELETE /api/permissions/:vhost/:user" do
627
+ it "clears permissions of a user in a vhost" do
628
+ pending
629
+ subject.create_user("/", "alt3")
630
+ subject.update_permissions_of("/", "alt3", :write => ".*", :read => ".*", :configure => ".*")
631
+ subject.clear_permissions_of("/", "alt3")
632
+
633
+ p = subject.list_permissions_of("/", "alt3")
634
+
635
+ puts p.inspect
636
+ end
637
+ end
638
+
639
+ #
640
+ # Parameters
641
+ #
642
+
643
+ describe "GET /api/parameters" do
644
+ it "returns a list of all parameters" do
645
+ xs = subject.list_parameters
646
+ xs.should be_kind_of(Array)
647
+ end
648
+ end
649
+
650
+
651
+ #
652
+ # Policies
653
+ #
654
+
655
+ describe "GET /api/policies" do
656
+ it "returns a list of all policies" do
657
+ xs = subject.list_policies
658
+ xs.should be_kind_of(Array)
659
+ end
660
+ end
661
+
662
+ describe "GET /api/policies/:vhost" do
663
+ it "returns a list of all policies in a vhost" do
664
+ xs = subject.list_policies("/")
665
+ xs.should be_kind_of(Array)
666
+ end
667
+ end
668
+
669
+
670
+ #
671
+ # Aliveness Test
672
+ #
673
+
674
+ describe "GET /api/aliveness-test/:vhost" do
675
+ it "performs aliveness check" do
676
+ r = subject.aliveness_test("/")
677
+
678
+ r.should be_true
679
+ end
680
+ end
681
+ end