dmexe_rabbitmq_http_api_client 0.3.0.1

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.
@@ -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